• Android系统启动流程分析


    Android系统启动流程简单分析

    系统启动的大致流程为:
    当Kernel启动过程会创建init进程。

    init进程会启动servicemanager(binder服务管家), Zygote进程(Java进程的鼻祖).

    Zygote进程会创建 system_server进程以及各种app进程,

    1.先看下init进程怎么去创建zygote进程

    init进程去解析所有的init.*.rc文件

    init.*.rc是一个配置文件里面采用特殊语法

    比如启动zygote进程在这个文件中

    system/core/rootdir/init.zygote64.rc

    service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
        class main
        priority -20
        user root
        group root readproc reserved_disk
        socket zygote stream 660 root system
        socket usap_pool_primary stream 660 root system
        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
        onrestart restart wificond
        writepid /dev/cpuset/foreground/tasks
    

    service表示服务,zygote表示服务名称,不能重复。
    /system/bin/app_precess64是linux的可执行文件。
    编译系统之后生成目录为:

    out/target/product/sailfish/symbols/system/bin/app_process64

    这个app_process64是哪里来的呢?

    其实是安卓系统编译过程中生成的具体看下这个目录:

    frameworks/base/cmds/app_process

    image

    其中Android.mk

    ...
    
    #这个是编译的cpp文件
    app_process_src_files := \
        app_main.cpp \
    ...
    
    LOCAL_MODULE:= app_process
    LOCAL_MULTILIB := both
    LOCAL_MODULE_STEM_32 := app_process32
    LOCAL_MODULE_STEM_64 := app_process64 #生成的名字
    
    ...
    

    所以/system/bin/app_process64运行时走的就是app_main.app,那么它的入口就是app_main.app的main()方法

    简单总结一下就是:
    init进程通过解析*.rc文件,然后去执行一个预先编译好的可执行文件/system/bin/app_process64,
    然后进入zygote的app_main.app的main()方法。

    zygoe的启动过程晚点在分析

    2.zygote进程fork创建system_server进程

    从app_main.main()方法一路向下执行,那么什么时候启动的system_server进程的。

    forkSystemServer()方法中通过linux的fork去创建system_server进程
    fork是怎么个操作呢,
    fork是linux的一个方法,采用copy-on-write(这是什么意思呢,晚点再说好吧)机制,把zygote这个进程拷贝一份,改一下进程的pid,那么就是一个新进程了。

    怎么启动system_server的呢?答案是通过反射,怎么触发的反射先不管,反正最后就是通过反射调用到system_server进程里面去了。

    反射SystemServer类的main()方法,然后执行

    你说反射怎么就定位到SystemServer类了呢,其实是写死的参数,就是上面说的forkSystemServer()方法里面

    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    看下面这个args[]数组,就是通过解析这个数组,拿到类名"com.android.server.SystemServer"
    然后通过类名反射它的class,在去反射调用main()方法

        private static Runnable forkSystemServer(String abiList, String socketName,
                ZygoteServer zygoteServer) {
            ...
            /* 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,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",
            };
            ...
        }
    

    所以到现在三个进程的关系已经说明白了:

    kernel创建init进程,init进程通过linux的可执行文件/system/app/app_process,创建zygote进程,zygote进程再fork出system_server金恒通过写死的参数,反射调用SystemServer类的main()方法。

    system_server进程创建AMS,PMS,WMS等系统服务当AMS准备完毕后去启动Luncher。到这里安卓系统就启动完毕了。

    参考文档

    Android系统启动-zygote篇

  • 相关阅读:
    mysql分组排序取组内第一的数据行
    C#版Nebula客户端编译
    关于nginx
    http状态码
    gitlab
    TCP/IP 3次握手和四次断开
    nps 内网穿透
    用CentOS7做一个简单的路由器
    linux 简单特效
    LVS粗讲
  • 原文地址:https://www.cnblogs.com/cfdroid/p/16337456.html
Copyright © 2020-2023  润新知