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 // @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 }