android启动--深入理解zygote
2012-06-13 15:51
483 查看
http://www.2cto.com/kf/201203/123062.html
前一篇http://www.2cto.com/kf/201203/123061.html文章介绍了init进程的启动过程,其中就有解析init.rc脚本,而根据其内容配置启动了很多重要的服务:Servicemanager和zygote进程就奠定了Android的基础,建立了真正的android空间。
进程名称 进程路径
zygote /system/bin/app_process
servicemanager /system/bin/servicemanager
bootanim /system/bin/bootanimation
media /system/bin/mediaserver
...
这里还都是在native世界中,此层分析哪个service没有启动,则找到相关的进程加打印即可,比较好分析,成功启动的进程利用ps命令即可查看。
说明一下android中的两个不同世界:
JAVA世界:运行基于 dalvik
虚拟机的 JAVA 程序
NATIVE世界:利用 C或C++开发的程序组成native世界。
下面开始分析 zygote 启动流程:
代码路径:frameworks\base\cmds\app_process
启动参数:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
int main(int argc, const char* const argv[])
{
// These are global variables in ProcessState.cpp
mArgC = argc;
mArgV = argv;
// Next arg is startup classname or "--zygote"
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) { // init.rc 中的参数值
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote"); // 利用prctl修改进程名称
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer); // 这就是真正的重点!!!!
}
....
}
下面开始建立 AndroidRuntime :
路径:frameworks\base\core\jni
class AppRuntime : public AndroidRuntime
AppRuntime 重载实现了 onStarted() , onZygoteInit(), onExit() 函数
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);
--> 调用
/*
* 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)
{
// 基本上再次看到这句话,说明系统重启了
LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");
// 1、启动 虚拟机
/* start the virtual machine */
if (startVm(&mJavaVM, &env) != 0)
goto bail;
// 2、注册 jni 函数
/*
* Register android functions.
*/
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
goto bail;
}
/*
3、从 com.android.internal.os.ZygoteInit 类中找到main函数,即调用
ZygoteInit.java类中的main, 此时将进入到 java 世界。。。。
*/
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
欢迎来到 JAVA 世界。。。。。
下面直接分析 ZygoteInit 类中的 main 函数:
路径: frameworks\base\core\java\com\android\internal\os
public static void main(String argv[]) {
//1 、建立端口号为 50 的监听套接字,用于接收
// ActivityManangerService 的请求,Fork应用程序
registerZygoteSocket();
// 2、预加载类和资源,优化代码时这里可以想点办法,不过有点麻烦
preloadClasses();
// 3、垃圾回收
gc();
// 4、启动 SystemServer ,这个下面再重点讲解
startSystemServer();
// 5、处理客户连接与请求,具体由 ZygoteConnection.runOnce()处理
runSelectLoopMode();
...
}
SystemServer 的分析:
这个进程是由 zygote 产生的第一个进程
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer()
{
...
/* 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", // process name
"com.android.server.SystemServer", // class name
};
// 解析参数
parsedArgs = new ZygoteConnection.Arguments(args);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null);
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs); // 后面讲述
}
}
-->
forkSystemServer 这是一个jni 函数,调用:
\dalvik\vm\native\dalvik_system_Zygote.c 下面
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_t pid;
// 根据参数fork 出一个子进程,若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
pid = forkAndSpecializeCommon(args);
if(pid > 0) {
gDvm.systemServerPid = pid;
/* There is a slight window that the system server process has crashed
* but it went unnoticed because we haven't published its pid yet. So
* we recheck here just to make sure that all is well.
*/
if (waitpid(pid, &status, WNOHANG) == pid) {
LOGE("System server process %d has died. Restarting Zygote!", pid);
kill(getpid(), SIGKILL);
}
/*
这里表示SystemServer进程退出,而其父进程是Zygote,所以这里 kill掉的就是Zygote进程,即两者都退出了。。。。
*/
}
}
Zygote 与 SystemServer 关系非常紧密,这里有个小处理逻辑:
static pid_t forkAndSpecializeCommon(const u4* args)
{
setSignalHandler();
}
-->
static void setSignalHandler()
{
int err;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sigchldHandler; // 在此安装了一个信号处理函数
err = sigaction (SIGCHLD, &sa, NULL);
...
}
信号处理函数:
/*
* This signal handler is for zygote mode, since the zygote
* must reap its children
*/
static void sigchldHandler(int s)
{
pid_t pid;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
/*
* If the just-crashed process is the system_server, bring down zygote
* so that it is restarted by init and system server will be restarted
* from there.
*/
if (pid == gDvm.systemServerPid) {
LOG(LOG_INFO, ZYGOTE_LOG_TAG,
"Exit zygote because system server (%d) has terminated\n",
(int) pid);
kill(getpid(), SIGKILL);
}
}
...
}
Zygote 启动流程内容太多,下一篇从handleSystemServerProcess 处理流程讲解
使用 Zygote.forkSystemServer 利用 fork 生成 SystemServer进程,那个这个进程到底干了哪些事情呢?
下面从 handleSystemServerProcess 处理流程开始讲解
代码片段如下:
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null);
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
-->
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
{
// 关闭哪些从 Zygote 继承来的 socket
closeServerSocket();
// 这里调用到 zygoteInit函数
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
}
RuntimeInit.java @ frameworks\base\core\java\com\android\internal\os
public static final void zygoteInit(String[] argv){
// 这里调用到 JNI 函数中去了
zygoteInitNative();
// 调用到startClass com.android.server.SystemServer 的main函数
invokeStaticMain(startClass, startArgs);
}
-->
zygoteInitNative @ frameworks\base\core\jni
调用到 onZygoteInit @frameworks\base\cmds\app_process\app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
if (proc->supportsProcesses()) {
LOGV("App process: starting thread pool.\n");
proc->startThreadPool(); // 启动线程,建立 binder 通讯
}
}
ok, 这个流程清楚了,下面我们重点看看 native system_server进程如何启动?
Main @ frameworks\base\services\java\com\android\server\SystemServer.java
public static void main(String[] args) {
System.loadLibrary("android_servers");
init1(args);
}
这里 init1 是个 native 函数:
system_init @ frameworks\base\cmds\system_server\library\system_init.cpp
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
runtime->callStatic("com/android/server/SystemServer", "init2");
...
}
这里又调用到
init2 @ frameworks\base\services\java\com\android\server\SystemServer.java
public static final void init2() {
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
这里启动了一个 ServerThread 线程并调用其start() 函数,其实也就是调用
ServerThread 线程的 run() 函数
public void run() {
Slog.i(TAG, "Entropy Service");
ServiceManager.addService("entropy", new EntropyService());
Slog.i(TAG, "Power Manager");
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
...
// 最后进入到 loop 消息循环中处理消息了。。。。
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
Oh , 原来就是在就里将很多重要的系统服务依次加入到ServiecManager中,至此整个 SystemServer 进程启动完成。
总结一下,重要执行过程如下:
前一篇http://www.2cto.com/kf/201203/123061.html文章介绍了init进程的启动过程,其中就有解析init.rc脚本,而根据其内容配置启动了很多重要的服务:Servicemanager和zygote进程就奠定了Android的基础,建立了真正的android空间。
进程名称 进程路径
zygote /system/bin/app_process
servicemanager /system/bin/servicemanager
bootanim /system/bin/bootanimation
media /system/bin/mediaserver
...
这里还都是在native世界中,此层分析哪个service没有启动,则找到相关的进程加打印即可,比较好分析,成功启动的进程利用ps命令即可查看。
说明一下android中的两个不同世界:
JAVA世界:运行基于 dalvik
虚拟机的 JAVA 程序
NATIVE世界:利用 C或C++开发的程序组成native世界。
下面开始分析 zygote 启动流程:
代码路径:frameworks\base\cmds\app_process
启动参数:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
int main(int argc, const char* const argv[])
{
// These are global variables in ProcessState.cpp
mArgC = argc;
mArgV = argv;
// Next arg is startup classname or "--zygote"
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) { // init.rc 中的参数值
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote"); // 利用prctl修改进程名称
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer); // 这就是真正的重点!!!!
}
....
}
下面开始建立 AndroidRuntime :
路径:frameworks\base\core\jni
class AppRuntime : public AndroidRuntime
AppRuntime 重载实现了 onStarted() , onZygoteInit(), onExit() 函数
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);
--> 调用
/*
* 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)
{
// 基本上再次看到这句话,说明系统重启了
LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");
// 1、启动 虚拟机
/* start the virtual machine */
if (startVm(&mJavaVM, &env) != 0)
goto bail;
// 2、注册 jni 函数
/*
* Register android functions.
*/
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
goto bail;
}
/*
3、从 com.android.internal.os.ZygoteInit 类中找到main函数,即调用
ZygoteInit.java类中的main, 此时将进入到 java 世界。。。。
*/
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
欢迎来到 JAVA 世界。。。。。
下面直接分析 ZygoteInit 类中的 main 函数:
路径: frameworks\base\core\java\com\android\internal\os
public static void main(String argv[]) {
//1 、建立端口号为 50 的监听套接字,用于接收
// ActivityManangerService 的请求,Fork应用程序
registerZygoteSocket();
// 2、预加载类和资源,优化代码时这里可以想点办法,不过有点麻烦
preloadClasses();
// 3、垃圾回收
gc();
// 4、启动 SystemServer ,这个下面再重点讲解
startSystemServer();
// 5、处理客户连接与请求,具体由 ZygoteConnection.runOnce()处理
runSelectLoopMode();
...
}
SystemServer 的分析:
这个进程是由 zygote 产生的第一个进程
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer()
{
...
/* 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", // process name
"com.android.server.SystemServer", // class name
};
// 解析参数
parsedArgs = new ZygoteConnection.Arguments(args);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null);
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs); // 后面讲述
}
}
-->
forkSystemServer 这是一个jni 函数,调用:
\dalvik\vm\native\dalvik_system_Zygote.c 下面
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_t pid;
// 根据参数fork 出一个子进程,若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
pid = forkAndSpecializeCommon(args);
if(pid > 0) {
gDvm.systemServerPid = pid;
/* There is a slight window that the system server process has crashed
* but it went unnoticed because we haven't published its pid yet. So
* we recheck here just to make sure that all is well.
*/
if (waitpid(pid, &status, WNOHANG) == pid) {
LOGE("System server process %d has died. Restarting Zygote!", pid);
kill(getpid(), SIGKILL);
}
/*
这里表示SystemServer进程退出,而其父进程是Zygote,所以这里 kill掉的就是Zygote进程,即两者都退出了。。。。
*/
}
}
Zygote 与 SystemServer 关系非常紧密,这里有个小处理逻辑:
static pid_t forkAndSpecializeCommon(const u4* args)
{
setSignalHandler();
}
-->
static void setSignalHandler()
{
int err;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sigchldHandler; // 在此安装了一个信号处理函数
err = sigaction (SIGCHLD, &sa, NULL);
...
}
信号处理函数:
/*
* This signal handler is for zygote mode, since the zygote
* must reap its children
*/
static void sigchldHandler(int s)
{
pid_t pid;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
/*
* If the just-crashed process is the system_server, bring down zygote
* so that it is restarted by init and system server will be restarted
* from there.
*/
if (pid == gDvm.systemServerPid) {
LOG(LOG_INFO, ZYGOTE_LOG_TAG,
"Exit zygote because system server (%d) has terminated\n",
(int) pid);
kill(getpid(), SIGKILL);
}
}
...
}
Zygote 启动流程内容太多,下一篇从handleSystemServerProcess 处理流程讲解
使用 Zygote.forkSystemServer 利用 fork 生成 SystemServer进程,那个这个进程到底干了哪些事情呢?
下面从 handleSystemServerProcess 处理流程开始讲解
代码片段如下:
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null);
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
-->
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
{
// 关闭哪些从 Zygote 继承来的 socket
closeServerSocket();
// 这里调用到 zygoteInit函数
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
}
RuntimeInit.java @ frameworks\base\core\java\com\android\internal\os
public static final void zygoteInit(String[] argv){
// 这里调用到 JNI 函数中去了
zygoteInitNative();
// 调用到startClass com.android.server.SystemServer 的main函数
invokeStaticMain(startClass, startArgs);
}
-->
zygoteInitNative @ frameworks\base\core\jni
调用到 onZygoteInit @frameworks\base\cmds\app_process\app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
if (proc->supportsProcesses()) {
LOGV("App process: starting thread pool.\n");
proc->startThreadPool(); // 启动线程,建立 binder 通讯
}
}
ok, 这个流程清楚了,下面我们重点看看 native system_server进程如何启动?
Main @ frameworks\base\services\java\com\android\server\SystemServer.java
public static void main(String[] args) {
System.loadLibrary("android_servers");
init1(args);
}
这里 init1 是个 native 函数:
system_init @ frameworks\base\cmds\system_server\library\system_init.cpp
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
runtime->callStatic("com/android/server/SystemServer", "init2");
...
}
这里又调用到
init2 @ frameworks\base\services\java\com\android\server\SystemServer.java
public static final void init2() {
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
这里启动了一个 ServerThread 线程并调用其start() 函数,其实也就是调用
ServerThread 线程的 run() 函数
public void run() {
Slog.i(TAG, "Entropy Service");
ServiceManager.addService("entropy", new EntropyService());
Slog.i(TAG, "Power Manager");
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
...
// 最后进入到 loop 消息循环中处理消息了。。。。
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
Oh , 原来就是在就里将很多重要的系统服务依次加入到ServiecManager中,至此整个 SystemServer 进程启动完成。
总结一下,重要执行过程如下:
相关文章推荐
- android启动--深入理解zygote
- android启动--深入理解zygote (II)
- android启动--深入理解zygote
- android启动--深入理解zygote (II)
- 完全理解android Activity启动模式LauchMode (深入Activity与任务栈)
- [笔记]Android系统进程Zygote启动过程的理解
- Zygote (深入理解android 卷1)
- 深入理解Android(06)——Java世界的入口ZygoteInit
- android启动--深入理解启动HOME
- 深入理解Android(08)——深入理解zygote的分裂原理
- 深入理解Android之init与zygote
- 深入理解Android启动过程
- Android 基础功 - activity启动模式深入理解分析
- AMS—启动一个Activity(基于深入理解Android)
- [深入理解Android卷一全文-第四章]深入理解zygote
- [深入理解Android卷一全文-第四章]深入理解zygote
- 深入理解Dalvik虚拟机- Android进程启动过程
- 深入理解 Android 卷I - 第4章 深入理解 Zygote
- 深入理解 Android 卷I - 第4章 深入理解 Zygote
- 启动AudioFlinger学习笔记----深入理解Android