2012年3月16日金曜日

app_process

_ 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 },

0 件のコメント:

コメントを投稿