Android系统启动
基于android12-release
Android系统启动
可以先查看图片:4.1 系统启动 或者下图:
1、Loader:Boot Rom、Boot Loader
Boot Rom:Android设备上电后,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。(由“芯片厂商”负责设计和实现)
Boot Loader:Bootloader 开始执行,首先负责完成硬件的初始化,然后找到Linux内核代码,并加载到内存。
引导程序是在Android操作系统开始运行前的一个小程序。它不是Android操作系统的一部分。引导程序是 OEM 厂商或者运营商加锁和限制的地方。(由“设备厂商”负责设计和实现)
相关资料如下:bootloader
2、Linux Kernel
Linux 内核开始启动,初始化各种软硬件环境,加载驱动程序,挂载根文件系统,并执行init程序,由此开启Android的世界。
严格来说,Android系统实际上是运行于Linux内核上的一系列 “服务进程”,并不算一个完整意义上的“操作系统”。Android系统以及各大Linux的发行版,他们的Linux内核部分启动过程都是差不多。Android最后都是start_kernel初始化函数(system/core/init/main.cpp)
重要进程:
pid=0,linux启动的第一个进程,swapper/idle进程
;pid=1,init进程
;pid=2,kthreadd进程
init/main.c (androidxref上老版本rest_init都是kernel_thread)
3、Native C/C++ Library :主要解析 init.rc 文件
init 进程决定了系统在启动过程中,究竟会启动哪些守护进程和服务,以及呈现出怎样的一个用户UI界面。
这里不过多介绍其他,相关代码:(基于aosp/android11-release)
-
system/core/init/main.cpp
-
system/core/init/first_stage_init.cpp
-
system/core/init/init.cpp 中SecondStageMain,最终在
LoadBootScripts
解析rc文件
rc相关语法Android Init Language: system\core\init\README.md
3.1 init
init 进程会执行 app_process 程序,创建 Zygote 进程,它是Android系统最重要的进程,所有后续的Android应用程序都是由它 fork 出来的。
init 触发进程和服务:
触发器的执行顺序为on early-init -> init -> late-init
3.2 Zygote
init.rc中import /system/etc/init/hw/init.${ro.zygote}.rc
,ro.zygote属性配置。
这里查看64位的 system/core/rootdir/init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
服务Service,以 service 开头,由 init 进程启动,一般运行在 init 的一个子进程,每一个service在启动时会通过fork方式生成子进程。这个 rc 文件其中 service 用于通知 init 进程创建名 zygote 的进程,这个 zygote 进程执行程序的路径为 /system/bin/app_process64,后面的则是要传给 app_process64 的参数。class main指的是zygote的class name为main。
init 触发启动 service:Start方法中调用 fork() 创建子进程,调用 ExpandArgsAndExecv 通过最终调用 execv 执行system/bin/app_process,这样就会进入frameworks/base/cmds/app_process/app_main.cpp
的main函数。
Result<void> Service::Start() {
// ... ... ... ...
pid_t pid = -1;
if (namespaces_.flags) {
pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);
} else {
pid = fork();
}
if (pid == 0) {
umask(077);
// ... ... ... ...
for (const auto& [key, value] : environment_vars_) {
setenv(key.c_str(), value.c_str(), 1);
}
for (const auto& descriptor : descriptors) {
descriptor.Publish();
}
// ... ... ... ...
if (!ExpandArgsAndExecv(args_, sigstop_)) {
PLOG(ERROR) << "cannot execv('" << args_[0]
<< "'). See the 'Debugging init' section of init's README.md for tips";
}
_exit(127);
}
// ... ... ... ...
}
frameworks/base/cmds/app_process/app_main.cpp
frameworks/base/core/jni/AndroidRuntime.cpp
int main(int argc, char* const argv[])
{
// ... ... 传到的参数argv为“-Xzygote /system/bin --zygote --start-system-server” ... ...
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// ... ... ... ...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
runtime.start 来启动 zygote
4、Java API Framework
4.1 启动 SystemServer
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/Zygote.java
public static void main(String argv[]) {
// ... ... ... ...
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
// ... ... ... ...
}
// ... ... ... ...
/**
* Prepare the arguments and forks for the system server process.
*
* @return A {@code Runnable} that provides an entrypoint into system_server code in the child
* process; {@code null} in the parent.
*/
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
// ... ... ... ...
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
// ... ... ... ...
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
forkSystemServer 开启线程,执行 Zygote.forkSystemServer fork子进程,用于运行system_server;handleSystemServerProcess 完成system_server进程剩余的工作
反射调用到com.android.server.SystemServer
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
frameworks/base/core/services/java/com/android/server/SystemServer.java
Zygote最终调用 RuntimeInit.applicationInit
中 findStaticMain
方法反射调用调用到cl.getMethod("main", new Class[] { String[].class });
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
TimingsTraceAndSlog t = new TimingsTraceAndSlog();
try {
t.traceBegin("InitBeforeStartServices");
// ... ... ... ...
// Initialize native services.
System.loadLibrary("android_servers");
// ... ... ... ...
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
mDumper.addDumpable(mSystemServiceManager);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
// ... ... ... ...
// Start services.
try {
t.traceBegin("StartServices");
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
// ... ... ... ...
}
启动服务
startBootstrapServices
启动引导服务startCoreServices
启动核心服务startOtherServices
启动其他服务
4.2 系统启动时序图
5、Launcher
frameworks/base/core/services/java/com/android/server/SystemServer.java
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
t.traceBegin("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
t.traceEnd();
t.traceBegin("StartObservingNativeCrashes");
try {
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
t.traceEnd();
t.traceBegin("RegisterAppOpsPolicy");
try {
mActivityManagerService.setAppOpsPolicy(new AppOpsPolicy(mSystemContext));
} catch (Throwable e) {
reportWtf("registering app ops policy", e);
}
t.traceEnd();
// No dependency on Webview preparation in system server. But this should
// be completed before allowing 3rd party
final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";
Future<?> webviewPrep = null;
if (!mOnlyCore && mWebViewUpdateService != null) {
webviewPrep = SystemServerInitThreadPool.submit(() -> {
Slog.i(TAG, WEBVIEW_PREPARATION);
TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
traceLog.traceBegin(WEBVIEW_PREPARATION);
ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");
mZygotePreload = null;
mWebViewUpdateService.prepareWebViewInSystemServer();
traceLog.traceEnd();
}, WEBVIEW_PREPARATION);
}
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
t.traceBegin("StartCarServiceHelperService");
final SystemService cshs = mSystemServiceManager
.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
if (cshs instanceof Dumpable) {
mDumper.addDumpable((Dumpable) cshs);
}
if (cshs instanceof DevicePolicySafetyChecker) {
dpms.setDevicePolicySafetyChecker((DevicePolicySafetyChecker) cshs);
}
t.traceEnd();
}
// Enable airplane mode in safe mode. setAirplaneMode() cannot be called
// earlier as it sends broadcasts to other services.
// TODO: This may actually be too late if radio firmware already started leaking
// RF before the respective services start. However, fixing this requires changes
// to radio firmware and interfaces.
if (safeMode) {
t.traceBegin("EnableAirplaneModeInSafeMode");
try {
connectivityF.setAirplaneMode(true);
} catch (Throwable e) {
reportWtf("enabling Airplane Mode during Safe Mode bootup", e);
}
t.traceEnd();
}
t.traceBegin("MakeNetworkManagementServiceReady");
try {
if (networkManagementF != null) {
networkManagementF.systemReady();
}
} catch (Throwable e) {
reportWtf("making Network Managment Service ready", e);
}
CountDownLatch networkPolicyInitReadySignal = null;
if (networkPolicyF != null) {
networkPolicyInitReadySignal = networkPolicyF
.networkScoreAndNetworkManagementServiceReady();
}
t.traceEnd();
t.traceBegin("MakeIpSecServiceReady");
try {
if (ipSecServiceF != null) {
ipSecServiceF.systemReady();
}
} catch (Throwable e) {
reportWtf("making IpSec Service ready", e);
}
t.traceEnd();
t.traceBegin("MakeNetworkStatsServiceReady");
try {
if (networkStatsF != null) {
networkStatsF.systemReady();
}
} catch (Throwable e) {
reportWtf("making Network Stats Service ready", e);
}
t.traceEnd();
t.traceBegin("MakeConnectivityServiceReady");
try {
if (connectivityF != null) {
connectivityF.systemReady();
}
} catch (Throwable e) {
reportWtf("making Connectivity Service ready", e);
}
t.traceEnd();
t.traceBegin("MakeVpnManagerServiceReady");
try {
if (vpnManagerF != null) {
vpnManagerF.systemReady();
}
} catch (Throwable e) {
reportWtf("making VpnManagerService ready", e);
}
t.traceEnd();
t.traceBegin("MakeVcnManagementServiceReady");
try {
if (vcnManagementF != null) {
vcnManagementF.systemReady();
}
} catch (Throwable e) {
reportWtf("making VcnManagementService ready", e);
}
t.traceEnd();
t.traceBegin("MakeNetworkPolicyServiceReady");
try {
if (networkPolicyF != null) {
networkPolicyF.systemReady(networkPolicyInitReadySignal);
}
} catch (Throwable e) {
reportWtf("making Network Policy Service ready", e);
}
t.traceEnd();
// Wait for all packages to be prepared
mPackageManagerService.waitForAppDataPrepared();
// It is now okay to let the various system services start their
// third party code...
t.traceBegin("PhaseThirdPartyAppsCanStart");
// confirm webview completion before starting 3rd party
if (webviewPrep != null) {
ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
}
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
t.traceEnd();
t.traceBegin("StartNetworkStack");
try {
// Note : the network stack is creating on-demand objects that need to send
// broadcasts, which means it currently depends on being started after
// ActivityManagerService.mSystemReady and ActivityManagerService.mProcessesReady
// are set to true. Be careful if moving this to a different place in the
// startup sequence.
NetworkStackClient.getInstance().start();
} catch (Throwable e) {
reportWtf("starting Network Stack", e);
}
t.traceEnd();
t.traceBegin("StartTethering");
try {
// TODO: hide implementation details, b/146312721.
ConnectivityModuleConnector.getInstance().startModuleService(
TETHERING_CONNECTOR_CLASS,
PERMISSION_MAINLINE_NETWORK_STACK, service -> {
ServiceManager.addService(Context.TETHERING_SERVICE, service,
false /* allowIsolated */,
DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
});
} catch (Throwable e) {
reportWtf("starting Tethering", e);
}
t.traceEnd();
t.traceBegin("MakeCountryDetectionServiceReady");
try {
if (countryDetectorF != null) {
countryDetectorF.systemRunning();
}
} catch (Throwable e) {
reportWtf("Notifying CountryDetectorService running", e);
}
t.traceEnd();
t.traceBegin("MakeNetworkTimeUpdateReady");
try {
if (networkTimeUpdaterF != null) {
networkTimeUpdaterF.systemRunning();
}
} catch (Throwable e) {
reportWtf("Notifying NetworkTimeService running", e);
}
t.traceEnd();
t.traceBegin("MakeInputManagerServiceReady");
try {
// TODO(BT) Pass parameter to input manager
if (inputManagerF != null) {
inputManagerF.systemRunning();
}
} catch (Throwable e) {
reportWtf("Notifying InputManagerService running", e);
}
t.traceEnd();
t.traceBegin("MakeTelephonyRegistryReady");
try {
if (telephonyRegistryF != null) {
telephonyRegistryF.systemRunning();
}
} catch (Throwable e) {
reportWtf("Notifying TelephonyRegistry running", e);
}
t.traceEnd();
t.traceBegin("MakeMediaRouterServiceReady");
try {
if (mediaRouterF != null) {
mediaRouterF.systemRunning();
}
} catch (Throwable e) {
reportWtf("Notifying MediaRouterService running", e);
}
t.traceEnd();
t.traceBegin("MakeMmsServiceReady");
try {
if (mmsServiceF != null) {
mmsServiceF.systemRunning();
}
} catch (Throwable e) {
reportWtf("Notifying MmsService running", e);
}
t.traceEnd();
t.traceBegin("IncidentDaemonReady");
try {
// TODO: Switch from checkService to getService once it's always
// in the build and should reliably be there.
final IIncidentManager incident = IIncidentManager.Stub.asInterface(
ServiceManager.getService(Context.INCIDENT_SERVICE));
if (incident != null) {
incident.systemRunning();
}
} catch (Throwable e) {
reportWtf("Notifying incident daemon running", e);
}
t.traceEnd();
if (mIncrementalServiceHandle != 0) {
t.traceBegin("MakeIncrementalServiceReady");
setIncrementalServiceSystemReady(mIncrementalServiceHandle);
t.traceEnd();
}
}, t);
Launcher启动:Launcher启动过程
frameworks\base\services\java\com\android\server\SystemServer.java
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java
frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java
frameworks\base\services\core\java\com\android\server\wm\ActivityStartController.java
frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java
SystemServer 执行 startOtherServices 启动服务时,最后会调用 mActivityManagerService.systemReady。AMS.systemReady -> ActivityTaskManagerService.java 中 startHomeOnAllDisplays -> mRootWindowContainer.startHomeOnAllDisplays -> startHomeOnDisplay -> startHomeOnTaskDisplayArea -> ATMS中getHomeIntent获取intent,mService.getActivityStartController().startHomeActivity
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
// ... ... ... ...
Slog.i(TAG, "System now ready");
// ... ... ... ...
synchronized (this) {
// ... ... ... ...
// Start up initial activity.
mBooting = true;
// ... ... ... ...
if (bootingSystemUser) {
t.traceBegin("startHomeOnAllDisplays");
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
t.traceEnd();
}
// ... ... ... ...
}
}
* 小结回顾
感谢并推荐:Android内核开发
Android内核开发:开发板选购
Android内核开发:理解和掌握repo工具
Android内核开发:源码的版本与分支详解
Android内核开发:系统编译输出的镜像文件
Android内核开发:系统分区与镜像文件的烧写
Android内核开发:图解Android系统的启动过程
Android内核开发:如何统计系统的启动时间
Android内核开发:学会分析系统的启动log
Android内核开发:系统启动速度优化