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文件开启服务的。 7 (1)打开.rc文件,解析文件内容 @system/core/init/init.c 8 将service信息放置到service_list中。@system/core/init/parser.c 9 (2)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 // @systemcore ootdirinit.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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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] "); 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' ", 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. "); 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. "); 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. "); 200 app_usage(); 201 LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); 202 return 10; 203 } 204 }
1 // @systemcore ootdirinit.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