Android Zygote系统进程启动过程分析Android N.docx
- 文档编号:23355907
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:27
- 大小:63.42KB
Android Zygote系统进程启动过程分析Android N.docx
《Android Zygote系统进程启动过程分析Android N.docx》由会员分享,可在线阅读,更多相关《Android Zygote系统进程启动过程分析Android N.docx(27页珍藏版)》请在冰豆网上搜索。
AndroidZygote系统进程启动过程分析AndroidN
AndroidZygote系统进程启动过程分析(AndroidN)
在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,因为Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。
Zygote进程也不例外,它是在系统启动的过程,由init进程创建的,在系统启动脚本system/core/rootdir/init.rc文件中,我们可以看到启动Zygote进程的脚本命令:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
import/init.${ro.zygote}.rc
从上面的代码可以看出,在system/core/rootdir目录下系统不止一个zygote*.rc文件
每个文件里的启动zygote方式差不多,下面就以init.zygote64_32.rc为例看下里面的代码
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
servicezygote/system/bin/app_process64-Xzygote/system/bin--zygote--start-system-server--socket-name=zygote
classmain
socketzygotestream660rootsystem
onrestartwrite/sys/android_power/request_statewake
onrestartwrite/sys/power/stateon
onrestartrestartaudioserver
onrestartrestartcameraserver
onrestartrestartmedia
onrestartrestartnetd
writepid/dev/cpuset/foreground/tasks
servicezygote_secondary/system/bin/app_process32-Xzygote/system/bin--zygote--socket-name=zygote_secondary
classmain
socketzygote_secondarystream660rootsystem
onrestartrestartzygote
writepid/dev/cpuset/foreground/tasks
看到上面的代码估计你也能猜出来另外三个zygote*.rc是怎样的,具体选择哪个文件和编译时定义的ro.zygote值有关。
前面的关键字service告诉init进程创建一个名为"zygote"的进程,这个
zygote进程要执行的程序是/system/bin/app_process64,后面是要传给app_process64的参数。
接下来的"classmain"表示执行system/bin/app_process64后调用main方法,socket关键字表示这个zygote进程需要一个名称为"zygote"的socket资源,这样,系统启动后,我们就可以
在/dev/socket目录下看到有一个名为zygote的文件,onrestart关键字表示这个zygote进程重启时需要执行的命令,最后一个writepid关键字表示需要重写系统pid。
通过上面我们知道Zygote进程要执行的程序便是app_process64了,它位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。
(app_process64orapp_process32都是通过
frameworks/base/cmds/app_process编译出来的,只是由编译环境来决定生成那个文件),在分析zygote进程启动之前,来看看它启动的时序图
下面就看看从app_process64到Zygote启动具体流程:
1、在app_main.cpp的main函数中利用AndroidRuntime启动Zygote
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
intmain(intargc,char*constargv[])
{
if(prctl(PR_SET_NO_NEW_PRIVS,1,0,0,0)<0){
//Olderkernelsdon'tunderstandPR_SET_NO_NEW_PRIVSandreturn
//EINVAL.Don'tdieonsuchkernels.
if(errno!
=EINVAL){
LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVSfailed:
%s",strerror(errno));
return12;
}
}
AppRuntimeruntime(argv[0],computeArgBlockSize(argc,argv));
//Processcommandlinearguments
//ignoreargv[0]
argc--;
argv++;
//Everythingupto'--'orfirstnon'-'arggoestothevm.
//
//ThefirstargumentaftertheVMargsisthe"parentdir",which
//iscurrentlyunused.
//
//Aftertheparentdir,weexpectoneormorethefollowinginternal
//arguments:
//
//--zygote:
Startinzygotemode
//--start-system-server:
Startthesystemserver.
//--application:
Startinapplication(standalone,nonzygote)mode.
//--nice-name:
Thenicenameforthisprocess.
//
//Fornonzygotestarts,theseargumentswillbefollowedby
//themainclassname.Allremainingargumentsarepassedto
//themainmethodofthisclass.
//
//Forzygotestarts,allremainingargumentsarepassedtothezygote.
//mainfunction.
//
//Notethatwemustcopyargumentstringvaluessincewewillrewritethe
//entireargumentblockwhenweapplythenicenametoargv0.
inti;
for(i=0;i if(argv[i][0]! ='-'){ break; } if(argv[i][1]=='-'&&argv[i][2]==0){ ++i;//Skip--. break; } runtime.addOption(strdup(argv[i])); } //Parseruntimearguments.Stopatfirstunrecognizedoption. boolzygote=false; boolstartSystemServer=false; boolapplication=false; String8niceName; String8className; ++i;//Skipunused"parentdir"argument. while(i constchar*arg=argv[i++]; if(strcmp(arg,"--zygote")==0){ zygote=true; niceName=ZYGOTE_NICE_NAME; }elseif(strcmp(arg,"--start-system-server")==0){ startSystemServer=true; }elseif(strcmp(arg,"--application")==0){ application=true; }elseif(strncmp(arg,"--nice-name=",12)==0){ niceName.setTo(arg+12); }elseif(strncmp(arg,"--",2)! =0){ className.setTo(arg); break; }else{ --i; break; } } Vector if(! className.isEmpty()){ //We'renotinzygotemode,theonlyargumentweneedtopass //toRuntimeInitistheapplicationargument. // //TheRemainderofargsgetpassedtostartupclassmain().Make //copiesofthembeforeweoverwritethemwiththeprocessname. args.add(application? String8("application"): String8("tool")); runtime.setClassNameAndArgs(className,argc-i,argv+i); }else{ //We'reinzygotemode. maybeCreateDalvikCache(); if(startSystemServer){ args.add(String8("start-system-server")); } charprop[PROP_VALUE_MAX]; if(property_get(ABI_LIST_PROPERTY,prop,NULL)==0){ LOG_ALWAYS_FATAL("app_process: UnabletodetermineABIlistfromproperty%s.", ABI_LIST_PROPERTY); return11; } String8abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); //Inzygotemode,passallremainingargumentstothezygote //main()method. for(;i args.add(String8(argv[i])); } } if(! niceName.isEmpty()){ runtime.setArgv0(niceName.string()); set_process_name(niceName.string()); } if(zygote){ runtime.start("com.android.internal.os.ZygoteInit",args,zygote);//启动ZygoteInit }elseif(className){ runtime.start("com.android.internal.os.RuntimeInit",args,zygote); }else{ fprintf(stderr,"Error: noclassnameor--zygotesupplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process: noclassnameor--zygotesupplied."); return10; } } main函数的主要作用就是创建一个AppRuntime变量,然后调用它的start成员函数,AppRuntime这个类同样是在frameworks/base/cmds/app_process/app_main.cpp文件中定义: [java]viewplaincopy在CODE上查看代码片派生到我的代码片 classAppRuntime: publicAndroidRuntime { public: AppRuntime(char*argBlockStart,constsize_targBlockLength) : AndroidRuntime(argBlockStart,argBlockLength) mClass(NULL) { } voidsetClassNameAndArgs(constString8&className,intargc,char*const*argv){ mClassName=className; for(inti=0;i mArgs.add(String8(argv[i])); } } virtualvoidonVmCreated(JNIEnv*env) { if(mClassName.isEmpty()){ return;//Zygote.Nothingtodohere. } char*slashClassName=toSlashClassName(mClassName.string()); mClass=env->FindClass(slashClassName); if(mClass==NULL){ ALOGE("ERROR: couldnotfindclass'%s'\n",mClassName.string()); } free(slashClassName); mClass=reinterpret_cast } virtualvoidonStarted() { sp : self(); ALOGV("Appprocess: startingthreadpool.\n"); proc->startThreadPool(); AndroidRuntime*ar=AndroidRuntime: : getRuntime(); ar->callMain(mClassName,mClass,mArgs); IPCThreadState: : self()->stopProcess(); } virtualvoidonZygoteInit() { sp : self(); ALOGV("Appprocess: startingthreadpool.\n"); proc->startThreadPool(); } virtualvoidonExit(intcode) { if(mClassName.isEmpty()){ //ifzygote IPCThreadState: : self()->stopProcess(); } AndroidRuntime: : onExit(code); } String8mClassName; Vector jclassmClass; }; 回到上面的main函数中,由于我们在init.zygote64_32.rc文件中,设置了app_process启动参数--zygote和--start-system-server,因此,在main函数里面,最终会执行下面语句: [java]viewplaincopy在CODE上查看代码片派生到我的代码片 runtime.start("com.android.internal.os.ZygoteInit",args,zygote); args参数,在上面main函数里定义的,从main函数可以看出还需要启动start-system-server,这个方法的实现具体如下 [java]viewplaincopy在CODE上查看代码片派生到我的代码片 frameworks/base/core/jni/AndroidRuntime.cpp voidAndroidRuntime: : start(constchar*className,constVector { ALOGD(">>>>>>START%suid%d<<<<<<\n", className! =NULL? className: "(unknown)",getuid()); staticconstString8startSystemServer("start-system-server"); /* *'startSystemServer==true'meansruntimeisobsoleteandnotrunfrom *init.rcanymore,soweprintoutthebootstarteventhere. */ for(size_ti=0;i if(options[i]==startSystemServer){ /*trackourprogressthroughthebootsequence*/ constintLOG_BOOT_PROGRESS_START=3000; LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); } } constchar*rootDir=getenv("ANDROID_ROOT"); if(rootDir==NULL){ rootDir="/system"; if(! hasDir("/system")){ LOG_FATAL("Norootdirectoryspecified,and/androiddoesnotexist."); return; } setenv("ANDROID_ROOT",rootDir,1); } //constchar*kernelHack=getenv("LD_ASSUME_KERNEL"); //ALOGD("FoundLD_ASSUME_KERNEL='%s'\n",kernelHack); /*startthevirtualmachine*/ JniInvocationjni_invocation; jni_invocation.Init(NULL); JNIEnv*env; if(startVm(&mJavaVM,&env,zygote)! =0){ return; } onVmCreated(env); /* *Registerandroidfunctions. */ if(startReg(env)<0){ ALOGE("Unabletoregisterallandroidnatives\n"); return; } /* *Wewanttocallmain()withaStringarraywithargumentsinit. *Atpresentwehavetwoarguments,theclassnameandanoptionstring. *Createanarraytoholdthem. */ jclassstringClass; jobjectArraystrArray; jstringclassNameStr; 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! =
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Zygote系统进程启动过程分析Android Zygote 系统 进程 启动 过程 分析