现在的位置: 首页 > 综合 > 正文

安卓开机启动流程 Android培训班(17)

2018年02月08日 ⁄ 综合 ⁄ 共 4543字 ⁄ 字号 评论关闭

平台:leadcore l1813

init模块

第一步:Keywords.h (system\core\init) 4127
2014/5/20
    KEYWORD(service,     SECTION, 0, 0)
    KEYWORD(restart,     COMMAND, 1, do_restart)
service关键字是用来设置一段服务的命令,往往一段服务里需要有多个选项组成。
第二步:
Init.rc (system\core\rootdir) 18247
2014/5/20
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
启动zygote服务(实质是app_process)。

第三步
根据关键字索引的项
Init_parser.c (system\core\init) 24943
2014/5/20
    case 's':
        if (!strcmp(s, "eclabel")) return K_seclabel;
        if (!strcmp(s, "ervice")) return K_service;
第四步
根据索引
Init_parser.c (system\core\init) 24943
2014/5/20
void parse_new_section(struct parse_state *state, int kw,
                       int nargs, char **args)
...
    case K_service:
        state->context = parse_service(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_service;
            return;
        }
        break;
...
第五步
往该表中添加需要添加的服务
static void *parse_service(struct parse_state *state, int nargs, char **args)
...
    list_add_tail(&service_list, &svc->slist);

第六步:zygote实际运行的是什么?
App_main.cpp (frameworks\base\cmds\app_process)
5397 2014/5/20
    AppRuntime runtime;
...
runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
...

第七部:探索AppRuntime 
App_main.cpp (frameworks\base\cmds\app_process)
5397 2014/5/20
继承自AndroidRuntime
重载了onZygoteInit、onStarted、onVmCreated,但前文的start调用的显然是父类的AndroidRuntime

第八步:探索AndroidRuntime
AndroidRuntime.cpp (frameworks\base\core\jni)
43378 2014/5/20
加载环境变量
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
...
        setenv("ANDROID_ROOT", rootDir, 1);
    }
启动虚拟机
    /* start the virtual machine */
    JNIEnv* env;
    if (startVm(&mJavaVM, &env) != 0) {
        return;
    } 
注册android函数
     /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
第九步:启动虚拟机,实际上做的哪些操作?
设置该虚拟机的初始内存以及内存大小等
    property_get("dalvik.vm.heapstartsize", heapstartsizeOptsBuf+4, "4m");
    property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
    关于堆栈的见参考《关于build.prop原始Dalvik虚拟机设定与调整.html》
    /*
     * Initialize the VM.
     *
     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     * If this call succeeds, the VM is ready, and we can start issuing
     * JNI calls.
     */
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        goto bail;
    }
第十步:startReg注册了那些函数?
static const RegJNIRec gRegJNI[] = {

以此了解了native世界与java世界如何沟通起来了。

第十一步:初探zygoteInit
ZygoteInit.java (frameworks\base\core\java\com\android\internal\os)
27424 2014/5/20
main函数:
注册Socket通讯
registerZygoteSocket();
重新导入资源与类
static void preload(){
        preloadClasses();
        preloadResources();
}
清理一下垃圾与资源
gc();
亮点出现了,启动系统服务
startSystemServer();
关闭Socket通讯
closeServerSocket();
详细的工作参考《Zygote工作流程分析》

第十二步:startSystemServer启动的是什么?启动的是系统服务systemServer,调用的是2014/5/20ZygoteConnection,后面去深入了解这个。
ZygoteInit.java (frameworks\base\core\java\com\android\internal\os)
27424
            parsedArgs = new ZygoteConnection.Arguments(args);
...
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
ps:fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

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

第十三步:通过handleSystemServerProcess了解systemServer执行了哪些历史使命?
ZygoteInit.java (frameworks\base\core\java\com\android\internal\os)
27424 2014/5/20
        closeServerSocket(); //与父亲zygote断开联系
Process.setArgV0(parsedArgs.niceName);
//另起炉灶,重新命名
execApplication()/zygoteInit()
if (ZYGOTE_FORK_MODE) {

runForkMode();
} else {
                runSelectLoopMode(); //system server自己干的事情增殖
}

第十四步:分析runSelectLoopMode
ZygoteConnection.java (frameworks\base\core\java\com\android\internal\os)
41516 2014/5/20
fork新的进程是如何做的:
        while (true) {
            ZygoteConnection peer = acceptCommandPeer();
...
                peer.run();
}

第十六步 关于两种创建方式
RuntimeInit.java (frameworks\base\core\java\com\android\internal\os)
14434 2014/5/20
可见创建的方式有两种:
//通过系统调用执行进程:execApplication
//通过寻找到相应目标类的main()函数并执行:
zygoteInit
            if (parsedArgs.invokeWith != null) {
                WrapperInit.execApplication(parsedArgs.invokeWith,
                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
                        pipeFd, parsedArgs.remainingArgs);
            } else {
                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                        parsedArgs.remainingArgs);
            }
实际上是什么呢?两种创建模式
execApplication:
        Zygote.execShell(command.toString());
zygoteInit:
    |--> applicationInit(targetSdkVersion, argv);
|-->invokeStaticMain(args.startClass, args.startArgs);

其实十四,十五都是了解增殖模式的。

第十六步:zygote自己干的事情有哪些呢?

后续待了解。

参考网页:

Zygote工作流程分析

http://www.cnblogs.com/bastard/archive/2012/09/03

 

Android培训班(17)

http://blog.csdn.net/caimouse/article/details/5770059/2668579.html

关于build.prop原始Dalvik虚拟机设定与调整

http://www.360doc.com/content/12/1225/14/44521_256171611.shtml

抱歉!评论已关闭.