当先锋百科网

首页 1 2 3 4 5 6 7

Android系统启动

基于aosp/android11-release

可以先查看图片:4.1 系统启动
或者下图:
在这里插入图片描述在这里插入图片描述

Loader:Boot Rom、Boot Loader


  Boot Rom:Android设备上电后,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。(由“芯片厂商”负责设计和实现)
  Boot Loader:Bootloader 开始执行,首先负责完成硬件的初始化,然后找到Linux内核代码,并加载到内存。
引导程序是在Android操作系统开始运行前的一个小程序。它不是Android操作系统的一部分。引导程序是 OEM 厂商或者运营商加锁和限制的地方。(由“设备厂商”负责设计和实现)

    相关资料如下:bootloader

Linux Kernel


Linux 内核开始启动,初始化各种软硬件环境,加载驱动程序,挂载根文件系统,并执行init程序,由此开启Android的世界。

  严格来说,Android系统实际上是运行于Linux内核上的一系列 “服务进程”,并不算一个完整意义上的“操作系统”。Android系统以及各大Linux的发行版,他们的Linux内核部分启动过程都是差不多。Android最后都是start_kernel初始化函数(system/core/init/main.cpp)

Native C/C++Library :主要解析 init.rc 文件


init 进程决定了系统在启动过程中,究竟会启动哪些守护进程和服务,以及呈现出怎样的一个用户UI界面。

这里不过多介绍其他,相关代码:(基于aosp/android11-release

  • system/core/init/main.cpp
  • system/core/init/first_stage_init.cpp
  • system/core/init/init.cpp中SecondStageMain,最终在LoadBootScripts解析rc文件
    在这里插入图片描述
    rc相关语法Android Init Language: system\core\init\README.md

init

init 进程会执行 app_process 程序,创建 Zygote 进程,它是Android系统最重要的进程,所有后续的Android应用程序都是由它 fork 出来的。
在这里插入图片描述
init 触发进程和服务:
在这里插入图片描述
触发器的执行顺序为on early-init -> init -> late-init

Zygote

init.rc中import /system/etc/init/hw/init.${ro.zygote}.rc,ro.zygote属性配置。
这里查看64位的 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 exec_background - system system -- /system/bin/vdc volume abort_fuse
    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,以 service 开头,由 init 进程启动,一般运行在 init 的一个子进程,每一个service在启动时会通过fork方式生成子进程。这个 rc 文件其中 service 用于通知 init 进程创建名 zygote 的进程,这个 zygote 进程执行程序的路径为 /system/bin/app_process64,后面的则是要传给 app_process64 的参数。class main指的是zygote的class name为main。


init 触发启动 service:Start方法中调用 fork() 创建子进程,调用 ExpandArgsAndExecv 通过最终调用 execv 执行system/bin/app_process,这样就会进入frameworks/base/cmds/app_process/app_main.cpp的main函数。

Result<void> Service::Start() {
    // ... ... ... ...
    pid_t pid = -1;
    if (namespaces_.flags) {
        pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);
    } else {
        pid = fork();
    }

    if (pid == 0) {
        umask(077);
        // ... ... ... ...
        for (const auto& [key, value] : environment_vars_) {
            setenv(key.c_str(), value.c_str(), 1);
        }

        for (const auto& descriptor : descriptors) {
            descriptor.Publish();
        }
        // ... ... ... ...
        if (!ExpandArgsAndExecv(args_, sigstop_)) {
            PLOG(ERROR) << "cannot execv('" << args_[0]
                        << "'). See the 'Debugging init' section of init's README.md for tips";
        }

        _exit(127);
    }
    // ... ... ... ...
}

在这里插入图片描述

frameworks/base/cmds/app_process/app_main.cpp
frameworks/base/core/jni/AndroidRuntime.cpp

int main(int argc, char* const argv[])
{
    // ... ... 传到的参数argv为“-Xzygote /system/bin --zygote --start-system-server” ... ...
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // ... ... ... ...
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}
runtime.start 来启动 zygote

Java API Framework


启动 SystemServer

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

    public static void main(String argv[]) {
        // ... ... ... ...
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }
        // ... ... ... ...
    }
// ... ... ... ...
   /**
     * Prepare the arguments and forks for the system server process.
     *
     * @return A {@code Runnable} that provides an entrypoint into system_server code in the child
     * process; {@code null} in the parent.
     */
    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,3011",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                "com.android.server.SystemServer",
        };
            // ... ... ... ...
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }

forkSystemServer 开启线程,执行 Zygote.forkSystemServer fork子进程,用于运行system_server;handleSystemServerProcess 完成system_server进程剩余的工作

反射调用到com.android.server.SystemServer

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
frameworks/base/core/services/java/com/android/server/SystemServer.java
Zygote最终调用 RuntimeInit.applicationInit 中 findStaticMain 方法反射调用调用到cl.getMethod("main", new Class[] { String[].class });

    public static void main(String[] args) {
        new SystemServer().run();
    }

启动服务和Launcher


frameworks/base/core/services/java/com/android/server/SystemServer.java
在这里插入图片描述
Launcher启动:待续~~
frameworks\base\services\java\com\android\server\SystemServer.java
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java
frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java
frameworks\base\services\core\java\com\android\server\wm\ActivityStartController.java
frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java
SystemServer 执行 startOtherServices 启动服务时,最后会调用 mActivityManagerService.systemReady。AMS.systemReady -> ActivityTaskManagerService.java 中 startHomeOnAllDisplays -> mRootWindowContainer.startHomeOnAllDisplays -> startHomeOnDisplay -> startHomeOnTaskDisplayArea -> ATMS中getHomeIntent获取intent,mService.getActivityStartController().startHomeActivity

   public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
        // ... ... ... ...
        Slog.i(TAG, "System now ready");
        // ... ... ... ...
        synchronized (this) {
            // ... ... ... ...
            // Start up initial activity.
            mBooting = true;
            // ... ... ... ...
            if (bootingSystemUser) {
                t.traceBegin("startHomeOnAllDisplays");
                mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
                t.traceEnd();
            }
            // ... ... ... ...
        }
    }

在这里插入图片描述
在这里插入图片描述

感谢并推荐:Android内核开发


Android内核开发:开发板选购
Android内核开发:理解和掌握repo工具
Android内核开发:源码的版本与分支详解
Android内核开发:系统编译输出的镜像文件
Android内核开发:系统分区与镜像文件的烧写
Android内核开发:图解Android系统的启动过程
Android内核开发:如何统计系统的启动时间
Android内核开发:学会分析系统的启动log
Android内核开发:系统启动速度优化