Android OS Startup

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

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

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
1 // @system\core\rootdir\init.rc
2 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
3 socket zygote stream 666 
4 onrestart write /sys/android_power/request_state wake 
5 onrestart write /sys/power/state on 
6 onrestart restart media 

 

  • Zygote start up from main(…) of app_process   //@frameworks/base/cmds/app_main.cpp。
  • Create Java Runtime:  runtime.start("com.android.internal.os.ZygoteInit.java", startSystemServer); //@AndroidRuntime.cpp  
  • Make Zygote run:com.android.internal.os.ZygoteInit:main()  //@com.android.internal.os.ZygoteInit
  • registerZygoteSocket();
  • startSystemServer();com.android.internal.os.ZygoteInit:startSystemServer() //@com.android.internal.os.ZygoteInit.
  • Now the Zygote service framework is built, and accept the requet from ActivityManagerService via Socket to fork APP.
  • Zygote.forkSystemServer(@dalvik.system.Zygote.java) is mapped to the process of linux with pid.
 1 public static void main(String argv[]) 
 2 {
 3     try {
 4         // Start profiling the zygote initialization.
 5         SamplingProfilerIntegration.start();
 6         registerZygoteSocket();
 7         EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis());
 8         preload();
 9         EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());
10         // Finish profiling the zygote initialization.
11         SamplingProfilerIntegration.writeZygoteSnapshot();
12         // Do an initial gc to clean up after startup
13         gc();
14         // If requested, start system server directly from Zygote
15         if (argv.length != 2) {
16             throw new RuntimeException(argv[0] + USAGE_STRING);
17         }
18         if (argv[1].equals("start-system-server")) {
19             startSystemServer();
20         } else if (!argv[1].equals("")) {
21             throw new RuntimeException(argv[0] + USAGE_STRING);
22         }
23         Log.i(TAG, "Accepting command socket connections");
24         if (ZYGOTE_FORK_MODE) {
25             runForkMode();
26         } else {
27             runSelectLoopMode();
28         }
29         closeServerSocket();
30     } catch (MethodAndArgsCaller caller) {
31         caller.run();
32     } catch (RuntimeException ex) {
33         Log.e(TAG, "Zygote died with exception", ex);
34         closeServerSocket();
35         throw ex;
36     }
37 }
 1 private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException 
 2 {
 3     /* Hardcoded command line to start the system server */
 4     String args[] = {
 5         "--setuid=1000",
 6         "--setgid=1000",
 7         "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
 8         "--capabilities=130104352,130104352",
 9         "--runtime-init",
10         "--nice-name=system_server",
11         "com.android.server.SystemServer",
12     };
13     ZygoteConnection.Arguments parsedArgs = null; 
14     int pid;
15     
16     try {
17         parsedArgs = new ZygoteConnection.Arguments(args);
18         ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
19         ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);  
20         /* Request to fork the system server process */
21         pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,   
22                                       parsedArgs.gids,                  
23                                       parsedArgs.debugFlags,            
24                                       null,                             
25                                       parsedArgs.permittedCapabilities, 
26                                       parsedArgs.effectiveCapabilities);
27     } 
28     catch (IllegalArgumentException ex) 
29     {
30         throw new RuntimeException(ex);
31     }
32     /* For child process */
33     if (pid == 0) {
34         handleSystemServerProcess(parsedArgs);
35     }
36     return true;
37 }

 

 1 //@dalvik.system.Zygote.java
 2 public static int forkSystemServer(int uid, int gid, int[] gids,int debugFlags, int[][] rlimits,long permittedCapabilities, long effectiveCapabilities) 
 3 {
 4     preFork();
 5     //call native method to fork a process of system server which is mappged to linux process
 6     int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits,
 7                                      permittedCapabilities,
 8                                      effectiveCapabilities);
 9     postFork();
10     return pid;
11 }

 

