OS puts emphases on how to provide interfaces to user's APPs

for using hardware device

in the convenient and efficient way.

Everything has its own logic of running and must be done step by step,no shortcut. 

Take a look at Android OS Framework

Android OS Startup

Now, how to make the above OS run and every component of OS work to provide the service for user APP. Take a look at the process of startup as following picture

Android OS Startup

Android OS Startup

Step1: Startup from power on, Linux start up

  • System boot:bootloader  @bootable/bootloader/* 
    • Comera+Power--->fastboot,
    • Home+Power--->load recovery.img
    • Power--->load boot.img
  • bootloader loads linux kernel
  • linux kernel initialize: @kernel/*

Step2: Android startup

  • kernel loads init-process: @ system/core/init/*
  • read config file: @system/rootdir/init.rc to start android service and start other commands and service(adbd for adb service, vold for SD mount)
  • Start native service, and other services such as ServiceManager,Zygote,media service.
  • Init read init process to start ril-daemon, media, bootsound, bootanim, servicemanager...... 
 1 init:@System/Core/Init
 2 Init.c: parse_config_file(Init.rc)  @parse_config_file(Init.marvel.rc)
 3 解析脚本文件:Init.rc和Init.xxxx.rc(硬件平台相关)
 4 Init.rc是Android自己规定的初始化脚本(Android Init Language, System/Core/Init/readme.txt)
 5 该脚本包含四个类型的声明: Actions, Commands, Services, Options.
 6 1.2 服务启动机制,我们来看看Init是这样解析.rc文件开启服务的。
 71)打开.rc文件,解析文件内容 @system/core/init/init.c
 8 将service信息放置到service_list中。@system/core/init/parser.c
 92)restart_service() @system/core/init/init.c
10 service_start
11 execve(…).建立service进程。
12 
13 
14 export PATH /sbin:/system/sbin:/system/bin 
15 export LD_LIBRARY_PATH /system/lib 
16 mkdir /dev 
17 mkdir /proc 
18 mkdir /sys 
19 mount tmpfs tmpfs /dev 
20 mkdir /dev/pts 
21 mkdir /dev/socket 
22 mount devpts devpts /dev/pts 
23 mount proc proc /proc 
24 mount sysfs sysfs /sys 
25 write /proc/cpu/alignment 4 
26 ifup lo 
27 hostname localhost 
28 domainname localhost 
29 mount yaffs2 mtd@system /system 
30 mount yaffs2 mtd@userdata /data 
31 import /system/etc/init.conf 
32 class_start default 
33 service adbd /sbin/adbd 
34 user adb 
35 group adb 
36 service usbd /system/bin/usbd -r 
37 user usbd 
38 group usbd 
39 socket usbd 666 
40 service zygote /system/bin/app_process -Xzygote /system/bin --zygote 
41 socket zygote 666 
42 service runtime /system/bin/runtime 
43 user system
44 group system 
45 on device-added-/dev/compass 
46 start akmd 
47 on device-removed-/dev/compass 
48 stop akmd 
49 service akmd /sbin/akmd 
50 disabled 
51 user akmd 
52 group akmd 
53 Zygote
54 
55 // @system\core\rootdir\init.rc
56 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
57 socket zygote stream 666 
58 onrestart write /sys/android_power/request_state wake 
59 onrestart write /sys/power/state on 
60 onrestart restart media 

Step3: Zygote Startup

  • In init.rc: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server    
  1 /**
  2  * Main entry of app process.
  3  *
  4  * Starts the interpreted runtime, then starts up the application.
  5  *
  6  */
  7 
  8 #define LOG_TAG "appproc"
  9 
 10 #include <binder/IPCThreadState.h>
 11 #include <binder/ProcessState.h>
 12 #include <utils/Log.h>
 13 #include <cutils/process_name.h>
 14 #include <cutils/memory.h>
 15 #include <android_runtime/AndroidRuntime.h>
 16 
 17 #include <stdio.h>
 18 #include <unistd.h>
 19 
 20 namespace android {
 21 
 22 void app_usage()
 23 {
 24     fprintf(stderr,
 25         "Usage: app_process [java-options] cmd-dir start-class-name [options]\n");
 26 }
 27 
 28 class AppRuntime : public AndroidRuntime
 29 {
 30 public:
 31     AppRuntime()
 32         : mParentDir(NULL)
 33         , mClassName(NULL)
 34         , mClass(NULL)
 35         , mArgC(0)
 36         , mArgV(NULL)
 37     {
 38     }
 39 
 40 #if 0
 41     // this appears to be unused
 42     const char* getParentDir() const
 43     {
 44         return mParentDir;
 45     }
 46 #endif
 47 
 48     const char* getClassName() const
 49     {
 50         return mClassName;
 51     }
 52 
 53     virtual void onVmCreated(JNIEnv* env)
 54     {
 55         if (mClassName == NULL) {
 56             return; // Zygote. Nothing to do here.
 57         }
 58 
 59         /**
 60          * This is a little awkward because the JNI FindClass call uses the
 61          * class loader associated with the native method we're executing in.
 62          * If called in onStarted (from RuntimeInit.finishInit because we're
 63          * launching "am", for example), FindClass would see that we're calling
 64          * from a boot class' native method, and so wouldn't look for the class
 65          * we're trying to look up in CLASSPATH. Unfortunately it needs to,
 66          * because the "am" classes are not boot classes.
 67          *
 68          * The easiest fix is to call FindClass here, early on before we start
 69          * executing boot class Java code and thereby deny ourselves access to
 70          * non-boot classes.
 71          */
 72         char* slashClassName = toSlashClassName(mClassName);
 73         mClass = env->FindClass(slashClassName);
 74         if (mClass == NULL) {
 75             LOGE("ERROR: could not find class '%s'\n", mClassName);
 76         }
 77         free(slashClassName);
 78 
 79         mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
 80     }
 81 
 82     virtual void onStarted()
 83     {
 84         sp<ProcessState> proc = ProcessState::self();
 85         LOGV("App process: starting thread pool.\n");
 86         proc->startThreadPool();
 87 
 88         AndroidRuntime* ar = AndroidRuntime::getRuntime();
 89         ar->callMain(mClassName, mClass, mArgC, mArgV);
 90 
 91         IPCThreadState::self()->stopProcess();
 92     }
 93 
 94     virtual void onZygoteInit()
 95     {
 96         sp<ProcessState> proc = ProcessState::self();
 97         LOGV("App process: starting thread pool.\n");
 98         proc->startThreadPool();
 99     }
100 
101     virtual void onExit(int code)
102     {
103         if (mClassName == NULL) {
104             // if zygote
105             IPCThreadState::self()->stopProcess();
106         }
107 
108         AndroidRuntime::onExit(code);
109     }
110 
111 
112     const char* mParentDir;
113     const char* mClassName;
114     jclass mClass;
115     int mArgC;
116     const char* const* mArgV;
117 };
118 
119 }
120 
121 using namespace android;
122 
123 /**
124  * sets argv0 to as much of newArgv0 as will fit
125  */
126 static void setArgv0(const char *argv0, const char *newArgv0)
127 {
128     strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0));
129 }
130 
131 int main(int argc, const char* const argv[])
132 {
133     // These are global variables in ProcessState.cpp
134     mArgC = argc;
135     mArgV = argv;
136 
137     mArgLen = 0;
138     for (int i=0; i<argc; i++) {
139         mArgLen += strlen(argv[i]) + 1;
140     }
141     mArgLen--;
142 
143     AppRuntime runtime;
144     const char* argv0 = argv[0];
145 
146     // Process command line arguments
147     // ignore argv[0]
148     argc--;
149     argv++;
150 
151     // Everything up to '--' or first non '-' arg goes to the vm
152 
153     int i = runtime.addVmArguments(argc, argv);
154 
155     // Parse runtime arguments.  Stop at first unrecognized option.
156     bool zygote = false;
157     bool startSystemServer = false;
158     bool application = false;
159     const char* parentDir = NULL;
160     const char* niceName = NULL;
161     const char* className = NULL;
162     while (i < argc) {
163         const char* arg = argv[i++];
164         if (!parentDir) {
165             parentDir = arg;
166         } else if (strcmp(arg, "--zygote") == 0) {
167             zygote = true;
168             niceName = "zygote";
169         } else if (strcmp(arg, "--start-system-server") == 0) {
170             startSystemServer = true;
171         } else if (strcmp(arg, "--application") == 0) {
172             application = true;
173         } else if (strncmp(arg, "--nice-name=", 12) == 0) {
174             niceName = arg + 12;
175         } else {
176             className = arg;
177             break;
178         }
179     }
180 
181     if (niceName && *niceName) {
182         setArgv0(argv0, niceName);
183         set_process_name(niceName);
184     }
185 
186     runtime.mParentDir = parentDir;
187 
188     if (zygote) {
189         runtime.start("com.android.internal.os.ZygoteInit",
190                 startSystemServer ? "start-system-server" : "");
191     } else if (className) {
192         // Remainder of args get passed to startup class main()
193         runtime.mClassName = className;
194         runtime.mArgC = argc - i;
195         runtime.mArgV = argv + i;
196         runtime.start("com.android.internal.os.RuntimeInit",
197                 application ? "application" : "tool");
198     } else {
199         fprintf(stderr, "Error: no class name or --zygote supplied.\n");
200         app_usage();
201         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
202         return 10;
203     }
204 }
app_main

相关文章: