歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android啟動過程

Android啟動過程

日期:2017/3/1 10:41:54   编辑:Linux編程

從內核之上,我們首先應該從文件系統的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. runtime.mClassName = arg;
  3. // Remainder of args get passed to startup class main()
  4. runtime.mArgC = argc-i;
  5. runtime.mArgV = argv+i;
  6. LOGV("App process is starting with pid=%d, class=%s.\n",
  7. getpid(), runtime.getClassName());
  8. 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. /* start the virtual machine */
  5. if (startVm(&mJavaVM, &env) != 0)
  6. goto bail;
  7. startClass = env->FindClass(slashClassName);
  8. if (startClass == NULL) {
  9. LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
  10. /* keep going */
  11. } else {
  12. startMeth = env->GetStaticMethodID(startClass, "main",
  13. "([Ljava/lang/String;)V");
  14. if (startMeth == NULL) {
  15. LOGE("JavaVM unable to find main() in '%s'\n", className);
  16. /* keep going */
  17. } else {
  18. env->CallStaticVoidMethod(startClass, startMeth, strArray);
  19. }
  20. }
先看怎麼啟動虛擬機的,在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