https://www.cnblogs.com/littleboy123/p/13208179.html
https://www.jianshu.com/p/0a8bfc073090
目录
一、init程序基本说明
所谓的init程序有2个,一个是根文件系统根目录下的init,一个是/system/bin/init,我们习惯把这两个init分别称为first init
与second init
.内核默认执行first init
,first 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文件
0 条评论