Dec 16, 2009(Wed) [くもり]明日は FF13!! な水曜日 [長年日記]
_ く〜っ, 昨日より寒い!!!! よ〜く考えると当たり前なんだけど, スピードは出ないし疲れる上りをがんばるより, らく〜にスピードを出せる下りをがんばる方が時間を短縮できる.
_ zygote 起動
カーネルが起動して最初にコールされるのが, init.rc なのだが, その中で, 最初の(というか, system server?)zygote が起動する. 起動スクリプトはこんな感じ.
system/core/rootdir/init.rc: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server socket zygote stream 666 onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media
app_process で zygote を起動させてます. app_process は zygote 以外のアプリも起動出来るみたい. am も内部で app_process をコールしているよ. ココでのポイントは `--start-system-server' を追加しているって事です. app_process の中身は...
frameworks/base/cmds/app_process/app_main.cpp: int main(int argc, const char* const argv[]) { AppRuntime runtime; // Next arg is startup classname or "--zygote" if (i < argc) { arg = argv[i++]; if (0 == strcmp("--zygote", arg)) { bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false; setArgv0(argv0, "zygote"); set_process_name("zygote"); runtime.start("com.android.internal.os.ZygoteInit", startSystemServer); } } }
runtime.start()で ZygoteInit をコールしていることが分かる. AppRuntime は AndroidRuntime を継承しているので, AndroidRuntime を見ると...
frameworks/base/core/jni/AndroidRuntime.cpp: /* * Start the Android runtime. This involves starting the virtual machine * and calling the "static void main(String[] args)" method in the class * named by "className". */ void AndroidRuntime::start(const char* className, const bool startSystemServer) { startClass = env->FindClass(slashClassName); if (startClass == NULL) { LOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { LOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } } }
JNI でcom.android.internal.os.ZygoteInit#main() をコールしていることが分かる.
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java: /** * Startup class for the zygote process. * * Pre-initializes some classes, and then waits for commands on a UNIX domain * socket. Based on these commands, forks of child processes that inherit * the initial state of the VM. * * Please see {@link ZygoteConnection.Arguments} for documentation on the * client protocol. * * @hide */ public class ZygoteInit { public static void main(String argv[]) { try { // Do an initial gc to clean up after startup gc(); if (argv[1].equals("true")) { startSystemServer(); } } } /** * Prepare the arguments and fork for the system server process. */ private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException { /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003", "--capabilities=130104352,130104352", "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", }; int pid; try { /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, debugFlags, null); } } }
main() -> startSystemServer()ときて, Zygote#forkSystemServer()の中で fork() が呼ばれるよ. これを見ると zygote の UID は 1000 のようです. そうそう, zygote のやりとりにはソケットを使っているみたいよ.
dalvik/libcore/dalvik/src/main/java/dalvik/system/Zygote.java; package dalvik.system; public class Zygote { /** * Special method to start the system server process. In addition to the * common actions performed in forkAndSpecialize, the pid of the child * process is recorded such that the death of the child process will cause * zygote to exit. */ native public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits); /** * Special method to start the system server process. * @deprecated use {@link Zygote#forkSystemServer(int, int, int[], int, int[][])} */ @Deprecated public static int forkSystemServer(int uid, int gid, int[] gids, boolean enableDebugger, int[][] rlimits) { int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0; return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits); }}
ココがちょっぴりわからない. どっちがコールされるの? forkSystemServer()にしても forkAndSpecialize()にしても, fork()がこーるされるんだけどね.
dalvik/vm/native/dalvik_system_Zygote.c: static void Dalvik_dalvik_system_Zygote_forkSystemServer( const u4* args, JValue* pResult) { pid_t pid; pid = forkAndSpecializeCommon(args); RETURN_INT(pid); } static void Dalvik_dalvik_system_Zygote_forkAndSpecialize(const u4* args, JValue* pResult) { pid_t pid; pid = forkAndSpecializeCommon(args); RETURN_INT(pid); } /* * Utility routine to fork zygote and specialize the child process. */ static pid_t forkAndSpecializeCommon(const u4* args) { pid_t pid; dvmDumpLoaderStats("zygote"); pid = fork(); return pid; }
forkSystemServer()なのに Dalvik_dalvik_system_Zygote_forkSystemServer()かとゆーと, これも JNI なんだと思う(ここんところはちょっと自信なし).
dalvik/vm/native/dalvik_system_Zygote.c: const DalvikNativeMethod dvm_dalvik_system_Zygote[] = { { "fork", "()I", Dalvik_dalvik_system_Zygote_fork }, { "forkAndSpecialize", "(II[II[[I)I", Dalvik_dalvik_system_Zygote_forkAndSpecialize }, { "forkSystemServer", "(II[II[[I)I", Dalvik_dalvik_system_Zygote_forkSystemServer }, { NULL, NULL, NULL }, }; dalvik/vm/native/InternalNative.c: /* * Set of classes for which we provide methods. * * The last field, classNameHash, is filled in at startup. */ static DalvikNativeClass gDvmNativeMethodSet[] = { { "Ldalvik/system/Zygote;", dvm_dalvik_system_Zygote, 0 }, }
Your site is great, thank you, I have learned a lot of knowledge. I found you on the http://findata.gov
Hello people) Welcome to my homepage http://ekurtados.br