您的位置:首页 > 移动开发 > Android开发

浅谈Android系统启动过程

2015-12-08 12:45 453 查看
转载请标明出处:http://blog.csdn.net/EdisonChang/article/details/50217225

本篇文章主要介绍Android启动过程,结合系统源码并参考了《深入理解Android内核设计思想》相关章节,在此对图书作者致敬。

Android是基于Linux内核的简易操作系统,init是Android中第一个启动的进程,init通过init.rc配置的命令陆续启动其他系统服务进程。与我们关系最为密切的,莫过于ServiceManager,Zygote和SystemServer。

ServiceManager 服务管理器

service servicemanager /system/bin/servicemanager

class core

user system

group system

critical

onrestart restart zygote

onrestart restart media

onrestart restart surfaceflinger

onrestart restart drm

ServiceManager是Linux程序,负责管理Android中各项服务,ServiceManager所属class是core,拥有core属性的进程会被同时启动和停止。cirtical选项说明它是系统的关键进程,如果进行在四分钟内异常退出超过四次,设备会重启并进入还原模式。

int ServiceManager::start(const char *name)

int ServiceManager::stop(const char *name)

bool ServiceManager::isRunning(const char *name)


Zygote孵化进程

service zygote /system/bin/app_process -Xzygote /system/bin –zygote

–start-system-server

class main

socket zygote stream 666

onrestart write /sys/android_power/request_state wake

onrestart write /sys/power/state on

onrestart restart media

onrestart restart netd

与ServiceManager类似,Zygote也由init解析脚本启动,Zygote所属的class为mian ,并不是core,它所在程序为app_processs。而且init.rc中在启动时指定了–zygote 和 –start–system-server 命令行参数,

int main(int argc, const char* const argv[])
{
//************
while (i < argc) {
const char* arg = argv[i++];
if (!parentDir) {
parentDir = arg;
} else if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = "zygote";
} 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 = arg + 12;
} else {
className = arg;
break;
}
}

if (niceName && *niceName) {
setArgv0(argv0, niceName);
set_process_name(niceName);
}

runtime.mParentDir = parentDir;

if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer ? "start-system-server" : "");
} else if (className) {
// Remainder of args get passed to startup class main()
runtime.mClassName = className;
runtime.mArgC = argc - i;
runtime.mArgV = argv + i;
runtime.start("com.android.internal.os.RuntimeInit",
application ? "application" : "tool");
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
}


通过frameworks/base/cmds/app_process/app_main.cpp中app_processs的main方法可以看出这个时候就会调用runtime.start方法启动ZygoteInit预装载各种系统类和SystemServer。

Android 的系统服务——SystemServer

SystemServer提供了众多由java编写的各种系统服务,是Android进入Launcher前的最后准备。如果在init.rc中指定启动参数-start-system-server,那么ZygoteInit就会调用startSystemServer方法,ZygoteInit通过forkSystemServer来生成一个新的进程,用于承载各项系统服务。

/**
* 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,1018,3001,3002,3003,3006,3007",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}

/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}

return true;
}


根据fork的特性,子进程和父进程将获得同样的代码环境,其中子进程的pid为0,如上系统源码,这时候就会调用handleSystemServerProcess方法处理各项系统服务 。

private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {

closeServerSocket();

// set umask to 0077 so new files and directories will default to owner-only permissions.
Libcore.os.umask(S_IRWXG | S_IRWXO);

if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}

if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
null, parsedArgs.remainingArgs);
} else {
/*
* Pass the remaining arguments to SystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
}

/* should never reach here */
}


WrapperInit.execApplication处理方法如下,通过–application 命令行启动app_process,调用com.android.internal.os.RuntimeInit 进行相应的初始化操作,

然后调用nativeFinishInit方法回调RuntimeInit 初始化结束状态。

public static void execApplication(String invokeWith, String niceName,
int targetSdkVersion, FileDescriptor pipeFd, String[] args) {
StringBuilder command = new StringBuilder(invokeWith);
command.append(" /system/bin/app_process /system/bin --application");
if (niceName != null) {
command.append(" '--nice-name=").append(niceName).append("'");
}
command.append(" com.android.internal.os.WrapperInit ");
command.append(pipeFd != null ? pipeFd.getInt$() : 0);
command.append(' ');
command.append(targetSdkVersion);
Zygote.appendQuotedShellArgs(command, args);
Zygote.execShell(command.toString());
}


public static final void main(String[] argv) {
if (argv.length == 2 && argv[1].equals("application")) {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application");
redirectLogStreams();
} else {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting tool");
}

commonInit();

/*
* Now that we're running in interpreted code, call back into native code
* to run the system.
*/
nativeFinishInit();

if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");
}


欢迎补充和指正,多谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: