init.rc文件

我们先看init.rc文件的具体内容。

import /init.environ.rc
import /system/etc/init/hw/init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /system/etc/init/hw/init.usb.configfs.rc
import /system/etc/init/hw/init.${ro.zygote}.rc
on early-init
    ...
on init
    ...
    # This allows the ledtrig-transient properties to be created here so
    # that they can be chown'd to system:system later on boot
    write /sys/class/leds/vibrator/trigger "transient"

    # This is used by Bionic to select optimized routines.
    write /dev/cpu_variant:${ro.bionic.arch} ${ro.bionic.cpu_variant}
    chmod 0444 /dev/cpu_variant:${ro.bionic.arch}
    write /dev/cpu_variant:${ro.bionic.2nd_arch} ${ro.bionic.2nd_cpu_variant}
    chmod 0444 /dev/cpu_variant:${ro.bionic.2nd_arch}

    # Allow system processes to read / write power state.
    chown system system /sys/power/state
    chown system system /sys/power/wakeup_count
    chmod 0660 /sys/power/state

    # Start logd before any other services run to ensure we capture all of their logs.
    start logd
    # Start lmkd before any other services run so that it can register them
    chown root system /sys/module/lowmemorykiller/parameters/adj
    chmod 0664 /sys/module/lowmemorykiller/parameters/adj
    chown root system /sys/module/lowmemorykiller/parameters/minfree
    chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
    start lmkd

    # Start essential services.
    start servicemanager
    start hwservicemanager
    start vndservicemanager

# Mount filesystems and start core system services.
on late-init
    trigger early-fs

    trigger fs
    trigger post-fs

    # Now we can start zygote for devices with file based encryption
    trigger zygote-start

    # Remove a file to wake up anything waiting for firmware.
    trigger firmware_mounts_complete

    trigger early-boot
    trigger boot

# 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
    wait_for_prop odsign.verification.done 1
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start statsd
    start netd
    start zygote
    start zygote_secondary

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

on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
    wait_for_prop odsign.verification.done 1
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start statsd
    start netd
    start zygote
    start zygote_secondary

解析init.rc

接着我们看是怎么解析init.rc文件的。给parse变量进行赋值,创建了三个parser,分别是对service,on,import单词进行parse。
首先*.rc 脚本中所有 service关键字定义的服务将会添加到service_list列表中。
*.rc 脚本中所有on关键开头的项将会被会添加到 action_list 列表中。

Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser;
    parser.AddSectionParser("service", std::make_unique(&service_list, GetSubcontext(), std::nullopt));
    parser.AddSectionParser("on", std::make_unique(&action_manager, GetSubcontext()));
    parser.AddSectionParser("import", std::make_unique(&parser));
    return parser;
}
void Parser::AddSectionParser(const std::string& name, std::unique_ptr parser) {
    section_parsers_[name] = std::move(parser);
}

用于解析的关键函数是parseData函数,
next_token函数用就是寻找单词结束或者行结束标志,如果是单词结束标志就将单词push到args中,如果是行结束标志,则根据第一个单词来判断是否是一个section,section的标志只有三个"on",“service”,“import”,如果是"section",会根据关键字的不同会调用不同的 parser去解析(多态) 通过相应的ParseSection()函数来处理一个section,,action使用ActionParser,而 service 使用 ServiceParser 解析,该部分定义在LoadBootScrip()函数的第一行,parser.AddSectionParser()方法为parser的map成员section_parsers_创建了三个SectionParser,分别用来解析service,on,import的section;否则把这一行继续作为前“section”所属的行来处理
ParseSection()被用来解析一个新的section,ParseLineSection()被用来解析该section下的命令行

void Parser::ParseData(const std::string& filename, std::string* data) {
   data->push_back('\n');
   data->push_back('\0');

   for (;;) {
       switch (next_token(&state)) {
           case T_EOF:
               end_section();

               for (const auto& [section_name, section_parser] : section_parsers_) {
                   section_parser->EndFile();
               }

               return;
           case T_NEWLINE: {
               state.line++;
               if (args.empty()) break;
               // If we have a line matching a prefix we recognize, call its callback and unset any
               // current section parsers.  This is meant for /sys/ and /dev/ line entries for
               // uevent.
               auto line_callback = std::find_if(
                   line_callbacks_.begin(), line_callbacks_.end(),
                   [&args](const auto& c) { return android::base::StartsWith(args[0], c.first); });
               if (line_callback != line_callbacks_.end()) {
                   end_section();

                   if (auto result = line_callback->second(std::move(args)); !result.ok()) {
                       parse_error_count_++;
                       LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
                   }
               } else if (section_parsers_.count(args[0])) {
                    end_section();
                    section_parser = section_parsers_[args[0]].get();
                    section_start_line = state.line;
                    if (auto result =
                                section_parser->ParseSection(std::move(args), filename, state.line);
                        !result.ok()) {
                        parse_error_count_++;
                        LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
                        section_parser = nullptr;
                        bad_section_found = true;
                    }
                } else if (section_parser) {
                    if (auto result = section_parser->ParseLineSection(std::move(args), state.line);
                        !result.ok()) {
                        parse_error_count_++;
                        LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
                    }
                } else if (!bad_section_found) {
                    parse_error_count_++;
                    LOG(ERROR) << filename << ": " << state.line
                               << ": Invalid section keyword found";
                }
                args.clear();
                break;
            }
            case T_TEXT:
                args.emplace_back(state.text);
                break;
        }
    }
}

解析完了init.rc文件以后,调用am.QueueEventTrigger(‘init-early’)意为early-init时间已经到来,可以执行triggle只为early-init的action了。
init最终会进入了无限循环的监听状态,可以看到这里面一个核心函数就是 am.ExecuteOneCommand();之前说的QueueEventTrigger(“early-init”)把early-init加入到event_queue_的队列中,ExecuteOneCommand()一开始就遍历之前解析的action向量表。当一个 action对象所有的 command 均执行完毕后,再执行下一个action。

从init.rc文件中可以看到最关键的是启动zygote。



本站内容来源于作者发布和网络转载,如有版权相关问题请及时与我们取得联系,我们将立即删除。

 关于作者
 热门教程
系统启动流程
1、BootRom 启动电源以及系统启动。 当电源按下时,引导芯片代码从预定义的地方(固化在ROM中)开始执行。加载引
2023-09-10
剑道仙尊
54
Android源码开始
Framework源码下载: https://android.googlesource.com/platform/fr
2023-09-10
剑道仙尊
55
Launcher的Activity.onCreate
进入 ActivityThread.main,最终完成 Launcher.onCreate 操作 Zygote for
2022-09-11
剑道仙尊
41
Launcher启动流程
Launcher介绍 系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就叫做 Laun
2022-09-11
剑道仙尊
43
创建Launcher进程
Zygote进程接收请求并创建 Launcher进程 想要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程
2022-09-11
剑道仙尊
45
Launcher的配置
Launcher 的配置 在 SystemServer.startOtherServices 方法中调用Activit
2022-09-11
剑道仙尊
45
PackageManagerService
PackageManagerService( PMS ) 1、PMS会把每个apk进行扫描,然后分别把每个apk里的信
2022-09-11
剑道仙尊
42
WindowManagerService
待更新。。。
2022-09-11
剑道仙尊
27
ActivityManagerService
ActivityManagerService(AMS)主要负责系统中四大组件的启动、切换、调度以及应用程序的管理和调度
2022-09-11
剑道仙尊
51
systemserver进程
system server进程是由zygote进程fork出来的,在上面的ZygoteInit.main方法中调用fo
2022-09-10
剑道仙尊
33