https://www.cnblogs.com/littleboy123/p/13208179.html
https://www.jianshu.com/p/0a8bfc073090

一、init程序基本说明

所谓的init程序有2个,一个是根文件系统根目录下的init,一个是/system/bin/init,我们习惯把这两个init分别称为first initsecond init.内核默认执行first initfirst init最终会执行second init.

1.first init

其main函数类为first_stage_main.cpp,编译目标位于Android.mk。

LOCAL_MODULE := init_first_stage
LOCAL_MODULE_STEM := init

LOCAL_FORCE_STATIC_EXECUTABLE := true

为静态链接执行文件
first_stage_main.cpp的源码非常简单,会调用first_stage_init.cpp里的FirstStageMain方法。

FirstStageMain方法主要工作
1)挂载一些文件系统
2)创建一些设备节点

FirstStageMain最终会执行second first,会携带selinux_setup参数。

    const char* path = "/system/bin/init";
    const char* args[] = {path, "selinux_setup", nullptr};
    execv(path, const_cast<char**>(args));

first init 最终会生成在out/target/product/kona/ramdisk/中,并打包到ramdisk.img中。

在编译boog.img时,如果first init的源码有改动,会自动编译。

2.second init

int main(int argc, char** argv) {
    #if __has_feature(address_sanitizer)
        __asan_set_error_report_callback(AsanReportCallback);
    #endif

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

    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap function_map;

            return SubcontextMain(argc, argv, &function_map);
        }

        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }

        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }

    return FirstStageMain(argc, argv);
}

2-1)SetupSelinux

实现类为system/core/init/selinux.cpp

// This function initializes SELinux then execs init to run in the init SELinux context.
int SetupSelinux(char** argv) {
    InitKernelLogging(argv);

    if (REBOOT_BOOTLOADER_ON_PANIC) {
        InstallRebootSignalHandlers();
    }

    // Set up SELinux, loading the SELinux policy.
    SelinuxSetupKernelLogging();
    SelinuxInitialize();

    // We're in the kernel domain and want to transition to the init domain.  File systems that
    // store SELabels in their xattrs, such as ext4 do not need an explicit restorecon here,
    // but other file systems do.  In particular, this is needed for ramdisks such as the
    // recovery image for A/B devices.
    if (selinux_android_restorecon("/system/bin/init", 0) == -1) {
        PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
    }

    const char* path = "/system/bin/init";
    const char* args[] = {path, "second_stage", nullptr};
    execv(path, const_cast<char**>(args));

    // execv() only returns if an error happened, in which case we
    // panic and never return from this function.
    PLOG(FATAL) << "execv(\"" << path << "\") failed";

    return 1;
}

根据源码可知SetupSelinux方法会再次调用second init并携带参数
second_stage

2-2)SecondStageMain

实现类为system/core/init/init.cpp
SecondStageMain的源码追踪:

2-2-1)InstallSignalFdHandler

监听子进程,进行处理(回收、重启)。
https://blog.csdn.net/weixin_49274713/article/details/130485247

https://blog.csdn.net/qq_28261343/article/details/128280652

2-2-2)property_load_boot_defaults()

从各种build.prop文件中读取属性

2-2-3)LoadBootScripts

解析各种和开机启动相关的.rc文件

分类: init程序

0 条评论

发表回复

您的电子邮箱地址不会被公开。