Step3:SystemServer Startup

  • Zygote fork a process of SystemServer: forkSystemServer() //@dalvik.system.Zygote.java
  • Zygote.nativeForkSystemServer() //@dalvik/vm/native/dalvik_system_Zygote.c
  • SystemServer is created and running.
  • com.android.server.SystemServer:init1(): The native method start all system native service.
  • com.android.server.SystemServer:init2(): Create a ServerThread to add just created native service by init1() to service list and finally loop.

    com.android.server.SystemServer:main()//@com.android.server.SystemServer.java

 1 public static void main(String[] args) 
 2 {
 3     if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
 4         // If a device's clock is before 1970 (before 0), a lot of
 5         // APIs crash dealing with negative numbers, notably
 6         // java.io.File#setLastModified, so instead we fake it and
 7         // hope that time from cell towers or NTP fixes it
 8         // shortly.
 9         Slog.w(TAG, "System clock is before 1970; setting to 1970.");
10         SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
11     }
12     if (SamplingProfilerIntegration.isEnabled()) {
13         SamplingProfilerIntegration.start();
14         timer = new Timer();
15         timer.schedule(new TimerTask() 
16             {
17              @Override
18              public void run() {
19                 SamplingProfilerIntegration.writeSnapshot("system_server", null);
20             }
21         }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
22     }
23     // Mmmmmm... more memory!
24     dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
25     // The system server has to run all of the time, so it needs to be
26     // as efficient as possible with its memory usage.
27     VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
28System.loadLibrary("android_servers");//load android_servers.so
29    init1(args);
30 }
31 /***
32  * This method is called from Zygote to initialize the system. This will cause the native
33  * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
34  * up into init2() to start the Android services.
35  */
36 native public static void init1(String[] args);
37 
38 public static final void init2() {
39     Slog.i(TAG, "Entered the Android system server!");
40     Thread thr = new ServerThread();
41     thr.setName("android.server.ServerThread");
42     thr.start();
43 }

 

  1 //@com.android.server.SystemService
  2 class ServerThread extends Thread 
  3 {
  4     ......    
  5     @Override
  6     public void run() 
  7     {
  8         ...............................
  9         Looper.prepare();
 10         android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
 11         BinderInternal.disableBackgroundScheduling(true);
 12         android.os.Process.setCanSelfBackground(false);
 13         // Check whether we failed to shut down last time we tried.
 14         {
 15             ....................
 16         }        
 17         String factoryTestStr = SystemProperties.get("ro.factorytest");
 18         int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
 19                 : Integer.parseInt(factoryTestStr);
 20         .......//declare all native service object.
 21         // Critical services...add all service into list of service manager
 22         try {
 23             Slog.i(TAG, "Entropy Service");
 24             ServiceManager.addService("entropy", new EntropyService());
 25             power = new PowerManagerService();
 26             ServiceManager.addService(Context.POWER_SERVICE, power);
 27             context = ActivityManagerService.main(factoryTest);           
 28             ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
 29             AttributeCache.init(context);                       
 30             ........................
 31             alarm = new AlarmManagerService(context);
 32             ServiceManager.addService(Context.ALARM_SERVICE, alarm);          
 33             Watchdog.getInstance().init(context, battery, power, alarm,ActivityManagerService.self());
 34             Slog.i(TAG, "Window Manager");
 35             wm = WindowManagerService.main(context, power,factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,!firstBoot);
 36             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
 37             ActivityManagerService.self().setWindowManager(wm);            
 38             .......................
 39 
 40         } catch (RuntimeException e) {           
 41         }
 42         .............................
 43         // Bring up services needed for UI.
 44         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) 
 45         {
 46             try {
 47                 Slog.i(TAG, "Input Method Service");
 48                 imm = new InputMethodManagerService(context);
 49                 ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
 50             } catch (Throwable e) {
 51                 reportWtf("starting Input Manager Service", e);
 52             }
 53            .......................
 54         }
 55 
 56         try {
 57             wm.displayReady();
 58         } catch (Throwable e) {
 59             reportWtf("making display ready", e);
 60         }
 61 
 62         try {
 63             pm.performBootDexOpt();
 64         } catch (Throwable e) {
 65             reportWtf("performing boot dexopt", e);
 66         }
 67 
 68         try {
 69             ActivityManagerNative.getDefault().showBootMessage(context.getResources().getText(
 70                                         com.android.internal.R.string.android_upgrading_starting_apps),
 71                                        false);
 72         } catch (RemoteException e) {
 73         }
 74         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
 75             try {
 76                 Slog.i(TAG, "Device Policy");
 77                 devicePolicy = new DevicePolicyManagerService(context);
 78                 ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
 79             } catch (Throwable e) {
 80                 reportWtf("starting DevicePolicyService", e);
 81             }
 82             ....................
 83            try {
 84                 Slog.i(TAG, "Wi-Fi Service");
 85                 wifi = new WifiService(context);
 86                 ServiceManager.addService(Context.WIFI_SERVICE, wifi);
 87             } catch (Throwable e) {
 88                 reportWtf("starting Wi-Fi Service", e);
 89             }      
 90            ....................  
 91            try {
 92                 Slog.i(TAG, "NetworkTimeUpdateService");
 93                 networkTimeUpdater = new NetworkTimeUpdateService(context);
 94             } catch (Throwable e) {
 95                 reportWtf("starting NetworkTimeUpdate service", e);
 96             }
 97         }
 98         // Before things start rolling, be sure we have decided whether
 99         // we are in safe mode.
