您的位置:首页 > 教育 > 培训 > Android Init Language自学笔记

Android Init Language自学笔记

2024/10/6 10:35:58 来源:https://blog.csdn.net/a2516110/article/details/140268971  浏览:    关键词:Android Init Language自学笔记

Android Init Language由五个元素组成:Acttions、Commands、Services、Options和Imports。

Actions和Services隐式声明了一个新的section。所以的Commands和Options都属于最近声明的section。

Services具有唯一的名称,如果重名会报错。

Actions

Actions被视为Commands的序列。

Actions有一个trigger指明什么时候action被执行。当有和trigger事件匹配的事件发生时,这个action会被添加到待执行队列的尾部(除非它已经存在于队列中)。

Actions形如:

on <trigger> [&& <trigger>]*<command><command><command>...

Services

Services是init启动或重启时执行的程序。形如:

service <name> <pathname> [ <argument> ]*<option><option><option>...

Options

Options是Services的修饰符,表示如何或何时运行service。

具体有哪些Options,详见:init/README.md (googlesource.com)

Commands

具体有哪些Commands,详见:init/README.md (googlesource.com)
在代码中(/system/core/init/builtins.cpp)中,有Commands与函数的映射,指明了某个Command所对应的C++代码的执行函数。

// Builtin-function-map start
const BuiltinFunctionMap& GetBuiltinFunctionMap() {constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();// clang-format offstatic 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",     {0,     0,    {false,  do_verity_update_state}}},{"wait",                    {1,     2,    {true,   do_wait}}},{"wait_for_prop",           {2,     2,    {false,  do_wait_for_prop}}},{"write",                   {2,     2,    {true,   do_write}}},};// clang-format onreturn builtin_functions;
}

例如,bootchart这个Commands的执行函数是do_bootchart()这个函数。do_bootchart()函数如下:

Result<void> do_bootchart(const BuiltinArguments& args) {if (args[1] == "start") return do_bootchart_start();return do_bootchart_stop();
}

Imports

形如:

import <path>

Import有它自己的section,不是Actions的一部分。

Import用来解析init配置文件、扩展当前配置。如果 是一个目录,则其中所有文件会被当作配置文件解析,但不是解析子目录中的文件。

Triggers(触发器)

触发器用来匹配某类事件并触发aciton发生。

触发器分为事件触发器和属性触发器。

事件触发器由“trigger” Command或init程序的QueueEventTrigger()函数触发。

属性触发器是在属性改变时触发。

一个Action可以有多个属性触发器,但只能有一个事件触发器。

具体有哪些触发器,详见:init/README.md (googlesource.com)

init.rc举例

下面节选一下init.rc文件中怎么写的,先感受一下

# Copyright (C) 2012 The Android Open Source Project
#
# IMPORTANT: Do not create world writable files or directories.
# This is a common source of Android security bugs.
#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......# Mount filesystems and start core system services.
on late-inittrigger early-fs# Mount fstab in init.{$device}.rc by mount_all command. Optional parameter# '--early' can be specified to skip entries with 'latemount'.# /system and /vendor must be mounted by the end of the fs stage,# while /data is optional.trigger fstrigger post-fs# Mount fstab in init.{$device}.rc by mount_all with '--late' parameter# to only mount entries with 'latemount'. This is needed if '--early' is# specified in the previous mount_all command on the fs stage.# With /system mounted and properties form /system + /factory available,# some services can be started.trigger late-fs# Now we can mount /data. File encryption requires keymaster to decrypt# /data, which in turn can only be loaded when system properties are present.trigger post-fs-data# Should be before netd, but after apex, properties and logging is available.trigger load_bpf_programs# Now we can start zygote for devices with file based encryptiontrigger zygote-start# Remove a file to wake up anything waiting for firmware.trigger firmware_mounts_completetrigger early-boottrigger boot......service boringssl_self_test32 /system/bin/boringssl_self_test32reboot_on_failure reboot,boringssl-self-check-failedstdio_to_kmsg# Explicitly specify that boringssl_self_test32 doesn't require any capabilitiescapabilitiesuser nobody

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com