Android启动过程,SystemServer启动过程分析

本文详细解析了Android系统从Init.rc脚本开始,如何通过一系列复杂过程最终启动SystemServer,揭示了zygote进程与system_server进程之间的关联。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文旨在记录所看所学,以备以后查询。

由Init.rc到SystemServer启动

首先来分析Init.rc,这个特殊的脚本文件位于手机的根目录,它由init进程读取,来执行系统的初始化工作。打开它我们会看到import /init.${ro.zygote}.rc,表示根据手机platform类型引入对应的脚本,这里我们
分析init.zygote64_32.rc。
第一行这样写:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
这里只是声明了这个服务,相当于只是声明了函数,在哪里调用的呢,经过搜索关键字不难发现:
on late-init -》trigger zygote-start -》on zygote-start -》start zygote。

下面分析怎么启动SystemServer,很明显是执行了/system/bin/app_process64程序,那么这个程序位于什么地方呢?搜索mk文件中的关键字app_process64,发现位于android/frameworks/base/cmds/app_process/Android.mk,那么很显然app_process目录就是app_process64的源码目录。
下面分析cmds/app_process/app_main.cpp。

    //这里读取参数后设置flag,根据前面rc文件传入的参数,不难发现如下结果
    //zygote = true startSystemServer = true application = false;
while (i < argc) {
	const char* arg = argv[i++];
	if (strcmp(arg, "--zygote") == 0) {
	    zygote = true;
	    niceName = ZYGOTE_NICE_NAME;
	} else if (strcmp(arg, "--start-system-server") == 0) {
	    startSystemServer = true;
	} else if (strcmp(arg, "--application") == 0) {
	    application = true;
	} else if (strncmp(arg, "--nice-name=", 12) == 0) {
	    niceName.setTo(arg + 12);
	} else if (strncmp(arg, "--", 2) != 0) {
	    className.setTo(arg);
	    break;
	} else {
	    --i;
	    break;
	}
}
    ...
    //这里是main方法的尾部,能看得出来最终启动了com.android.internal.os.ZygoteInit,
    //通过AndroidRuntime启动,这里就不再赘述
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    }

下面分析com.android.internal.os.ZygoteInit类,通过上面的分析,可以猜测–start-system-server参数用于标记是否启动SystemServer,那么在main方法中搜索就不难找到关键。

for (int i = 1; i < argv.length; i++) {
    if ("start-system-server".equals(argv[i])) {
        startSystemServer = true;
    } else if ("--enable-lazy-preload".equals(argv[i])) {
        enableLazyPreload = true;
    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
        abiList = argv[i].substring(ABI_LIST_ARG.length());
    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
    } else {
        throw new RuntimeException("Unknown command line argument: " + argv[i]);
    }
}
...
if (startSystemServer) {
	//这里通过forkSystemServer来启动SystemServer
    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

    // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
    // child (system_server) process.
    if (r != null) {
    	//事实上这里会因为SystemServer的looper操作而进入死循环
        r.run();
        return;
    }
}
private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
            ...
      //通过fork来创建SystemServer进程
      pid = Zygote.forkSystemServer(
      parsedArgs.uid, parsedArgs.gid,
      parsedArgs.gids,
      parsedArgs.runtimeFlags,
      ...
        /* For child process */
      //fork 返回0表示位于子进程,返回-1表示错误,返回大于0的数表示位于父进程,并且子进程进程号为
      //返回值。
      if (pid == 0) {
          if (hasSecondZygote(abiList)) {
              waitForSecondaryZygote(socketName);
          }

          zygoteServer.closeServerSocket();
          //这里是需要重点关注的地方。
          return handleSystemServerProcess(parsedArgs);
      }
      return null;
}
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
...
	//最终这样返回Runnable,继续往下分析
    return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
	//最终这样返回Runnable,继续往下分析
	return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
	...
	//这里可以看到通过调用args.startClass的main方法来返回一个Runnable对象
    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}
//这里需要回去找到args.startClass
//一步步回溯就不难找到如下代码
String args[] = {
    "--setuid=1000",
    "--setgid=1000",
    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
    "--capabilities=" + capabilities + "," + capabilities,
    "--nice-name=system_server",
    "--runtime-args",
    "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
    "com.android.server.SystemServer",
};
//这里指定了com.android.server.SystemServer作为启动class

通过ps命令不难验证,system_server进程的父进程就是zygote64(这取决于手机是64位平台,还是32位)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值