Android系统启动流程 源码解析

Android系统启动流程

本文链接:https://blog.csdn.net/feather_wch/article/details/132518105

有道云脑图:https://note.youdao.com/s/GZ9d8vzO

1、整体流程

  1. Boot Room
  2. BootLoader
  3. idle
    1. kthread
    2. init
  4. init
    1. ServiceManager
    2. zygote
  5. zygote
    1. SystemServer
    2. app

一、init

1、kernel/common/init/main.c

kernel_init();
->try_to_run_init_process("/bin/init");
  ->run_init_process(filename)
    ->kernel_execve(filename, xxx, xxx);
      ->// 会执行init

2、andorid.mk->android.bp编译

// init/android.bp

cc_binary {
   
    name: "init_second_stage",
    stem: "init",
    static_libs: ["libinit"],
    srcs: ["main.cpp"], // main.cpp
    // ...
}

3、init是用户空间鼻祖

  1. 属于C、C++ Framework

1.1 启动源码

FirstStageMain()
 ->挂载文件系统
 ->重定向输入输出
SetupSelinux()
 ->初始化Selinux
SecondStageMain()
 ->初始化属性
 ->设置Selinux
 ->监听子进程终止信号
    ->epoll_ctl 注册监听SIGCHILD 避免僵尸进程
 ->启动属性服务,将sokcet,注册到epoll中
 ->匹配命令和函数
 ->解析init.rc
    ->构造解析器,对应于rc文件里面的service、on、import
    ->parser.ParseConfig:解析rc文件
        ->解析Dir
        ->解析File
            ->按照二进制格式,解析:servicemanager、zygote
 -> 循环执行脚本,epoll循环等待
    -> 执行脚本
// frameworks/core/core/init/main.cpp
int main(int argc, char** argv) {
    // 会反复进入

// 2、第二次进来,根据参数执行
    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
                // 5、内部while+poll,第四阶段
            return SubcontextMain(argc, argv, &function_map);
        }
    // 3、selinux:第二阶段
        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }
    // 4、第三阶段
        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }

// 1、首次进来:第一阶段
    return FirstStageMain(argc, argv);
}

// 第一阶段:
int FirstStageMain(int argc, char** argv) {
    if (REBOOT_BOOTLOADER_ON_PANIC) {
        InstallRebootSignalHandlers();
    }
    CHECKCALL(clearenv());
    CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));
// 1、挂载文件系统
    CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
    CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));
    CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
    CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));
    CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));
    CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));
    // null也是作为管道文件进行处理
    CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));
    CHECKCALL(mkdir("/mnt/vendor", 0755));
    CHECKCALL(mkdir("/mnt/product", 0755));

// 2、重定向输入输出:stdio重定向Dev Null,作为管道文件,输入输出
    SetStdioToDevNull(argv);
    // 日志输出初始化
    InitKernelLogging(argv);
// 3、设置selinux安全策略:重新进入main.cpp
    const char* path = "/system/bin/init";
    const char* args[] = {path, "selinux_setup", nullptr};
    execv(path, const_cast<char**>(args)); // 执行

    return 1;
}
// Selinux:设置SeLinux安全策略,Android最小权限原则,selinux控制
int SetupSelinux(char** argv) {

    // 设置selinux
    SelinuxSetupKernelLogging();
    // selinux初始化
    SelinuxInitialize();
    // 重新进入第二阶段
    const char* path = "/system/bin/init";
    const char* args[] = {path, "second_stage", nullptr};
    execv(path, const_cast<char**>(args));
    return 1;
}

