android开机启动流程简单分析android启动当引导程序启动Linux内核后,会加载各种驱动和数据结构,当有了驱动以后,开始启动Android系统同时会加载用户级别的第一个进程init(system\core\init\init.cpp)代码如下:int main(int argc, char** argv) {.....//创建文件夹,挂载// Get the basic filesystem setup we need put together in the initramdisk// on / and then we'll let the rc file figure out the rest.if (is_first_stage) {mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");mkdir("/dev/pts", 0755);mkdir("/dev/socket", 0755);mount("devpts", "/dev/pts", "devpts", 0, NULL);#define MAKE_STR(x) __STRING(x)mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));mount("sysfs", "/sys", "sysfs", 0, NULL);}.....//打印日志,设置log的级别klog_init();klog_set_level(KLOG_NOTICE_LEVEL);.....Parser& parser = Parser::GetInstance();parser.AddSectionParser("service",std::make_unique<ServiceParser>());parser.AddSectionParser("on", std::make_unique<ActionParser>());parser.AddSectionParser("import", std::make_unique<ImportParser>());// 加载init.rc配置文件parser.ParseConfig("/init.rc");}加载init.rc文件,会启动一个Zygote进程,此进程是Android系统的一个母进程,用来启动Android的其他服务进程,代码:从Android L开始,在/system/core/rootdir 目录中有4 个zygote 相关的启动脚本如下图:在init.rc文件中,有如下代码:import /init.environ.rcimport /b.rcimport /init.${ro.hardware}.rcimport /b.configfs.rcimport /init.${ro.zygote}.rc注意到上面的代码import /init.${ro.zygote}.rc,这里会读取ro.zygote这个属性,导入相应的init.rc文件。
ro.zygote的属性可为:zygote32、zygote64、zygote32_64、zygote64_32。
对于这个属性的解释如下。
init.zygote32.rc:zygote 进程对应的执行程序是app_process (纯32bit 模式)init.zygote64.rc:zygote 进程对应的执行程序是app_process64 (纯64bit 模式)init.zygote32_64.rc:启动两个zygote 进程(名为zygote 和zygote_secondary),对应的执行程序分别是app_process32 (主模式)、app_process64。
init.zygote64_32.rc:启动两个zygote 进程(名为zygote 和zygote_secondary),对应的执行程序分别是app_process64 (主模式)、app_process32主流的机型属性都为zygote64_32,我们来看看init.zygote64_32.rc文件:service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygoteclass mainsocket zygote stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart audioserveronrestart restart cameraserveronrestart restart mediaonrestart restart netdwritepid /dev/cpuset/foreground/tasksservice zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondaryclass mainsocket zygote_secondary stream 660 root systemonrestart restart zygotewritepid /dev/cpuset/foreground/tasks在Linux 系统中,service 通常是一种被称为守护进程(daemon) 的程序。
它通常在系统启动时启动,并一直运行于后台,直到系统关闭时终止。
这里会以service方式来启动zygote进程,app_process的代码位于/frameworks/base/cmds/app_process/路径下,该路径下有一个文件app_main.cpp,入口是main 函数。
接下来看app_main.cpp函数,这里实现从c++代码调到java代码:int main(int argc, char* const argv[]){.....//android运行时环境AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// Process command line arguments// ignore argv[0]argc--;argv++;.....if (zygote) {//启动java代码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.");return 10;}}ZygoteInit.java 代码:/frameworks/base/core/Java/com/android/internal/os/ZygoteInit.javapublic static void main(String argv[]) {.....try {.....boolean startSystemServer = false;String socketName = "zygote";String abiList = null;for (int i = 1; i < argv.length; i++) {if ("start-system-server".equals(argv[i])) {startSystemServer = true;} else if (argv[i].startsWith(ABI_LIST_ARG)) {abiList = argv[i].substring(ABI_LIST_ARG.length());} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {socketName = argv[i].substring(SOCKET_NAME_ARG.length());} else {throw new RuntimeException("Unknown command line argument: " + argv[i]);}}.....//预加载android依赖的文件preload();.....if (startSystemServer) {//启动系统服务startSystemServer(abiList, socketName);}.....} catch (MethodAndArgsCaller caller) {caller.run();} catch (Throwable ex) {Log.e(TAG, "Zygote died with exception", ex);closeServerSocket();throw ex;}}看这个类的main方法,最上面根据传入的参数判断是否将startSystemServer这个标记设为true,接着预加载android依赖的文件,最后根据上面设置的标记来判断是否能启动系统服务。