一、Android 启动流程概括
按下电源键触发开机,从 ROM 加载引导程序 BootLoader 到 RAM 中,BootLoader 执行启动 Linux kernel,然后启动第一个用户进程 init,init 进程的工作包括挂载文件、创建文件目录、设置 selinux 安全策略,解析 init.rc 脚本等。随后 init 进程会启动 Zygote 进程,Zygote 进程做一些资源预加载的工作,并启动 SystemServer 进程。SystemServer 进程作为 Socket 服务端,启动包括 AMS、WMS、PMS 等 90 多个服务在内的系统服务。在众多服务启动完毕后,AMS 会打开 Launcher 应用的 Home Activity,进入手机桌面。
附:kernel 的初始化流程(详细代码自行下载 linux kernel 源码)
传统的加载器包含两个文件
init.s:初始化堆栈,调用 main.c 的 main() 函数
main.c:初始化硬件(主板、闹钟等),创建 linux 标签
当内核完成系统设置后,会在系统文件中寻找 init 文件。
Dir:kernel/common/init/main.c
(1)执行 kernel_init() 函数
(2)启动 /bin/init 文件:try_to_run_init_process("/bin/init");
(3)try_to_run_init_process() ---> run_init_process()--->kernel_execve()
init/android.bp 中指明了 init 的入口函数:init/main.cpp,随后会执行 main.cpp 中的 main 方法
二、init 进程的启动流程
Dir:system/core/init/main.cpp ---> main() 方法
FirstStageMain() ---- SetupSelinux() ---- SecondStageMain()
第一阶段
FirstStageMain()
1、mount()--挂载文件、mkdir()--创建文件目录
2、SetStdioToDevNull()--重定向标准输入输出
3、InitKernelLogging()--初始化内核日志
4、启动 setupSelinux
SetupSelinux()
配置安全策略 -- 对应安卓的权限策略
第二阶段
SecondStageMain()
1、初始化属性系统
PropertyInit()
2、监听子进程的终止信号,释放资源,防止僵尸进程
InstallSignalFdHandler(&epoll);
InstallInitNotifier(&epoll);
StartPropertyService(&property_fd);
3、匹配 linux 命令和实际执行函数之间的关系
GetBuiltinFunctionMap()
4、解析 init.rc
LoadBootScripts(am, sm)
-->CreateParser() //创建解析器
-->//添加 rc 文件的解析组件 service、on、import
parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, GetSubcontext(), std::nullopt));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
-->//解析 rc 文件
parser.ParseConfig("/system/etc/init/hw/init.rc");
-->ParserConfigDir-->ParserConfigFile
-->ParserConfigFile
-->ParserData
5、While(true) 循环监听
auto pending_functions = epoll.Wait(epoll_timeout);
总结:init 进程处理的事情:
1、 挂载文件
2、设置 selinux -- 安全策略
3、开启属性服务,注册到 epoll 中
4、解析 init.rc
5、循环处理脚本,包括启动 zygote
6、循环等待
启动 Service 的过程
/system/core/rootdir/init.rc
-->
on nonencrypted
class_start main --> do_class_start(const BuiltinArguments& args)
class_start late_start
/system/core/init/builtins.cpp
-->do_class_start(const BuiltinArguments& args)
-->StartIfNotDisabled()
/system/core/init/service.cpp
-->StartIfNotDisabled()
-->Start()
三、Zygote 启动流程
1、触发 Zygote
Dir:/system/core/rootdir/init.rc
(1)init.rc 中引入的 zygote.rc 脚本
import /system/etc/init/hw/init.${ro.zygote}.rc
不同的 rc 配置文件对应不同的启动策略
根据不同厂商共有四个属性:
init.zygote32.rc -- 执行 app_process
init.zygote64.rc --执行 app_process64
init.zygote32_64.rc -- 启动两个 zygote 进程,名为 zygote 和 zygote_secondary,分别执行 app_process32、app_process64
init.zygote64_32.rc -- -- 启动两个 zygote 进程,名为 zygote 和 zygote_secondary,分别执行 app_process64、app_process32
(2)zygote 触发时机
on late-init
-->trigger zygote-start
on zygote-start
-->start zygote
Dir:/system/core/init/init.cpp
if (bootmode == "charger") {
am.QueueEventTrigger("charger");
} else {
am.QueueEventTrigger("late-init");
}
附:app_process 位于手机系统的 bin 目录下,在 AS File Explorer 中可以看到,app_process 会
读取到 /frameworks/base/cmds/app_process/Android.bp 文件,然后执行 app_main.cpp,
/frameworks/base/cmds/app_process/app_main.cpp 的 main 方法解析的参数,则来源于 init.zygote.rc
2、Zygote 初始化
Dir:/frameworks/base/cmds/app_process/app_main.cpp
(1)main() 进行参数解析【--zygote --start-system-server】
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
}
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
(2)创建虚拟机及注册 JNI
Dir:frameworks/base/core/jni/AndroidRuntime.cpp
startVm() -- 创建虚拟机
startReg() -- 注册 JNI
--> register_jni_procs(gRegJNI, NELEM(gRegJNI), env) //gRegJNI 是一个 jni 数组对象
env->CallStaticVoidMethod(startClass, startMeth, strArray); //startClass 即传入的ZygoteInit
//接下来就会执行 ZygoteInit.java 的 main 方法,从 native 层进入 java 层
//JVM :虚拟机,其实就是一块代码,负责实现内存管理,因为是 zygote 通过 fork 创建的进程,所以每个进程都拥有一个独立的 JVM
3、Zygote 的 java 启动
(1)预加载,加快 app 进程的启动
Dir:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java -- main()
preload(bootTimingsTraceLog);
(1)bootTimingsTraceLog.traceBegin("PreloadClasses");
//preloadClassess 将framework.jar里的preloaded-classes 定义的所有class load到内存里,preloaded-classes 编译Android后可以在framework/base下找到。
//会加载手机 system/etc/preloaded-classes 文件中记录好的类文件
(2)preloadResources();
//preloadResources 将系统的Resource(不是在用户apk里定义的resource)load到内存。资源preload到Zygoted的进程地址空间,所有fork的子进程将共享这份空间而无需重新load, 这大大减少了应用程序的启动时间,但反过来增加了系统的启动时间。通过对preload 类和资源数目进行调整可以加快系统启动。Preload也是Android启动最耗时的部分之一
(2)通知 VM 进行垃圾回收
//gc()必须在fork之前完成(接下来的StartSystemServer就会有fork操作),这样将来被复制出来的子进程才能有尽可能少的垃圾内存没有释放
gcAndFinalize();
(3)创建 zygote 服务端,本质上是一个 socket
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
zygoteServer = new ZygoteServer(isPrimaryZygote);
-->
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
-->
//frameworks/base/core/java/com/android/internal/os/Zygote.java
return new LocalServerSocket(fd);
(4)创建 SystemServer 进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
ZygoteInit.java--forkSystemServer()
-->Zygote.java--nativeForkSystemServer()
-->com_android_internal_os_Zygote_nativeForkSystemServer.cpp【通过 JNI 的映射】
-->pid_t pid = zygote::ForkCommon(env, true,fds_to_close,fds_to_ignore,true);
-->pid_t pid = fork(); //最终调用 linux 的 fork()
(5)循环等待
caller = zygoteServer.runSelectLoop(abiList);
四、SystemServer 启动流程
1、参数处理
//ZygoteInit.java
//在 handleSystemServerProcess() 中进行 server 的初始化工作
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
//(1) prepareSystemServerProfile(systemServerClasspath);
//(2) 判断fork args 中是否有 invokWith 参数,如果有则进行WrapperInit.execApplication
if (parsedArgs.mInvokeWith != null) {
String[] args = parsedArgs.mRemainingArgs;
// If we have a non-null system server class path, we'll have to duplicate the
// existing arguments and append the classpath to it. ART will handle the classpath
// correctly when we exec a new process.
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(args, 0, amendedArgs, 2, args.length);
args = amendedArgs;
}
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
ClassLoader cl = getOrCreateSystemServerClassLoader();
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
2、初始化
(1) ZygoteInit
//ZygoteInit.java
ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, cl);
-->
ZygoteInit.nativeZygoteInit();
-->
//JNI
com_android_internal_os_ZygoteInit_nativeZygoteInit
-->
//AndroidRuntime.cpp
gCurRuntime->onZygoteInit();
-->
//app_main.cpp
virtual void onZygoteInit(){
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
//启动一个 Binder 线程池,用于 SystemServer 和其他线程的通信
proc->startThreadPool();
}
(2)applicationInit
//ZygoteInit.java
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,classLoader);
-->
//RuntimeInit.java
return findStaticMain(args.startClass, args.startArgs, classLoader);
-->
//RuntimeInit.java; 通过反射找到SystemServer 的 main 方法
m = cl.getMethod("main", new Class[] { String[].class });
return new MethodAndArgsCaller(m, argv);
//耗时操作通过线程完成,MethodAndArgsCaller 的 run 方法中执行
mMethod.invoke(null, new Object[] {null, new Object[]{ mArgs });
-->
//SystemServer 的 main 方法执行:
public static void main(String[] args) {
new SystemServer().run();
}
五、SystemServer 执行流程
1、初始化
(1)一些属性的设置
(2)初始化上下文
// Initialize the system context.
createSystemContext();
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
2、创建 SystemServiceManager
//初始化SystemServiceManager,用来管理启动service,SystemServiceManager中封装了启动Service的startService方法启动系统必要的Service
mSystemServiceManager = new SystemServiceManager(mSystemContext);
3、启动一系列系统服务
try {
t.traceBegin("StartServices");
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
startApexServices(t);
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}