您的位置:首页 > 移动开发 > Android开发

Android开机流程跟踪

2015-10-12 13:26 513 查看
android系统的熟悉少不了对开机流程研究。因此这里简略看一下开机流程。并没有各个大佬的详细,勿喷。一、涉及的类文件:./base/services/java/com/android/server/SystemServer.java./base/core/java/com/android/internal/os/ZygoteInit.java./base/core/java/com/android/internal/os/Zygote.java./base/cmds/app_process/app_main.cpp./base/core/java/com/android/internal/os/RuntimeInit.javaframework/base/core/jni/AndroidRuntime.cpp......二、android开机流程简略图Android系统的开机流程主要部分有下面几个,本篇文章主要是研究systemserver进程到启动服务阶段的源代码。三,Zygote进程的启动在.rc文件中脚本描述在android5.1.1的代码中,*.rc有64和32位的区别,因此比之前的版本多了几个rc文件
./core/rootdir/init.trace.rc
./core/rootdir/init.zygote64_32.rc
./core/rootdir/init.rc
./core/rootdir/init.zygote64.rc
./core/rootdir/init.zygote32.rc
./core/rootdir/init.zygote32_64.rc
[/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
onrestartrestartmedia
onrestartrestartnetd
[/code]其中:service,class,socket等的含义。上面的--zygot--start-system-server--socket-name=zygote为参数配置。上面的参数解析,在./base/cmds/app_process/app_main.cppmain()方法中完成、。
intmain(intargc,char*constargv[])
{
......
//Parseruntimearguments.Stopatfirstunrecognizedoption.
//这里解析参数配置信息确定zygote以及nicename等参数
boolzygote=false;
boolstartSystemServer=false;
boolapplication=false;
String8niceName;
String8className;
++i;//Skipunused"parentdir"argument.
while(i<argc){
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;
}
}
......
//这里设置processname从配置信息我们可以看到,processname为zygote
if(!niceName.isEmpty()){
runtime.setArgv0(niceName.string());
set_process_name(niceName.string());
}
if(zygote){
runtime.start("com.android.internal.os.ZygoteInit",args);
}elseif(className){
runtime.start("com.android.internal.os.RuntimeInit",args);
}else{
//参数配置错误
......
}
}
[/code]接下来在AndroidRuntime的start方法framework/base/core/jni/AndroidRuntime.cpp
/*
*StarttheAndroidruntime.Thisinvolvesstartingthevirtualmachine
*andcallingthe"staticvoidmain(String[]args)"methodintheclass
*namedby"className".
*
*Passesthemainfunctiontwoarguments,theclassnameandthespecified
*optionsstring.
*/
voidAndroidRuntime::start(constchar*className,constVector<String8>&options)
{
staticconstString8startSystemServer("start-system-server");
......
创建根目录/system...
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)!=0){
return;
}
onVmCreated(env);
注册JNI方法
/*
*Registerandroidfunctions.
*/
if(startReg(env)<0){
ALOGE("Unabletoregisterallandroidnatives\n");
return;
}
......封装className等参数信息
/*
*StartVM.ThisthreadbecomesthemainthreadoftheVM,andwill
*notreturnuntiltheVMexits.
*/
char*slashClassName=toSlashClassName(className);
jclassstartClass=env->FindClass(slashClassName);
if(startClass==NULL){
ALOGE("JavaVMunabletolocateclass'%s'\n",slashClassName);
/*keepgoing*/
}else{
jmethodIDstartMeth=env->GetStaticMethodID(startClass,"main",
"([Ljava/lang/String;)V");
if(startMeth==NULL){
ALOGE("JavaVMunabletofindmain()in'%s'\n",className);
/*keepgoing*/
}else{
重点在这里,接下来进入ZygoteInit.java的main方法//com.android.internal.os.ZygoteInitmain
env->CallStaticVoidMethod(startClass,startMeth,strArray);
#if0
if(env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
......
}
[/code]接下来在ZygoteInit.java中main方法framework/base/core/java/com/android/internal/os/ZygoteInit.java
//fulairy
publicstaticvoidmain(Stringargv[]){
try{
......
booleanstartSystemServer=false;
StringsocketName="zygote";
StringabiList=null;
for(inti=1;i<argv.length;i++){
if("start-system-server".equals(argv[i])){
startSystemServer=true;
}elseif(argv[i].startsWith(ABI_LIST_ARG)){
abiList=argv[i].substring(ABI_LIST_ARG.length());
}elseif(argv[i].startsWith(SOCKET_NAME_ARG)){//SOCKET_NAME_ARG=--socket-name=
socketName=argv[i].substring(SOCKET_NAME_ARG.length());
}else{
thrownewRuntimeException("Unknowncommandlineargument:"+argv[i]);
}
}
if(abiList==null){
thrownewRuntimeException("NoABIlistsupplied.");
}
注册socket监听
registerZygoteSocket(socketName);
加载资源文件
preload();加载资源class,resource,libraryetc
触发垃圾回收
//Doaninitialgctocleanupafterstartup
gc();
if(startSystemServer){
startSystemServer(abiList,socketName);
}
runSelectLoop(abiList);
closeServerSocket();
}catch(MethodAndArgsCallercaller){
		//MethodAndArgsCaller异常很重要
caller.run();
}catch(RuntimeExceptionex){
Log.e(TAG,"Zygotediedwithexception",ex);
closeServerSocket();
throwex;
}
}
[/code]从后面的代码跟踪可以看到,startSystemServer会抛出MetthodAndArgsCaller异常,caller.run然后再去调用SystemServer的main方法。三、systemserver进程启动由startSystemServer方法,
/**
*Preparetheargumentsandforkforthesystemserverprocess.
*/
privatestaticbooleanstartSystemServer(StringabiList,StringsocketName)
throwsMethodAndArgsCaller,RuntimeException{
longcapabilities=posixCapabilitiesAsBits(
OsConstants.CAP_BLOCK_SUSPEND,
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
);
/*Hardcodedcommandlinetostartthesystemserver*/
Stringargs[]={
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
"--capabilities="+capabilities+","+capabilities,
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.ArgumentsparsedArgs=null;
intpid;
try{
//这里将参数封装为ZygoteConnection.Arguments参数类型
parsedArgs=newZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/*Requesttoforkthesystemserverprocess*/
//为啥不直接把parsedArgs传递过去就完了....因为需要传递的信息只需要一部分,保证了程序安全性。
pid=Zygote.forkSystemServer(
parsedArgs.uid,parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
}catch(IllegalArgumentExceptionex){
thrownewRuntimeException(ex);
}
/*Forchildprocess*/
if(pid==0){
if(hasSecondZygote(abiList)){
waitForSecondaryZygote(socketName);
}
接下来
handleSystemServerProcess(parsedArgs);
}
returntrue;
}
[/code]需要了解一下forkmethodhandleSystemServerProcess
/**
*Finishremainingworkforthenewlyforkedsystemserverprocess.
*/
privatestaticvoidhandleSystemServerProcess(
ZygoteConnection.ArgumentsparsedArgs)
throwsZygoteInit.MethodAndArgsCaller{
if(parsedArgs.invokeWith!=null){
......
}else{
ClassLoadercl=null;
if(systemServerClasspath!=null){
cl=newPathClassLoader(systemServerClasspath,ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl);
}
/*
*PasstheremainingargumentstoSystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs,cl);
}
/*shouldneverreachhere*/
}
[/code]接下来在RuntimeInit的zygoteInit方法中./base/core/java/com/android/internal/os/RuntimeInit.java
/**
*Themainfunctioncalledwhenstartedthroughthezygoteprocess.This
*couldbeunifiedwithmain(),ifthenativecodeinnativeFinishInit()
*wererationalizedwithZygotestartup.<p>
*
*Currentrecognizedargs:
*<ul>
*<li><code>[--]<startclassname><args>
*</ul>
*
*@paramtargetSdkVersiontargetSDKversion
*@paramargvargstrings
*/
publicstaticfinalvoidzygoteInit(inttargetSdkVersion,String[]argv,ClassLoaderclassLoader)
throwsZygoteInit.MethodAndArgsCaller{
if(DEBUG)Slog.d(TAG,"RuntimeInit:Startingapplicationfromzygote");
redirectLogStreams();//aboutprintandroidlog
//一下三个方法是比较重要的
commonInit();//包含uncaughtexception,timezone,logmanager,HTTPuserAgent,NetworkManagementSocketTagger
nativeZygoteInit();//nativeinit
//thingsinitthatpre
applicationInit(targetSdkVersion,argv,classLoader);
}
[/code]这里要特别看一下applicationInit方法,算是上面几个init方法中最重要的一个
privatestaticvoidapplicationInit(inttargetSdkVersion,String[]argv,ClassLoaderclassLoader)
throwsZygoteInit.MethodAndArgsCaller{
//IftheapplicationcallsSystem.exit(),terminatetheprocess
//immediatelywithoutrunninganyshutdownhooks.Itisnotpossibleto
//shutdownanAndroidapplicationgracefully.Amongotherthings,the
//AndroidruntimeshutdownhooksclosetheBinderdriver,whichcancause
//leftoverrunningthreadstocrashbeforetheprocessactuallyexits.
nativeSetExitWithoutCleanup(true);
//Wewanttobefairlyaggressiveaboutheaputilization,toavoid
//holdingontoalotofmemorythatisn'tneeded.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);//之前的版本好像没有这个方法,应该是5.1中新增,设置sdk版本
finalArgumentsargs;
try{
args=newArguments(argv);
}catch(IllegalArgumentExceptionex){
Slog.e(TAG,ex.getMessage());
//lettheprocessexit
return;
}
//Remainingargumentsarepassedtothestartclass'sstaticmain
接下来有invokeStaticMain方法
invokeStaticMain(args.startClass,args.startArgs,classLoader);
}
[/code]
/**
*Invokesastatic"main(argv[])methodonclass"className".
*ConvertsvariousfailingexceptionsintoRuntimeExceptions,with
*theassumptionthattheywillthencausetheVMinstancetoexit.
*
*@paramclassNameFully-qualifiedclassname
*@paramargvArgumentvectorformain()
*@paramclassLoadertheclassLoadertoload{@className}with
*/
privatestaticvoidinvokeStaticMain(StringclassName,String[]argv,ClassLoaderclassLoader)
throwsZygoteInit.MethodAndArgsCaller{
Class<?>cl;
try{
cl=Class.forName(className,true,classLoader);
}catch(ClassNotFoundExceptionex){
thrownewRuntimeException(
"Missingclasswheninvokingstaticmain"+className,
ex);
}
Methodm;
try{
m=cl.getMethod("main",newClass[]{String[].class});
}catch(NoSuchMethodExceptionex){
thrownewRuntimeException(
"Missingstaticmainon"+className,ex);
}catch(SecurityExceptionex){
thrownewRuntimeException(
"Problemgettingstaticmainon"+className,ex);
}
...themainmethodmustbestaticmain
intmodifiers=m.getModifiers();
if(!(Modifier.isStatic(modifiers)&&Modifier.isPublic(modifiers))){
thrownewRuntimeException(
"Mainmethodisnotpublicandstaticon"+className);
}
//之前我们在ZygoteInit.java中的main方法看到有MethoddAndArgsCaller异常的捕捉caller.run()
/*
*ThisthrowgetscaughtinZygoteInit.main(),whichresponds
*byinvokingtheexception'srun()method.Thisarrangement
*clearsupallthestackframesthatwererequiredinsetting
*uptheprocess.
*/
thrownewZygoteInit.MethodAndArgsCaller(m,argv);
}
[/code]题外话:从上面的流程跟踪下来,个人感觉,google大佬们也在做一些优化,整合。比起4.x甚至3.x的版本。接下来就是在SystemServer中的main方法,启动各个systemservice四、SystemServer启动各个service
/**
*Themainentrypointfromzygote.
*/
publicstaticvoidmain(String[]args){
newSystemServer().run();
}
[/code]我们可以看到MethodAndArgsCaller类中run实现,即直接应用参数Method反射/**884*Helperexceptionclasswhichholdsamethodandargumentsand885*cancallthem.Thisisusedaspartofatrampolinetogetridof886*theinitialprocesssetupstackframes.887*/888publicstaticclassMethodAndArgsCallerextendsException889implementsRunnable{890/**methodtocall*/891privatefinalMethodmMethod;892893/**argumentarray*/894privatefinalString[]mArgs;895896publicMethodAndArgsCaller(Methodmethod,String[]args){897mMethod=method;898mArgs=args;899}900901publicvoidrun(){902try{903mMethod.invoke(null,newObject[]{mArgs});904}catch(IllegalAccessExceptionex){905thrownewRuntimeException(ex);906}catch(InvocationTargetExceptionex){907Throwablecause=ex.getCause();908if(causeinstanceofRuntimeException){909throw(RuntimeException)cause;910}elseif(causeinstanceofError){911throw(Error)cause;912}913thrownewRuntimeException(ex);914}915}916}......后面的世界面孔那就多了......上面部分大致的流程图就是这样,图画的比较随性,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android开发 源代码