Android 7.0系统启动
随着android版本的升级,aosp项目中的代码也有了些变化,本文基于android 7.0分析android启动流程.当我们按下电源键后,整个android设备大体经过了一下过程:?
今天我们只想来分析init进程及其后的过程,也就是下图所示部分:?
init进程
init进程会解析init.rc文件,加载相关分区,并启动相关服务.
init进程在/system/core/init/init.cpp?
init.rc文件在/system/core/rootdir下?
init.rc文件由parser.cpp解析,在/system/core/init/init_parser.cpp
在init.rc中,zygote进程被启动.zygote进程是其他所有进程的孵化器.init.rc通过include引入init.zygote.rc,这里以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 socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd writepid /dev/cpuset/foreground/tasks
对个脚本简单分析:
service zygote /system/bin/app_process64?:service命令告诉init进程要创建一个名字为zygote的进程,这个zygote进程执行的程序是/system/bin/app_process64,后面是传给app_process64程序的参数.
socket zygote stream 660 root system:表示zygote进程需要一个名为”zygote”的socket,该socket用来实现进程间的通信.当新启动一个应用时,activitymanagerservice想向该socket发起请求,请求zygote进程fork出一个新的进程.
后面的onrestart表示zygote重启时需要执行的动作.
zygote进程启动
zygote进程启动
上面说到init进程会根据init.rc执行相关的操作,其中有一项就是创建zygote进程.zygote进程所对应的程序是/system/bin/app_process,?
位于/frameworks/base/cmds/app_process/app_main.cpp,其入口函数是main():
int main(int argc, char* const argv[]) { if (prctl(pr_set_no_new_privs, 1, 0, 0, 0) < 0) { log_always_fatal("pr_set_no_new_privs failed: %s", strerror(errno)); } if (!log_ndebug) { string8 argv_string; for (int i = 0; i < argc; ++i) { argv_string.append("\""); argv_string.append(argv[i]); argv_string.append("\" "); } alogv("app_process main with argv: %s", argv_string.string()); } appruntime runtime(argv[0], computeargblocksize(argc, argv)); // process command line arguments // ignore argv[0] argc--; argv++; const char* spaced_commands[] = { "-cp", "-classpath" }; bool known_command = false; int i; for (i = 0; i < argc; i++) { if (known_command == true) { runtime.addoption(strdup(argv[i])); alogv("app_process main add known option '%s'", argv[i]); known_command = false; continue; } for (int j = 0; j < static_cast(sizeof(spaced_commands) / sizeof(spaced_commands[0])); ++j) { if (strcmp(argv[i], spaced_commands[j]) == 0) { known_command = true; alogv("app_process main found known command '%s'", argv[i]); } } if (argv[i][0] != '-') { break; } if (argv[i][1] == '-' && argv[i][2] == 0) { ++i; // skip --. break; } runtime.addoption(strdup(argv[i])); alogv("app_process main add option '%s'", argv[i]); } // parse runtime arguments. stop at first unrecognized option. bool zygote = false; bool startsystemserver = false; bool application = false; string8 nicename; string8 classname; ++i; // skip unused "parent dir" argument. while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true; nicename = zygote_nice_name; } else if (strcmp(arg, "--start-system-server") == 0) { //init.zygote64.rc中接受的参数,表示启动systemserver组件 startsystemserver = true; } else if (strcmp(arg, "--application") == 0) { application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { nicename.setto(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { classname.setto(arg); break; } else { --i; break; } } vector args; if (!classname.isempty()) { args.add(application ? string8("application") : string8("tool")); runtime.setclassnameandargs(classname, argc - i, argv + i); if (!log_ndebug) { string8 restofargs; char* const* argv_new = argv + i; int argc_new = argc - i; for (int k = 0; k < argc_new; ++k) { restofargs.append("\""); restofargs.append(argv_new[k]); restofargs.append("\" "); } alogv("class name = %s, args = %s", classname.string(), restofargs.string()); } } else { // we're in zygote mode. maybecreatedalvikcache(); if (startsystemserver) { args.add(string8("start-system-server")); } char prop[prop_value_max]; if (property_get(abi_list_property, prop, null) == 0) { log_always_fatal("app_process: unable to determine abi list from property %s.", abi_list_property); return 11; } string8 abiflag("--abi-list="); abiflag.append(prop); args.add(abiflag); // in zygote mode, pass all remaining arguments to the zygote // main() method. for (; i < argc; ++i) { args.add(string8(argv[i])); } } if (!nicename.isempty()) { runtime.setargv0(nicename.string(), true /* setprocname */); } if (zygote) { //此处见到了我们熟悉的zygoteinit,但该方法的具体实现在//androidruntime.start() 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."); } }
上述代码总体比较简单,主要是处理相关参数,并创建appruntime,由于在init.rc文件中,app_process启动参数被设置为
--zygote --start-system-server,因此会执行
runtime.start("com.android.internal.os.zygoteinit", args, zygote),现在我们来看看appruntime的具体实现,它同样在?
在/frameworks/base/cmds/app_process/app_main.cpp:
class appruntime : public androidruntime { public: appruntime(char* argblockstart, const size_t argblocklength) : androidruntime(argblockstart, argblocklength) , mclass(null) { } void setclassnameandargs(const string8& classname, int argc, char * const *argv) { mclassname = classname; for (int i = 0; i < argc; ++i) { margs.add(string8(argv[i])); } } virtual void onvmcreated(jnienv* env) { if (mclassname.isempty()) { return; // zygote. nothing to do here. } char* slashclassname = toslashclassname(mclassname.string()); mclass = env->findclass(slashclassname); if (mclass == null) { aloge("error: could not find class '%s'\n", mclassname.string()); } free(slashclassname); mclass = reinterpret_cast(env->newglobalref(mclass)); } virtual void onstarted() { spproc = processstate::self(); alogv("app process: starting thread pool.\n"); proc->startthreadpool(); androidruntime* ar = androidruntime::getruntime(); ar->callmain(mclassname, mclass, margs); ipcthreadstate::self()->stopprocess(); } virtual void onzygoteinit() { sp proc = processstate::self(); alogv("app process: starting thread pool.\n"); proc->startthreadpool(); } virtual void onexit(int code) { if (mclassname.isempty()) { // if zygote ipcthreadstate::self()->stopprocess(); } androidruntime::onexit(code); } string8 mclassname; vector margs; jclass mclass; };
appruntime继承androidruntime,而androidruntime位于?
/frameworks/base/core/jni/androidruntime.cpp.?
而start()方法便是定义在androidruntime的虚方法:
//这里的classname的值就是com.android.intrnal.os.zygoteinit void androidruntime::start(const char* classname, const vector& options, bool zygote) { //...省略多行代码 static const string8 startsystemserver("start-system-server"); for (size_t i = 0; i < options.size(); ++i) { if (options[i] == startsystemserver) { /* track our progress through the boot sequence */ const int log_boot_progress_start = 3000; log_event_long(log_boot_progress_start, ns2ms(systemtime(system_time_monotonic))); } } const char* rootdir = getenv("android_root"); if (rootdir == null) { rootdir = "/system"; if (!hasdir("/system")) { log_fatal("no root directory specified, and /android does not exist."); return; } setenv("android_root", rootdir, 1); } //1. 启动虚拟机 if (startvm(&mjavavm, &env, zygote) != 0) { return; } onvmcreated(env); //2. 调用startreg()注册jni方法 if (startreg(env) < 0) { aloge("unable to register all android natives\n"); return; } jclass stringclass; jobjectarray strarray; jstring classnamestr; stringclass = env->findclass("java/lang/string"); assert(stringclass != null); strarray = env->newobjectarray(options.size() + 1, stringclass, null); assert(strarray != null); classnamestr = env->newstringutf(classname); assert(classnamestr != null); env->setobjectarrayelement(strarray, 0, classnamestr); for (size_t i = 0; i < options.size(); ++i) { jstring optionsstr = env->newstringutf(options.itemat(i).string()); assert(optionsstr != null); env->setobjectarrayelement(strarray, i + 1, optionsstr); } char* slashclassname = toslashclassname(classname); jclass startclass = env->findclass(slashclassname); if (startclass == null) { aloge("javavm unable to locate class '%s'\n", slashclassname); } else { //3. 本质就是调用com.android.intrnal.os.zygoteinit类的main函数 jmethodid startmeth = env->getstaticmethodid(startclass, "main", "([ljava/lang/string;)v"); if (startmeth == null) { aloge("javavm unable to find main() in '%s'\n", classname); /* keep going */ } else { env->callstaticvoidmethod(startclass, startmeth, strarray); #if 0 if (env->exceptioncheck()) threadexituncaughtexception(env); #endif } } free(slashclassname); // 省略多行代码 }
在start()方法中主要做三件事情:?
1. 调用startvm()函数启动虚拟机?
2. 调用startreg()注册jni方法?
3. 调用com.android.internal.os.zygoteinit.java类的main函数.
走进zygoteinit
走进zygoteinit
关于前两者就不细说了,重点来关注我们熟悉的zygoteinit.java.它在?
rameworks/base/core/java/com/android/internal/os/zygoteinit.java,我们直接来看他的main方法:
public static void main(string argv[]) { zygoteserver zygoteserver = new zygoteserver(); zygotehooks.startzygotenothreadcreation(); try { os.setpgid(0, 0); } catch (errnoexception ex) { throw new runtimeexception("failed to setpgid(0,0)", ex); } try { trace.tracebegin(trace.trace_tag_dalvik, "zygoteinit"); runtimeinit.enableddms(); // start profiling the zygote initialization. samplingprofilerintegration.start(); 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]); } } if (abilist == null) { throw new runtimeexception("no abi list supplied."); } //创建名为zygote的socket zygoteserver.registerserversocket(socketname); trace.tracebegin(trace.trace_tag_dalvik, "zygotepreload"); //省略多行参数 samplingprofilerintegration.writezygotesnapshot(); // do an initial gc to clean up after startup trace.tracebegin(trace.trace_tag_dalvik, "postzygoteinitgc"); gcandfinalize(); trace.traceend(trace.trace_tag_dalvik); trace.settracingenabled(false); zygote.nativeunmountstorageoninit(); zygotehooks.stopzygotenothreadcreation(); //由于在init.rc中设置了start-system-server参数,因此 //这里将启动systemserver,可见systemserver由zygote创 //建的第一个进程 if (startsystemserver) { //启动systemserver组件 startsystemserver(abilist, socketname, zygoteserver); } log.i(tag, "accepting command socket connections"); //等待activitymanagerservice请求 zygoteserver.runselectloop(abilist); zygoteserver.closeserversocket(); } catch (zygote.methodandargscaller caller) { caller.run(); } catch (throwable ex) { log.e(tag, "system zygote died with exception", ex); zygoteserver.closeserversocket(); throw ex; } }
这里的main()方法中主要做了三件事情?
1. 通过registerserversocket()来创建socket,它将作为服务端用来和作为客户端的activitymanagerservice进行通信?
2. 通过startsystemserver()方法来启动systemserver?
3. 最后通过通过runselectloop方法使得刚才创建的socket进入无限循环,以等待来自activitymanagerservice请求
zygote中socket创建
zygote中socket创建
首先来看
resiterserversocket()它在:
void registerserversocket(string socketname) { if (mserversocket == null) { int filedesc; final string fullsocketname = android_socket_prefix + socketname; try { string env = system.getenv(fullsocketname); //从环境变量env中获取文件描述符, filedesc = integer.parseint(env); } catch (runtimeexception ex) { throw new runtimeexception(fullsocketname + " unset or invalid", ex); } try { //通过文件描述符创建socket,该描述符代表/dev/socket/zygote文件. filedescriptor fd = new filedescriptor(); fd.setint$(filedesc); mserversocket = new localserversocket(fd); } catch (ioexception ex) { throw new runtimeexception( "error binding to local socket '" + filedesc + "'", ex); } } }
方法主要通过文件描述符创建socket,该文件描述代表/dev/socket/zygote文件,现在看看开头init.rc中的配置:
socket zygote stream 660 root system
zygote启动systemserver
zygote启动systemserver
现在来看startsystemserver()方法:
private static boolean startsystemserver(string abilist, string socketname, zygoteserver zygoteserver) throws zygote.methodandargscaller, runtimeexception { long capabilities = posixcapabilitiesasbits( osconstants.cap_ipc_lock, osconstants.cap_kill, osconstants.cap_net_admin, osconstants.cap_net_bind_service, osconstants.cap_net_broadcast, osconstants.cap_net_raw, osconstants.cap_sys_module, osconstants.cap_sys_nice, osconstants.cap_sys_resource, osconstants.cap_sys_time, osconstants.cap_sys_tty_config, osconstants.cap_wake_alarm ); if (!systemproperties.getboolean(property_running_in_container, false)) { capabilities |= posixcapabilitiesasbits(osconstants.cap_block_suspend); } /* 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,1032,3001,3002,3003,3006,3007,3009,3010", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "com.android.server.systemserver", }; zygoteconnection.arguments parsedargs = null; int pid; try { parsedargs = new zygoteconnection.arguments(args); zygoteconnection.applydebuggersystemproperty(parsedargs); zygoteconnection.applyinvokewithsystemproperty(parsedargs); //创建子进程 pid = zygote.forksystemserver( parsedargs.uid, parsedargs.gid, parsedargs.gids, parsedargs.debugflags, null, parsedargs.permittedcapabilities, parsedargs.effectivecapabilities); } catch (illegalargumentexception ex) { throw new runtimeexception(ex); } //pid=0表示子进程,此处就是systemserver进程 if (pid == 0) { //用于处理系统中有两个zygote进程的情况,由于通常我们不会配置两个zygote,因此暂时不关注 if (hassecondzygote(abilist)) { waitforsecondaryzygote(socketname); } //zygote创建的子进程(此处就是systemserver)不需要使用zygote中创建的socket文件描述符,因此通过closeserversocket()关闭它. zygoteserver.closeserversocket(); handlesystemserverprocess(parsedargs); } return true; }
这里首先通过zygote.forksystemserver()创建一个系统服务进程.与该方法相似还有forkandspecialize(),用于创建一个普通应用进程.进程创建成功后返回pid为0.由于此处生成的新进程和zygote进程一模一样,也就是说这个新进程中同样包含了刚才创建的socket,但是该socket在此处无效,因此要将其关闭.接下来调用handlesystemserverprocess()处理刚才新建的进程即systemserver进程,需要注意此时已经工作在systemserver进程中了:
private static void handlesystemserverprocess( zygoteconnection.arguments parsedargs) throws zygote.methodandargscaller { //省略多行代码,此处invokewith为null if (parsedargs.invokewith != null) { string[] args = parsedargs.remainingargs; if (systemserverclasspath != null) { //省略多行代码 } else { classloader cl = null; if (systemserverclasspath != null) { //为systeserver进程创建pathclassloader类加载器 cl = createsystemserverclassloader(systemserverclasspath, parsedargs.targetsdkversion); thread.currentthread().setcontextclassloader(cl); } runtimeinit.zygoteinit(parsedargs.targetsdkversion, parsedargs.remainingargs, cl); } }
该函数继续调用runtimeinit.zygoteinit()进一步执行启动systemserver组件的操作.继续来看 runtimeinit.zygoteinit()的具体实现,它在?
/frameworks/base/core/java/com/android/internal/os/runtimeinit.java文件中:
public static final void zygoteinit(int targetsdkversion, string[] argv, classloader classloader) throws zygote.methodandargscaller { //...省略多行代码 commoninit(); nativezygoteinit(); applicationinit(targetsdkversion, argv, classloader); }
在该方法中主要调用了三个方法:
commoninit():为当前进程的vm设置未捕获异常处理器
nativezygoteinit():binder驱动初始化,该方法完成后,就可以通过该binder进行进程通信
applicationinit():主要用调用com.android.server.systemserver类的main()方法
由于commoninit()方法比较简单,在此就不做分析.?
nativezygoteinit()是一个本地方法,其对应实现在frameworks/base/core/jni/androidruntime.cpp中:
static void com_android_internal_os_runtimeinit_nativezygoteinit(jnienv* env, jobject clazz) { gcurruntime->onzygoteinit(); }
这里的gcurruntime是appruntime的指针,在frameworks/base/core/jni/androidruntime.cpp中定义,并在androidruntime的够赞函数中初始化:
//定义 static androidruntime* gcurruntime = null; ... //在frameworks/base/cmds/app_process/app_main.cpp的main()方法中被调用 androidruntime::androidruntime(char* argblockstart, const size_t argblocklength) : mexitwithoutcleanup(false), margblockstart(argblockstart), margblocklength(argblocklength) { skgraphics::init(); moptions.setcapacity(20); assert(gcurruntime == null); gcurruntime = this; }
继续来看onzygoteinit():
virtual void onzygoteinit() { spproc = processstate::self(); alogv("app process: starting thread pool.\n"); proc->startthreadpool(); }
这里调用processstate::startthreadpool()方法启动线程池,这个线程池就是用来和binder驱动程序进程交互的.(binder驱动本质就是一个文件,位于/dev/binder),关于线程池具体创建的过程暂不做说明.
现在来看applicationinit():
private static void applicationinit(int targetsdkversion, string[] argv, classloader classloader) throws zygoteinit.methodandargscaller { //省略多行代码 invokestaticmain(args.startclass, args.startargs, classloader); }
这里继续调用了invokestaticmain()进行后续工作:
private static void invokestaticmain(string classname, string[] argv, classloader classloader) throws zygoteinit.methodandargscaller { class cl; try { cl = class.forname(classname, true, classloader); } catch (classnotfoundexception ex) { throw new runtimeexception( "missing class when invoking static main " + classname, ex); } method m; try { m = cl.getmethod("main", new class[] { string[].class }); } catch (nosuchmethodexception ex) { //... } catch (securityexception ex) { //... } // 省略多行代码 /* * this throw gets caught in zygoteinit.main(), which responds * by invoking the exception's run() method. this arrangement * clears up all the stack frames that were required in setting * up the process. */ throw new zygoteinit.methodandargscaller(m, argv); }
此时要执行的是com.android.server.systemserver的中mian()方法.此外真正执行的过程是在zygote.methodandargscaller的run()方法中:
public static class methodandargscaller extends exception implements runnable { /** method to call */ private final method mmethod; /** argument array */ private final string[] margs; public methodandargscaller(method method, string[] args) { mmethod = method; margs = args; } public void run() { try { mmethod.invoke(null, new object[] { margs }); } catch (illegalaccessexception ex) { throw new runtimeexception(ex); } catch (invocationtargetexception ex) { //省略多行代码 } } }
methodandargscaller继承exception并实现runnable接口,作为一个异常他被zygoteinit.main()捕获并处理:
public static void main(string argv[]) { // ... try { //...省略多行代码 startsystemserver(abilist, socketname); } catch (methodandargscaller caller) { caller.run(); } catch (throwable ex) { //... } }
现在systemserver的
main()已经被调用,我们顺着来看一下实现:
public class systemserver{ public static void main(string[] args) { new systemserver().run(); } private void run() { try { //...省略一些初始化操作 android.os.process.setthreadpriority( android.os.process.thread_priority_foreground); android.os.process.setcanselfbackground(false); //初始化主线程looper looper.preparemainlooper(); //创建systemservicemanager对象 msystemservicemanager = new systemservicemanager(msystemcontext); localservices.addservice(systemservicemanager.class, msystemservicemanager); } finally { trace.traceend(trace.trace_tag_system_server); } // 启动关键服务 startbootstrapservices(); //启动核心服务 startcoreservices(); //启动其他服务 startotherservices(); //...省略多行代码 //启动消息循环 looper.loop(); } }
在main()方法中调用了run()方法继续启动操作.在run方法中这三个方法非常重要:
startbootstrapservices():启动引导服务,比如ams,pms等
startcoreservices():启动核心服务,比如batteryservice等
startotherservices():启动其他服务,比如networkstatsservice等.
关于systemservice的具体执行过程,在此不做细解.
socket循环监听
socket循环监听
到目前为止,关于
zygoteserver.registerserversocket()和
startsystemserver()的大体流程我们已经弄清除,接下来就是
zygoteserver.runselectloop()方法:
void runselectloop(string abilist) throws zygote.methodandargscaller { arraylist fds = new arraylist(); arraylist peers = new arraylist(); fds.add(mserversocket.getfiledescriptor()); peers.add(null); while (true) { structpollfd[] pollfds = new structpollfd[fds.size()]; for (int i = 0; i < pollfds.length; ++i) { pollfds[i] = new structpollfd(); pollfds[i].fd = fds.get(i); pollfds[i].events = (short) pollin; } try { os.poll(pollfds, -1); } catch (errnoexception ex) { throw new runtimeexception("poll failed", ex); } for (int i = pollfds.length - 1; i >= 0; --i) { if ((pollfds[i].revents & pollin) == 0) { continue; } if (i == 0) { //监听socket链接,如果你做过socket编程就发现此处充当了服务端socket zygoteconnection newpeer = acceptcommandpeer(abilist); peers.add(newpeer); fds.add(newpeer.getfiledesciptor()); } else { //重点关注runonce()方法 boolean done = peers.get(i).runonce(this); if (done) { peers.remove(i); fds.remove(i); } } } } }
该方法非常简单:不断的处理来自客户端ams的请求,然后交给runonce().此处可见android 7.0应用启动流程分析
到现在为止,整个systemserver进程的启动流程已经明确看,用一张顺序图大体的表示上述的整个流程:?