// frameworks/core/core/init.coo
int SecondStageMain(int argc, char** argv) {

    // Set init and its forked children's oom_adj.
    if (auto result = WriteFile("/proc/1/oom_score_adj", StringPrintf("%d", DEFAULT_OOM_SCORE_ADJUST));
        !result.ok()) {
        LOG(ERROR) << "Unable to write " << DEFAULT_OOM_SCORE_ADJUST
                   << " to /proc/1/oom_score_adj: " << result.error();
    }

// 1. 初始化属性:加载属性
    PropertyInit();

    // Mount extra filesystems required during second stage init
    MountExtraFilesystems();

// 2. Selinux相关
    SelinuxSetupKernelLogging();
    SelabelInitialize();
    SelinuxRestoreContext();

    Epoll epoll; // ===============================================================================> epoll
    if (auto result = epoll.Open(); !result.ok()) {
        PLOG(FATAL) << result.error();
    }
// 3. 监听子进程中止信号:避免僵尸进程 ==============================================================> 僵尸进程
    InstallSignalFdHandler(&epoll);
    InstallInitNotifier(&epoll);
// 4. 启动属性服务
    StartPropertyService(&property_fd);

    SetUsbController();

// 5. 匹配命令和函数的关系:mount等命令都对应于函数
    const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
    Action::set_function_map(&function_map);

// 6. 解析 init.rc
    LoadBootScripts(am, sm);

// 7. while循环解析脚本:启动zygote、执行重启
    while (true) {
        // 解析start等命令
        am.ExecuteOneCommand();
        // epoll_wait循环等待 ===================================================================> Handler中Looper.loop
        auto pending_functions = epoll.Wait(epoll_timeout);
    }

    return 0;
}

// >>>>>>>>>>>>>>>>>>>>>>>>>>
//在linux当中,父进程是通过捕捉SIGCHLD信号来得知子进程运行结束的情况,
//SIGCHLD信号会在子进程终止的时候发出
//函数的作用就是,接收到SIGCHLD信号时触发HandleSignalFd进行信号处理
// 这样可以在当子进程发出信号后能够及时的将它销毁,避免僵尸进程的存在
static void InstallSignalFdHandler(Epoll* epoll) {


    const struct sigaction act { .sa_handler = SIG_DFL, .sa_flags = SA_NOCLDSTOP };
    sigaction(SIGCHLD, &act, nullptr);

    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGCHLD); //SIGCHLD

    signal_fd = signalfd(-1, &mask, SFD_CLOEXEC);
    // 注册,epoll注册handler。 ===========================> epoll_ctl EPOLL_CTL_ADD
    if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result.ok()) {
        LOG(FATAL) << result.error();
    }
}
    // 注册,epoll注册handler。 ===========================> epoll_ctl EPOLL_CTL_ADD
Result<void> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
    epoll_event ev;
    ev.events = events;
    ev.data.ptr = reinterpret_cast<void*>(&it->second);
    if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
        epoll_handlers_.erase(fd);
        return result;
    }
    return {};
}

// >>>>>>>>>>>>>>>>>>> 启动属性服务,注册到epoll中
void StartPropertyService(int* epoll_socket) {
    InitPropertySet("ro.property_service.version", "2");

    int sockets[2];
    if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != 0) {
        PLOG(FATAL) << "Failed to socketpair() between property_service and init";
    }
    *epoll_socket = from_init_socket = sockets[0];
    init_socket = sockets[1];
    StartSendingMessages();

    if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, false, 0666, 0, 0, {});
        result.ok()) {
        property_set_fd = *result;
    }

    listen(property_set_fd, 8);

    auto new_thread = std::thread{PropertyServiceThread};
    property_service_thread.swap(new_thread);
}


init.rc解析

// 解析init.rc
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    // 1、创建对应解析器 service、on、import
    Parser parser = CreateParser(action_manager, service_list);

    // 2、解析init.rc init.rc里面有zygote等等
    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/system/etc/init/hw/init.rc");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        parser.ParseConfig("/system_ext/etc/init");
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
        if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}
// 根据rc文件的内容,创建对应解析器 
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser;
    parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, GetSubcontext(), std::nullopt));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
    parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));

    return parser;
}

// frameworks/core/core/init/parse.cpp
// 解析
bool Parser::ParseConfig(const std::string& path) {
    if (is_dir(path.c_str())) {
        return ParseConfigDir(path); // 目录 -> ParseConfigFile
    }
    return ParseConfigFile(path); // 文件
}
bool Parser::ParseConfigFile(const std::string& path) {
    // 解析数据
    ParseData(path, &config_contents.value());
    return true;
}

// 根据二进制格式要求,解析数据
void Parser::ParseData(const std::string& filename, std::string* data) {
    for (;;) {
        switch (next_token(&state)) {
            case T_EOF:
                // ...
                return;
            case T_NEWLINE: {
                // ...
                break;
            }
            case T_TEXT:
                args.emplace_back(state.text);
                break;
        }
    }
}

1.2 init.rc文件

import /system/etc/init/hw/init.${ro.zygote}.rc

