版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/michael_yt/article/details/78603600
本篇博客基于 android7.1 主要介绍android启动流程中,从init开始到启动SystemServer结束为止,整个流程中各个方法里面主要做了哪些初始化操作,以便于对整个系统的启动有一定的了解。
整体介绍图
注 图片来源于http://blog.csdn.net/dd864140130/article/details/57624948
整体流程图
流程中各部分的实现细节
基于Linux内核的android系统,在内核初始化完成后将创建第一个用户进程Init,实现了内核空间到用户空间的转变
init.cpp
int main(int argc, char** argv) {
if (is_first_stage) {
//挂载基本的四类文件系统,tmpfs、devpts、proc、sysfs
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
mount("sysfs", "/sys", "sysfs", 0, NULL);
}
......省略部分代码
open_devnull_stdio();//将标准输入输出,错误输出重定向到/dev/_null_设备中
klog_init(); //初始化内核log系统
property_init(); //初始化属性服务
// If arguments are passed both on the command line and in DT,
// properties set in DT always have priority over the command-line ones.
process_kernel_dt();
process_kernel_cmdline();
selinux_initialize(is_first_stage); //初始化selinux
parser.ParseConfig("/init.rc"); //解析并执行init.rc文件
am.QueueEventTrigger("early-init"); //执行init.rc中的early-init action
am.QueueEventTrigger("init"); //执行init.rc中的init action
am.QueueEventTrigger("late-init"); //执行init.rc中的late-init
......省略部分代码
restart_processes();//启动ServiceManager
return 0;
}
init.rc
import <path> //用来引入一个要解析的其他配置文件,通常用于当前配置文件的扩展,在当前文件解析完成后再解析
on <trgger> [&& <trigger>]* //trgger触发器,事件触发:通过trigger”命令或QueueEventTrigger()触发、属性触发:指定属性的变量值变成指定值时触发,其格式为property:<name>=*
<command> //Commands代表一组命令,在为Action设置了触发器后,就需要为其定义一组命令(command)了
...
service <name> <pathname> [ <argument> ]* //Service:是一些在系统初始化时就启动或者退出时需要重启的程序、name:service名字、patchname:执行程序路径、argument:给执行程序的配置参数
<option> //option用来修饰服务,决定了服务在什么时候运行以及怎样运行
...
//例子
import /init.${ro.zygote}.rc //引入了zygote
on early-init
# Set init and its forked children's oom_adj.
write /proc/1/oom_score_adj -1000
# Disable sysrq from keyboard
write /proc/sys/kernel/sysrq 0
service healthd /sbin/healthd
class core
critical
seclabel u:r:healthd:s0
group root system wakelock
以上具体的command和option的含义请参考system/core/init/readme.txt中的官方解释
init.zygote64.rc
在init.rc中,Zygote进程被启动.Zygote进程是其他所有进程的孵化器.init.rc通过include引入init.zygote.rc,这里以init.zygote64.rc为例:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server //创建一个名为zygote的进程服务,它的执行程序路径为/system/bin/app_process64,后面的是它的参数,启动zygote和启动systemserver
class main //为当前service设定一个类别.相同类别的服务将会同时启动或者停止,默认类名是default.
socket zygote stream 660 root system // 创建一个名为zygote的socket,,该socket用来实现进程间的通信,当新启动一个应用时,ActivityManagerService想向该Socket发起请求,请求zygote进程fork出一个新的进程.
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver // 当服务重启时执行该命令
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
writepid /dev/cpuset/foreground/tasks // 当fork一个子进程时,写子进程的pid到一个给定的文件。是给cgroup/cpuset使用
通过上面init.rc中关于zygote的AIL语言分析,我们可以知道接下来它会执行/system/bin/app_process,
位于/frameworks/base/cmds/app_process/app_main.cpp,其入口函数是main():
app_main.cpp
int main(int argc, char* const argv[])
{
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); //创建AppRuntime
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true; //根据init.zygote64.rc中的配置设置启动zygote
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true; //根据init.zygote64.rc中的配置设置启动SystemServer
......省略部分代码
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);// 通过AppRuntime启动ZygoteInit
.......省略部分代码
因为AppRuntime继承自AndroidRuntime,所以最终调用的是AndroidRuntime中的start方法
AppRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL); //创建JniInvocation并执行Init方法,通过读取persist.sys.dalvik.vm.lib.2 这个属性值来判断是创建Dalvik还是ART虚拟机,libart.so ART、libdvm.so Dalvik
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) { //启动虚拟机
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
if (startReg(env) < 0) { //注册JNI方法
ALOGE("Unable to register all android natives\n");
return;
}
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V"); //通过JNI启动ZygoteInit.main方法
..........省略部分代码
通过上面的代码流程和系统参数的初始化,我们来到了ZygoteInit.java 的main方法
ZygoteInit.java
public static void main(String argv[]) {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start(); //开始解析并初始化zygote
registerZygoteSocket(socketName); //创建Socket,它将作为服务端用来和作为客户端的ActivityManagerService进行通信
preload();//预加载framework和众多App所需要的通用资源,Classes、Resources、OpenGL、SharedLibraries、TextResources等等
if (startSystemServer) {
startSystemServer(abiList, socketName); //通过startSystemServer()方法来启动SystemServer
}
Log.i(TAG, "Accepting command socket connections");
runSelectLoop(abiList);//使刚才创建的Socket进入无限循环,以等待来自ActivityManagerService请求
......省略部分代码
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
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); //创建SystemServer,与其相似还有forkAndSpecialize(),用于创建一个普通应用进程
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {//创建成功返回0
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket(); //因为是通过zygote创建的但是SystemServer不需要socket所以将其关闭
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);//执行dex2oat
}
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);//通过这个方法进一步启动SystemServer组件
......省略部分代码
RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {
commonInit();//为当前进程的VM设置未捕获异常处理器
nativeZygoteInit();//Binder驱动初始化,该方法完成后,就可以通过该Binder进行进程通信
applicationInit(targetSdkVersion, argv, classLoader); //主要用调用com.android.server.SystemServer类的main()方法
通过RuntimeInit类的出来我们就来到了SystemServer
SystemServer.java
private void run() {
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);//如果系统时间早于1970则修改为1970
}
SystemProperties.set("persist.sys.locale", languageTag);//设置系统默认语言是在AndroidRuntime获取的
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());//设置虚拟机
Looper.prepareMainLooper();//初始化一个当前线程的looper
System.loadLibrary("android_servers");//初始化native_service
createSystemContext();//创建system上下文
mSystemServiceManager = new SystemServiceManager(mSystemContext);创建manager
startBootstrapServices();//启动引导服务,比如AMS,PMS等
startCoreServices(); //启动核心服务,比如BatteryService等
startOtherServices(); //启动其他服务,比如NetworkStatsService等.
Looper.loop(); //启动消息循环
参考 http://blog.csdn.net/dd864140130/article/details/57624948