100         final boolean safeMode = wm.detectSafeMode();
101         if (safeMode) {
102             ActivityManagerService.self().enterSafeMode();
103             // Post the safe mode state in the Zygote class
104             Zygote.systemInSafeMode = true;
105             // Disable the JIT for the system_server process
106             VMRuntime.getRuntime().disableJitCompilation();
107         } else {
108             // Enable the JIT for the system_server process
109             VMRuntime.getRuntime().startJitCompilation();
110         }
111         // It is now time to start up the app processes...
112         if (devicePolicy != null) {
113             try {
114                 devicePolicy.systemReady();
115             } catch (Throwable e) {
116                 reportWtf("making Device Policy Service ready", e);
117             }
118         }
119         if (notification != null) {
120             try {
121                 notification.systemReady();
122             } catch (Throwable e) {
123                 reportWtf("making Notification Service ready", e);
124             }
125         }
126         try {
127             wm.systemReady();
128         } catch (Throwable e) {
129             reportWtf("making Window Manager Service ready", e);
130         }
131         if (safeMode) {
132             ActivityManagerService.self().showSafeModeOverlay();
133         }
134         // Update the configuration for this context by hand, because we're going
135         // to start using it before the config change done in wm.systemReady() will
136         // propagate to it.
137         ..................................
138         power.systemReady();
139         try {
140             pm.systemReady();
141         } catch (Throwable e) {
142             reportWtf("making Package Manager Service ready", e);
143         }
144 
145         // These are needed to propagate to the runnable below.
146         final Context contextF = context;
147         final BatteryService batteryF = battery;
148         .........................
149         // We now tell the activity manager it is okay to run third party
150         // code.  It will call back into us once it has gotten to the state
151         // where third party code can really run (but before it has actually
152         // started launching the initial applications), for us to complete our
153         // initialization.
154         ActivityManagerService.self().systemReady(new Runnable() {
155             public void run() {
156                 Slog.i(TAG, "Making services ready");
157                 startSystemUi(contextF);
158                 try {
159                     if (batteryF != null) batteryF.systemReady();
160                 } catch (Throwable e) {
161                     reportWtf("making Battery Service ready", e);
162                 }
163                 .....................
164                 try {
165                     if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
166                 } catch (Throwable e) {
167                     reportWtf("making Text Services Manager Service ready", e);
168                 }
169             }
170         });
171 
172         // For debug builds, log event loop stalls to dropbox for analysis.
173         if (StrictMode.conditionallyEnableDebugLogging()) {
174             Slog.i(TAG, "Enabled StrictMode for system server main thread.");
175         }
176         Looper.loop();
177         Slog.d(TAG, "System ServerThread is exiting!");
178     }
179     static final void startSystemUi(Context context) {
180         Intent intent = new Intent();
181         intent.setComponent(new ComponentName("com.android.systemui",
182                     "com.android.systemui.SystemUIService"));
183         Slog.d(TAG, "Starting service: " + intent);
184         context.startService(intent);
185     }
186 }

  

 

Step4:Home luncher Startup

 

 

http://blog.csdn.net/maxleng/article/details/5508372

http://wenku.baidu.com/view/fc7729375a8102d276a22f13.html

http://wenku.baidu.com/view/42ebf459be23482fb4da4c33.html

http://www.cnblogs.com/linucos/archive/2012/05/22/2513760.html

Android's Process & Thread

 

posted @ 2013-08-06 15:46  iDragon  阅读(893)  评论(0)    收藏  举报