Android Zygote系统进程启动过程分析Android N.docx

上传人:b****8 文档编号:8960002 上传时间:2023-05-16 格式:DOCX 页数:27 大小:63.42KB
下载 相关 举报
Android Zygote系统进程启动过程分析Android N.docx_第1页
第1页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第2页
第2页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第3页
第3页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第4页
第4页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第5页
第5页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第6页
第6页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第7页
第7页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第8页
第8页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第9页
第9页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第10页
第10页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第11页
第11页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第12页
第12页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第13页
第13页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第14页
第14页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第15页
第15页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第16页
第16页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第17页
第17页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第18页
第18页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第19页
第19页 / 共27页
Android Zygote系统进程启动过程分析Android N.docx_第20页
第20页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Android Zygote系统进程启动过程分析Android N.docx

《Android Zygote系统进程启动过程分析Android N.docx》由会员分享,可在线阅读,更多相关《Android Zygote系统进程启动过程分析Android N.docx(27页珍藏版)》请在冰点文库上搜索。

Android Zygote系统进程启动过程分析Android N.docx

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;

}

}

Vectorargs;

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(env->NewGlobalRef(mClass));

}

virtualvoidonStarted()

{

spproc=ProcessState:

:

self();

ALOGV("Appprocess:

startingthreadpool.\n");

proc->startThreadPool();

AndroidRuntime*ar=AndroidRuntime:

:

getRuntime();

ar->callMain(mClassName,mClass,mArgs);

IPCThreadState:

:

self()->stopProcess();

}

virtualvoidonZygoteInit()

{

spproc=ProcessState:

:

self();

ALOGV("Appprocess:

startingthreadpool.\n");

proc->startThreadPool();

}

virtualvoidonExit(intcode)

{

if(mClassName.isEmpty()){

//ifzygote

IPCThreadState:

:

self()->stopProcess();

}

AndroidRuntime:

:

onExit(code);

}

String8mClassName;

VectormArgs;

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&options,boolzygote)

{

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!

=

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2