on init

    # Mount binderfs
    mkdir /dev/binderfs
    mount binder binder /dev/binderfs stats=global
    chmod 0755 /dev/binderfs

    symlink /dev/binderfs/binder /dev/binder
    symlink /dev/binderfs/hwbinder /dev/hwbinder
    symlink /dev/binderfs/vndbinder /dev/vndbinder

    # Start essential services.
    start servicemanager
    start hwservicemanager
    start vndservicemanager

on late-init
    # Now we can start zygote for devices with file based encryption
    trigger 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 statsd
    start netd
    start zygote
    start zygote_secondary

二、ServiceManager

ServiceManager启动流程:见Binder部分。

main()
->1.初始化Binder驱动,加载"/dev/binder"
->2.实例化ServiceManager,并将自己作为第一个服务,进行添加注册
->3.将自己设置为IPCThreadState的contextobject,也就是设置服务端的BBinder对象
->4.利用Looper,也就是底层epoll处理事务,设置BinderCallback监听(epoll_ctl),无限等待
->5.while() // Binder驱动遇到事件,会回调handleEvent

三、Zygote

3.1 rc解析

// 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
 # zygote被关闭就会重启Android操作系统 
    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
// frameworks/base/cmds/app_process/Android.bp
cc_binary {
    name: "app_process",
    srcs: ["app_main.cpp"] // 指明代码为app_main.cpp
}

3.2 启动:app_main.cpp

AppRuntime
class AppRuntime : public AndroidRuntime
{
public:
    AppRuntime(char* argBlockStart, const size_t argBlockLength): AndroidRuntime(argBlockStart, argBlockLength), mClass(NULL){}

    void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {
        mClassName = className;
        for (int i = 0; i < argc; ++i) {
             mArgs.add(String8(argv[i]));
        }
    }

    virtual void onVmCreated(JNIEnv* env)
    {
        if (mClassName.isEmpty()) {
            return; // Zygote. Nothing to do here.
        }

        char* slashClassName = toSlashClassName(mClassName.string());
        mClass = env->FindClass(slashClassName);
        if (mClass == NULL) {
            ALOGE("ERROR: could not find class '%s'\n", mClassName.string());
        }
        free(slashClassName);

        mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
    }

    virtual void onStarted()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();

        AndroidRuntime* ar = AndroidRuntime::getRuntime();
        ar->callMain(mClassName, mClass, mArgs);

        IPCThreadState::self()->stopProcess();
        hardware::IPCThreadState::self()->stopProcess();
    }

// nativeZygoteInit调用时,被JNI中转到这里。
    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self(); // 1、初始化ProcessState(初始化Binder驱动)
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool(); // 2、创建Binder线程池,底层一路到IPCThreadState::self()->joinThreadPool();
    }

    virtual void onExit(int code)
    {
        if (mClassName.isEmpty()) {
            // if zygote
            IPCThreadState::self()->stopProcess();
            hardware::IPCThreadState::self()->stopProcess();
        }

        AndroidRuntime::onExit(code);
    }


    String8 mClassName;
    Vector<String8> mArgs;
    jclass mClass;
};
main

1、app_main.cpp 启动Zygote或者正常app流程 ->目录frameworks\base\cmds\app_process\

// 核心:根据init.zygote64.rc里面配置的参数,--zygote和--start-system-server,启动zygote,systemserver作为参数传入,以后启动
int main(int argc, char* const argv[])
{
    /**========================
     * 1、根据rc配置,解析出需要启动zygote,并且在zygote启动后,
     *========================*/
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // 解析传入的参数 -Xzygote /system/bin --zygote --start-system-server
    int i;
    for (i = 0; i < argc; i++) {
        // 参数解析
        runtime.addOption(strdup(argv[i]));
    }

    // 判断是zygote还是app
    bool zygote = false;
    bool startSystemServer = false; // 用于存入参数
    bool application = false; // app
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }

    }
    Vector<String8> args;
    if (!className.isEmpty()) {
        // 非zygote模式,存入application启动相关参数
        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);

    } else {
        // zygote模式,将systemserver和其他剩余参数,都一次性放入

        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }
        String8 abiFlag("--abi-list=");
        abiFlag.append(prop);
        args.add(abiFlag);
        // In zygote mode, pass all remaining arguments to the zygote
        // main() method.
        for (; i < argc; ++i) {
            args.add(String8(argv[i]));
        }
    }

    /**===============================================
     * 2、启动zygote(systemserver等内容作为参数传入)
     *====================
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值