歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android啟動過程

從內核之上,我們首先應該從文件系統的init開始,因為 init 是內核進入文件系統後第一個運行的程序,通常我們可以在linux的命令行中指定內核第一個調用誰,如果沒指定那麼內核將會到/sbin/, /bin/ 等目錄下查找默認的init,如果沒有找到那麼就報告出錯。
init.c位置:system/core/init/init.c
在init.c的main函數裡面
完成以下步驟:
1、創建設備節點
2、初始化log系統
3、解析init.rc文件,解析函數在同一目錄的parser.c裡面實現
4、初始化屬性服務器,在同一目錄下的property_service.c裡面實現
。。。。
最後、進入loop等待事件到來。
 
 
一、init.rc的解析過程
init.rc是一個初始化腳本,路徑(不確定):device/renesas/emev/init.rc
在init.c的main函數裡面,調用parser.c的parse_config_file("/init.rc");執行解析過程


先讀取文件內容到data裡面,再調用parse_config(fn, data);進行解析


init.rc包含Android初始化語言的四大類聲明:行為類(Actions),命令類(Commands),服務類(Services),選項類(Options),解析完會形成兩個列表service_list 和action_list
其中有一個很重要的服務就是zygote,在init.rc裡面的片段:

  1. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server  
  2.     socket zygote stream 666  
  3.     onrestart write /sys/android_power/request_state wake  
  4.     onrestart write /sys/power/state on  
  5.     onrestart restart media  
這是腳本中service的格式
  1. service <name> <pathname> [ <argument> ]*  
  2. <option>  
  3. <option>  
  4. ...  
zygote對應的可執行文件為app_process,android2.2中它的源代碼位置:framework/base/cmds/app_process
app_main.cpp的main函數,它先調用AndroidRuntime::addVmArguments將它的參數“-Xzygote /system/bin”傳給AndroidRuntime作為啟動JavaVM用。接著如果定位余下的參數,如果有"--zygote",執行下面代碼,從參數可以知道,這時候要求啟動start system server,並且將com.android.internal.os.ZygoteInit裝載至虛擬機
  1. ZygoteInit.java的main方法)。  
  2.         if (0 == strcmp("--zygote", arg)) {  
  3.             bool startSystemServer = (i < argc) ?  
  4.                     strcmp(argv[i], "--start-system-server") == 0 : false;  
  5.             setArgv0(argv0, "zygote");  
  6.             set_process_name("zygote");  
  7.             runtime.start("com.android.internal.os.ZygoteInit",  
  8.                 startSystemServer);  
  9.         }  
否則不啟動system server:
  1. set_process_name(argv0);  
  2.   
  3. runtime.mClassName = arg;  
  4.   
  5. // Remainder of args get passed to startup class main()   
  6. runtime.mArgC = argc-i;  
  7. runtime.mArgV = argv+i;  
  8.   
  9.   
  10. LOGV("App process is starting with pid=%d, class=%s.\n",  
  11.      getpid(), runtime.getClassName());  
  12. runtime.start();  
runtime是AppRuntime對象,繼承自AndroidRuntime,在AndroitRuntime.app裡的start()函數如下,默認裝載的是RuntimeInit進程,不啟動system server.
  1. void AndroidRuntime::start()  
  2. {  
  3.     start("com.android.internal.os.RuntimeInit",  
  4.         false /* Don't start the system server */);  
  5. }  
在AndroidRuntime.cpp的start方法內,先啟動JAVA虛擬機,在定位執行className類的main方法(如果才存在的話)。
  1. void AndroidRuntime::start(const char* className, const bool startSystemServer)  
  2. {  
  3.     LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");  
  4.   
  5.   
  6.     /* start the virtual machine */  
  7.     if (startVm(&mJavaVM, &env) != 0)  
  8.         goto bail;  
  9.   
  10.   
  11.     startClass = env->FindClass(slashClassName);  
  12.     if (startClass == NULL) {  
  13.         LOGE("JavaVM unable to locate class '%s'\n", slashClassName);  
  14.         /* keep going */  
  15.     } else {  
  16.         startMeth = env->GetStaticMethodID(startClass, "main",  
  17.             "([Ljava/lang/String;)V");  
  18.         if (startMeth == NULL) {  
  19.             LOGE("JavaVM unable to find main() in '%s'\n", className);  
  20.             /* keep going */  
  21.         } else {  
  22.             env->CallStaticVoidMethod(startClass, startMeth, strArray);  
  23.         }  
  24.     }  
  25. }  
先看怎麼啟動虛擬機的,在startVm方法內,先將一些系統參數選項,包括虛擬機相關的屬性,保存到一個JavaVMOption的實例內,比如虛擬機的堆大小,是否check jni,JNI版本信息,最後將這些參數傳給JNI_CreateJavaVM,創建JAVA虛擬機實例
  1. JNI_CreateJavaVM在jni.h中有聲明,代碼位置:dalvik/libnativehelper/include/nativehelper/,在Jni.c中有定義  
  2. jint JNI_GetDefaultJavaVMInitArgs(void*);  
  3. jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);  
  4. jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);  
Copyright © Linux教程網 All Rights Reserved