系统启动流程

  • Post author:
  • Post category:其他




简单流程

在这里插入图片描述

  1. 启动电源及系统启动

当电源按下时引导芯片代码开始从预定义的ROM中开始执行。加载引导程序Bootloader至RAM

  1. 引导进程Bootloader

是系统启动前的一个小程序,主要用于将系统的OS拉起来并运行

  1. Linux Kernel进程

内核启动时,设置缓存、被保护存储、计划列表、加载驱动。内核完成系统设置后,在系统文件中寻找init文件,然后启动root进程或系统的第一个进程

  1. init进程(native)

解析init文件孵化出zygote进程(JVM第一个进程,所有进程的父进程)

  1. Zygote进程(framework)

创建虚拟机JVM并为其注册JNI方法,创建服务端socket,启动SystemServer进程

  1. SystemServer进程

用于启动各种服务,AMS,PMS,WWS等

  1. Launcher

AMS启动



具体流程分析

在这里插入图片描述

  • Bootloader引导进程
  • Linux Kernel进程:加载各种驱动和数据结构,寻找系统文件中的init.rc文件,加载用户级别的第一个进程.

    加载init.rc配置文件
int main(int argc, char** argv) {
   
    if (!strcmp(basename(argv[0]), "ueventd")) {
   
        return ueventd_main(argc, argv);
    }

    if (!strcmp(basename(argv[0]), "watchdogd")) {
   
        return watchdogd_main(argc, argv);
    }

    if (argc > 1 && !strcmp(argv[1], "subcontext")) {
   
        InitKernelLogging(argv);
        const BuiltinFunctionMap function_map;
        return SubcontextMain(argc, argv, &function_map);
    }

    if (REBOOT_BOOTLOADER_ON_PANIC) {
   
        InstallRebootSignalHandlers();
    }

    bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);

    if (is_first_stage) {
   
        boot_clock::time_point start_time = boot_clock::now();

        // Clear the umask.
        umask(0);

        clearenv();
        setenv("PATH", _PATH_DEFPATH, 1);
        // Get the basic filesystem setup we need put together in the initramdisk
        // on / and then we'll let the rc file figure out the rest.
        // 创建文件夹,挂载
        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));
        // Don't expose the raw commandline to unprivileged processes.
        chmod("/proc/cmdline", 0440);
        gid_t groups[] = {
    AID_READPROC };
        setgroups(arraysize(groups), groups);
        mount("sysfs", "/sys", "sysfs", 0, NULL);
        mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);

        mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));

        if constexpr (WORLD_WRITABLE_KMSG) {
   
            mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11));
        }

        mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
        mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));

        // Mount staging areas for devices managed by vold
        // See storage config details at http://source.android.com/devices/storage/
        mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
              "mode=0755,uid=0,gid=1000");
        // /mnt/vendor is used to mount vendor-specific partitions that can not be
        // part of the vendor partition, e.g. because they are mounted read-write.
        mkdir("/mnt/vendor", 0755);

        // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
        // talk to the outside world...
        // 打开日志
        InitKernelLogging(argv);
        ...
    }
    ...
    // 加载init.rc文件
    LoadBootScripts(am, sm);
    ...
}
  • init.rc配置文件会进行很多的配置,创建很多的文件夹及文件,之后初始化Android驱动器,继而启动zygote进程
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=unsupported
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary
  • zygote进程会执行app_process可执行文件,在该文件中先添加Android的运行环境。在Android运行中调用了ZygoteInit.java,这就实现了从C++跳转到java代码
int main(int argc, const char* const argv[])
    {
   
        ...
        // Android运行时环境
        AppRuntime runtime;
        ...
        // Next arg is startup classname or "--zygote"
        if (i < argc



版权声明:本文为qq_34787560原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。