1 概述
rc文件由安卓初始化语言编写,可用于初始化系统服务,设置属性,创建系统资源等操作。
rc文件在init进程中完成扫描,解析,加载,执行等操作。
system/core/init/init.cpp
//执行第二阶段的启动
int SecondStageMain(int argc, char** argv) {
//创建epoll
Epoll epoll;
if (auto result = epoll.Open(); !result.ok()) {
PLOG(FATAL) << result.error();
}
//导入rc文件中command相关的对应函数关系
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
//将函数对应map设置到Action类的全局变量中function_map_中
Action::set_function_map(&function_map);
//am是rc文件中的action管理,负责触发执行。
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
//加载引导脚本,即rc文件
LoadBootScripts(am, sm);
// Turning this on and letting the INFO logging be discarded adds 0.2s to
// Nexus 9 boot time, so it's disabled by default.
if (false) DumpState();
// Make the GSI status available before scripts start running.
auto is_running = android::gsi::IsGsiRunning() ? "1" : "0";
SetProperty(gsi::kGsiBootedProp, is_running);
auto is_installed = android::gsi::IsGsiInstalled() ? "1" : "0";
SetProperty(gsi::kGsiInstalledProp, is_installed);
//添加内置动作触发器,其他的action在rc文件中用on声明。这里会同时添加到事件队列和action队列
am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
am.QueueBuiltinAction(TestPerfEventSelinuxAction, "TestPerfEventSelinux");
am.QueueBuiltinAction(ConnectEarlyStageSnapuserdAction, "ConnectEarlyStageSnapuserd");
//触发rc中定义的early-init操作
am.QueueEventTrigger("early-init");
// Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
//热插拔事件的触发器
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
// ... so that we can start queuing up actions that require stuff from /dev.
am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
/组合键触发器
Keychords keychords;
am.QueueBuiltinAction(
[&epoll, &keychords](const BuiltinArguments& args) -> Result<void> {
for (const auto& svc : ServiceList::GetInstance()) {
keychords.Register(svc->keycodes());
}
keychords.Start(&epoll, HandleKeychord);
return {
};
},
"KeychordInit");
// Trigger all the boot actions to get us started.
//触发rc中定义的init操作
am.QueueEventTrigger("init");
// Don't mount filesystems or start core system services in charger mode.
std::string bootmode = GetProperty("ro.bootmode", "");
if (bootmode == "charger") {
//触发rc中定义的charger操作
am.QueueEventTrigger("charger");
} else {
//触发rc中定义的late-init操作
am.QueueEventTrigger("late-init");
}
// Run all property triggers based on current state of the properties.
//根据现在的属性来触发属性触发器
am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
...
while (true) {
...
//这里真正执行rc文件中定义的命令
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
}
...
}
return 0;
}
2 加载命令-函数map
init第二阶段启动
system/core/init/init.cpp
//导入rc文件中command相关的对应函数关系
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
//将函数对应map设置到Action类的全局变量中function_map_中
Action::set_function_map(&function_map);
system/core/init/action.cpp
// Builtin-function-map start
const BuiltinFunctionMap& GetBuiltinFunctionMap() {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
// clang-format off
//命令与函数对应关系,查看rc文件时,根据后面对应函数进行执行
static const BuiltinFunctionMap builtin_functions = {
{
"bootchart", {
1, 1, {
false, do_bootchart}}},
{
"chmod", {
2, 2, {
true, do_chmod}}},
{
"chown", {
2, 3, {
true, do_chown}}},
{
"class_reset", {
1, 1, {
false, do_class_reset}}},
{
"class_restart", {
1, 2, {
false, do_class_restart}}},
{
"class_start", {
1, 1, {
false, do_class_start}}},
{
"class_stop", {
1, 1, {
false, do_class_stop}}},
{
"copy", {
2, 2, {
true, do_copy}}},
{
"copy_per_line", {
2, 2, {
true, do_copy_per_line}}},
{
"domainname", {
1, 1, {
true, do_domainname}}},
{
"enable", {
1, 1, {
false, do_enable}}},
{
"exec", {
1, kMax, {
false, do_exec}}},
{
"exec_background", {
1, kMax, {
false, do_exec_background}}},
{
"exec_start", {
1, 1, {
false, do_exec_start}}},
{
"export", {
2, 2, {
false, do_export}}},
{
"hostname", {
1, 1, {
true, do_hostname}}},
{
"ifup", {
1, 1, {
true, do_ifup}}},
{
"init_user0", {
0, 0, {
false, do_init_user0}}},
{
"insmod", {
1, kMax, {
true, do_insmod}}},
{
"installkey", {
1, 1, {
false, do_installkey}}},
{
"interface_restart", {
1, 1, {
false, do_interface_restart}}},
{
"interface_start", {
1, 1, {
false, do_interface_start}}},
{
"interface_stop", {
1, 1, {
false, do_interface_stop}}},
{
"load_exports", {
1, 1, {
false, do_load_exports}}},
{
"load_persist_props", {
0, 0, {
false, do_load_persist_props}}},
{
"load_system_props", {
0, 0, {
false, do_load_system_props}}},
{
"loglevel", {
1, 1, {
false, do_loglevel}}},
{
"mark_post_data", {
0, 0, {
false, do_mark_post_data}}},
{
"mkdir", {
1, 6, {
true, do_mkdir}}},
// TODO: Do mount operations in vendor_init.
// mount_all is currently too complex to run in vendor_init as it queues action triggers,
// imports rc scripts, etc. It should be simplified and run in vendor_init context.
// mount and umount are run in the same context as mount_all for symmetry.
{
"mount_all", {
0, kMax, {
false, do_mount_all}}},
{
"mount", {
3, kMax, {
false, do_mount}}},
{
"perform_apex_config", {
0, 0, {
false, do_perform_apex_config}}},
{
"umount", {
1, 1, {
false, do_umount}}},
{
"umount_all", {
0, 1, {
false, do_umount_all}}},
{
"update_linker_config", {
0, 0, {
false, do_update_linker_config}}},
{
"readahead", {
1, 2, {
true, do_readahead}}},
{
"remount_userdata", {
0, 0, {
false, do_remount_userdata}}},
{
"restart", {
1, 2, {
false, do_restart}}},
{
"restorecon", {
1, kMax, {
true, do_restorecon}}},
{
"restorecon_recursive", {
1, kMax, {
true, do_restorecon_recursive}}},
{
"rm", {
1, 1, {
true, do_rm}}},
{
"rmdir", {
1, 1, {
true, do_rmdir}}},
{
"setprop", {
2, 2, {
true, do_setprop}}},
{
"setrlimit", {
3, 3, {
false, do_setrlimit}}},
{
"start", {
1, 1, {
false, do_start}}},
{
"stop", {
1, 1, {
false, do_stop}}},
{
"swapon_all", {
0, 1, {
false, do_swapon_all}}},
{
"enter_default_mount_ns", {
0, 0, {
false, do_enter_default_mount_ns}}},
{
"symlink", {
2, 2, {
true, do_symlink}}},
{
"sysclktz", {
1, 1, {
false, do_sysclktz}}},
{
"trigger", {
1, 1, {
false, do_trigger}}},
{
"verity_update_state"