Android进程对应的文件有后缀为rc文件的,那么rc文件是什么又是怎么加载启动的呢

0rc文件简介

init.rc由AIL语言编写而成。可以参考system/core/init/README.md来学习AIL语法相关知识。具体可以点击下面源码文件路径访问

不同Android版本关于AIL的说明存在一些细微差异,但基本语法和总的思路是不变的。往往我们可以先查看对应的system/core/init/README.md来了解这些差异。

Android Init Language由五大类语句组成:

  • Actions
  • Commands
  • Services
  • Options
  • Imports

换行为语句分隔符。空格为词分隔符。反斜杠转义符可用于插入不做分隔的空格符。双引号用于包括不需要空格分隔的词。行尾反斜杠用于多行衔接为一行。行首以 # 开始用于注释。使用${var}可进行变量扩展。 一段内容往往以Actions 或者Services开头,并以Commands或者Options结尾。 Commands 或者Options用于修饰Actions 或者Services。(阅读时注意) Service有唯一名称,如果已经定义过一个相同的Service,后定义的被忽略,且log中记录了此异常。

1init.rc

平时最常见的就是开机需要用到的rc文件。

一般设备系统中多个路径下都存在rc文件。一般规范的路径为:/{system,vendor,odm}/etc/init/*.rc

根目录/init.rc为主rc文件,它是rc文件被加载的入口。它通过Imports语句将其他各个路径下的rc文件都加载进来。

1.1rc文件目录规范

路径 功能
/system/etc/init/ 用于核心系统功能,例如SurfaceFlingerMediaServicelogd
/vendor/etc/init/ 用于芯片供应商的一些核心操作或者守护进程功能
/odm/etc/init/ 用于设备制造厂商的功能,比如传感器和其他外围设备所需的操作或者守护进程

服务对应的二进制程序如果放在system|vendor|odm分区下,相应的定义服务的rc文件也需要在相同分区的etc/init/目录下。一般我们开发的时候rc和二进制程序是在相同的工程目录下,在Android.bp 是通过配置init_rc。

更改分区的方法

  • 默认安装到/system目录下

  • 安装到vendor

    vendor: true

  • 安装到product

    product_specific: true

  • 安装到odm

    device_specific: true

 1//logcatd开发的工程目录在system/core/logcat
 2//logcatd  logcatd.rc都在此工程目录下
 3//通过Android.bp指定init_rc 
 4
 5//@system/core/logcat/Android.bp
 6sh_binary {
 7    name: "logpersist.start",
 8    src: "logpersist",
 9    init_rc: ["logcatd.rc"],
10    required: ["logcatd"],
11    symlinks: [
12        "logpersist.stop",
13        "logpersist.cat",
14    ],
15//最终编译出来的logcatd.rc就位于system/etc/init/logcatd.rc
16$ cd out/target/product/${TARGET_PRODUCT}
17$ find -name logcatd.rc
18./system/etc/init/logcatd.rc

2语法详解

2.1Actions

Actions 是一系列commands的集合,同时包含一个trigger来决定是否要执行这一系列的命令。当触发器被触发时,Action就被加入执行队列(已在队列中则忽略)。每个队列中的Action是按顺序执行和移除的,而Action中的命令也是按顺序执行的。而其他的一些操作包括设备创建销毁,property的设置以及进程的重启是穿插在各个命令执行之间的。格式如下:

1on <trigger> [&& <trigger>]*
2   <command1>
3   <command2>
4   <command3>

同时被触发的Action将按照他们在rc文件中定义的先后顺序加入到执行队列中。例如:

 1on boot
 2   setprop a 1
 3   setprop b 2
 4
 5on boot && property:test=true
 6   setprop c 1
 7   setprop d 2
 8
 9on boot
10   setprop e 1
11   setprop f 2

如果当前启机且test属性为true,则执行顺序如下:

1setprop a 1
2setprop b 2
3setprop c 1
4setprop d 2
5setprop e 1
6setprop f 2

Triggers

Trigger 含义
bott 这是init程序启动后出发的第一个事件
< name > = < value > 当属性< name >满足特定< value >时触发
device-added-< path> 当设备节点添加/删除时触发此事件
service-exited-< name > 当指定的服务< name >存在时触发

一系列明确的事件,用于触发action操作。触发器分为事件触发器属性触发器

  • 事件触发器

    由“trigger”命令或init程序中的QueueEventTrigger()函数触发的。它们一般采用简单字符串的形式,例如“boot”或“late init”

  • 属性触发器

    由指定的Property更改时触发的。Property变更为某个指定的value,格式为property:=. Property只要有变更就触发,格式为property:=*

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

1#表示在开机并且 property:a=b时触发action。
2on boot && property:a=b

2.2Commands

名称 含义
exec < path > [< argument >]* Fork并执行一个程序,其路径为< path >,这条命令将阻塞直到该程序启动完成,因此他有可能造成init程序在某个点不停的等待。
export < name >< value > 设置某个环境变量< name >的值为< value >,这是对全局有效的,即其后的所有进程都将继承这个变量。
ifup < interface > 使网络接口< interface >成功连接
hostname < name > 设置主机名为< name >
chdir < directory > 更改工作目录为< directory >
chmod < octal-modc > 更改文件访问权限
chown < owner >< group >< path > 更改文件所有者和组群
chroot < directory > 更改根目录位置
class_start < serviceclass > 启动由< servicesclass >类名指定的所有相关服务,如果他们不存在运行状态的话
class_stop < serviceclass > 停止所有由< serviceclass >指定的服务,如果他们当前正在运行的话
domainname < name > 设置域名
insmod < path > < path >路径上安装一个模块
mkdir < path >[mode][owner][group] < path >上新建一个目录
mount < type >< device >< dir >[mountoption] 尝试在指定路径上挂载一个设备
setprop< name >< value > 设置系统属性< name >的值< value >
start < service > 这个命令将启动一个服务,如果他没有处于运行状态的话
stop < service > 这个命令将停止一个服务,如果他没有处于运行状态的话
exec [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ] 使用给定的参数Fork并执行命令。该命令在“——”之后开始,以便提供可选的安全上下文、用户和补充组。在此命令完成之前,不会运行其他命令。Seclabel可以是a -来表示默认。属性在参数内展开。Init停止执行命令,直到fork进程退出。exec – /system/bin/bootstrap/linkerconfig –target /linkerconfig/bootstrapexec - system system – /system/bin/vdc checkpoint markBootAttempt
symlink < target >< path > 创建一个< path >路径的连接,目标为< target >
sysclktz 设置基准时间,如果当前时间是GMT,这个值为0
trigger < event > 触发一个事件
write < path >< string >[ < string >]* 打开一个文件,并写入一个或多个字符串

mkdir <path> [<mode>] [<owner>] [<group>] [encryption=<action>] [key=<key>]

创建目录,可以指定mode,owner和group. 如果不指定则按权限为755,root用户和root组创建。如果指定了,但目录已存在,则目录的权限和用户,组信息将被更新。

action 可以指定为:

  • None: 不需要进行加密操作,目录根据上层目录加密算法进行处理。
  • Require: 需要加密,如果加密失败则终止开机进程。
  • Attempt: 尝试加密,加密失败仍可继续。
  • DeleteIfNecessary: 递归处理:如果存在子目录,但当前策略的加密算法不匹配,则删除子目录。

key 可以指定为:

  • ref: 使用systemwide DE key
  • per_boot_ref: 使用每次开机都更新的key

mount_all [ <fstab> ] [--<option>]

对给出的 fstab 表调用 fs_mgr_mount_all 接口,option为“early” 或者 “late”. option如果是–early则init将会跳过“latemount”标识的的item,并触发fs encryption state 事件。option如果是–late则init就只mount “latemount”标识的的item. 如果不携带[–]则mount的是fstab 表中全部item。

 1on fs
 2      mount_all /vendor/etc/fstab.${ro.hardware} --early
 3  
 4on late-fs
 5      # Start services for bootanim
 6      start servicemanager
 7      start hwcomposer-2-1
 8      start gralloc-2-0
 9      start surfaceflinger
10      start bootanim
11  
12      exec_start wait_for_keymaster
13      # Mount RW partitions which need run fsck
14      mount_all /vendor/etc/fstab.${ro.hardware} --late

调用到对应的fstab.${ro.hardware}

 1$ cat /vendor/etc/fstab.rk30board                                                                           # Android fstab file.
 2#<src>  <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
 3# The filesystem that contains the filesystem checker binary (typically /system) cannot
 4# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
 5
 6/dev/block/by-name/system                          /                          ext4      ro,barrier=1                                                      wait,avb,slotselect
 7/dev/block/by-name/cache                           /cache                    ext4       noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard                wait,check
 8/dev/block/by-name/metadata                        /mnt/vendor/metadata       ext4       noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard                wait
 9/dev/block/by-name/misc                            /misc                      emmc       defaults                                                           defaults
10/dev/block/by-name/frp                             /frp                       emmc       defaults                                                           defaults
11/dev/block/by-name/parameter                        /parameter                 emmc      defaults                                                            defaults
12/dev/block/by-name/baseparamer                    /baseparamer                emmc        defaults                                                            defaults
13/dev/block/by-name/resource	                     /resource	                  emmc	     defaults				                              defaults
14/devices/platform/*usb*                               auto                     vfat       defaults                                                        voldmanaged=usb:auto
15/dev/block/zram0                                     none                      swap       defaults                                                        zramsize=50%
16# For sdmmc
17/devices/platform/fe320000.dwmmc/mmc_host*           auto                      auto           defaults                                                  voldmanaged=sdcard1:auto
18# Full disk encryption has less effect on rk3399, so default to enable this.
19/dev/block/by-name/userdata                         /data                      f2fs      noatime,nodiratime,nosuid,nodev,discard,inline_xattr,fsync_mode=strict     wait,check,notrim,forceencrypt=/cache/key_file,quota,reservedsize=128M

2.3Services

Service指的是需要在初始化就启动的服务,通过定义还可以让他们在退出的时候自动重启。格式如下:

1service <name> <pathname> [ <argument> ]*
2   <option>
3   <option>
4   ...

举例说明

2.3.1无参数

1#init.rc
2service ueventd /system/bin/ueventd
3    class core
4    critical
5    seclabel u:r:ueventd:s0
6    shutdown critical

2.3.2有参数

1# logcatd service
2service logcatd /system/bin/logcatd -L -b ${logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r ${logd.logpersistd.rotate_kbytes:-2048} -n ${logd.logpersistd.size:-256} --id=${ro.build.id}
3    class late_start
4    disabled
5    # logd for write to /data/misc/logd, log group for read from log daemon
6    user logd
7    group log
8    task_profiles ServiceCapacityLow
9    oom_score_adjust -600

2.4Options

Option 是修饰service的属性,它用于定义service何时启动以及怎样启动。

option Description
critical 表明这个对设备至关重要的服务,如果他在四分钟内退出超过4次,则设备将重启进入bootloader模式
capabilities [ <capability>\* ] 表示执行该service的能力,如果没有增加capabilities修饰,则表示该服务没有任何capabilities
console [<console>] 用于指定该服务输出 是否要打印到dmesg。 默认输出到/dev/console, 而/dev/console可以通过设置androidboot.console来指定
timeout_period <seconds> 超过这个时间kill掉serviceoneshot service不会被重启,其他服务会自动重启。与restart_period配合使用可以创建周期运行的service
disable 此服务不会自动启动,而是需要通过显示调用服务名来启动
file <path> <type> 打开文件,并将它的fd传递给进程,C 层可使用android_get_control_file获取到fd。 type类为:“r”, “w” ,“rw”
interface <interface name> <instance name> 关联HIDL接口,名称必须是完整的,这样才能方便hwservicemanager快速启动这些HIDL服务。可关联多个HIDL 接口
keycodes <keycode> [ <keycode>\* ] 设置keycode,当同时触发这些按键事件时,服务将启动。常用于bugreport service
setenv < name >< value > 设置环境变量< name >为某个值< value >
socket < name >< type >< perm >[< user >[ < group >]] 创建一个名为/dev/socket/< name >Unix domain socket,然后将他的fd值传给启动它的进程,有效的< type >值包括dgram,steamseqpacket.而usergroup的默认值是0
ioprio <class> <priority> 通过SYS_ioprio_set syscall设置此service的IO优先级和IO优先级类。类为“rt”“be”“idle”。优先级为0-7
user < username > 在启动服务前将用户切换至< username >,默认情况下用户都是root
group < groupname >[< groupname >] 在启动服务将用户组切换至< groupname >
oneshot 当此服务退出时,不要主动去重启他
class < name > 为该服务指定一个class名,同一个class的所有服务必须同时自动或者停止,默认情况下服务的class名是”default”
onrestart 当此服务重启时,执行某些命令
enter_namespace <type> <path> 输入路径的namespace。network type可以指定为"net". 只能设置一个type
`namespace <pid mnt>`
oom_score_adjust <value> 自定义oom_score,等同于优先级,优先级越高值越小(-1000 ~1000)。分值越小越不会被kill
override 一般是odm service使用,用于覆盖之前system或者vendor已经定义的服务配置。如果rc中存在多个override标识的相同类名服务,则最后一个被解析的服务才生效。可以通过imports分析,避免出错。
priority <priority> 设置service进程的优先级。范围为-20~19. 默认为0. 实际是通过setpriority()函数设置
reboot_on_failure <target> 当该服务启动失败或者运行中异常退出时,执行重启。 参数 其实就是设置property sys.powerctl 的值。格式一般为"reboot,reason"
restart_period <seconds> 设置后non-oneshot 服务将以此周期重启服务。比如restart_period 3600 表示该服务将会每隔1小时启动
rlimit <resource> <cur> <max> 对当前服务以及子进程生效。等同于setrlimit命令。rootfs,ueventd, adbd等,默认为init.
shutdown <shutdown_behavior> 指定当关机时service进程行为。如果没有具体说明,关机时,使用SIGTERMSIGKILL关闭service。关机期间,“critical” 标识的service不会被关闭直到关机超时。“critical” 标识的service在关机开始时,如果没处于运行状态,则它还会被启动
socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ] 创建一个名为/dev/socket/nameUNIXsocket,并将其fd传递给service程序。type必须为“dgram”“stream”“seqpacket”。type可以加后缀“+passcred”,启用SO_PASSCRE。用户和组默认值为0。”seclabel’指的是selinux context. 进程中C层可以使用 libcutils ``android_get_control_socket()来获取这个fd
user <username> 指定user,默认为root。早期要获取Linux capabilities,进程需要以root运行并请求capabilities,之后再修改成它期望的运行uid。通过fs_config有一种新的机制来替换早期的那种实现,现在允许厂商将程序的Linux capabilities添加到文件系统中
task_profiles <profile> [ <profile>\* ] 设置任务profiles。这是为了取代writepid来设置当前serviceprofiles
writepid <file> [ <file>\* ] 将子进程的pid写入文件中,以支持cgroup/cpuset的使用。如果指定的不是/dev/cpuset/,但是property ‘ro.cpuset.default’ 中设置了非空的cpuset名称 (比如: ‘/foreground’),那么pid会被写入/dev/cpuset/cpuset_name/tasks。 此option仅适用于子进程,如果要设置当前servicetask profiles, 就需要使用task_profiles.
  • capabilities [ <capability>\* ] 表示执行该service的能力,如果没有增加capabilities修饰,则表示该服务没有任何capabilities。

     1  ###example1, BLOCK_SUSPEND:
     2  service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service.ranchu
     3      class hal
     4      user audioserver
     5      # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
     6      group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
     7      #有能力block系统休眠
     8      capabilities BLOCK_SUSPEND
     9      ioprio rt 4
    10      task_profiles ProcessCapacityHigh HighPerformance
    11      onrestart restart audioserver
    12
    13  ###example2,NET_ADMIN NET_RAW:
    14  service ril-daemon /vendor/bin/hw/libgoldfish-rild
    15      class main
    16      user radio
    17      group radio cache inet misc audio log readproc wakelock
    18      #NET_ADMIN:执行和网络相关的一系列操作,例如接口配置,防火墙配置等等
    19      #NET_RAW: 使用RAW and PACKET socket接字绑定到任何地址进行透明代理
    20      capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW
    21
    22  ###example3,SYS_BOOT:
    23  service charger /system/bin/charger
    24      class charger
    25      seclabel u:r:charger:s0
    26      user system
    27      group system wakelock input
    28      #有能力进行reboot或者调用kexec_load
    29      capabilities SYS_BOOT
    30      file /dev/kmsg w
    31      file /sys/fs/pstore/console-ramoops-0 r
    32      file /sys/fs/pstore/console-ramoops r
    33      file /proc/last_kmsg r
    
  • class <name> [ <name>\* ] 用于指定service的类名,相同的类名可以在action中配置成一起启动或者一起停止。 一个service至少有一个class,如果没有指定 class name, 默认class 为"default"。当然也可以指定多个class name, 多个class name便于service分组管理。

     1  ###example1, animation 
     2  service vendor.gralloc-3-0 /vendor/bin/hw/android.hardware.graphics.allocator@3.0-service
     3      interface android.hardware.graphics.allocator@3.0::IAllocator default
     4      #`animation` calss是指可以进行开机动画或者关机动画的服务组。
     5      #这些服务往往很早就运行或者在关机的最后阶段运行的
     6      #因此需要注意他们不能去打开/data下的文件,应该要保证/data分区即便卸载了也能正常运行。
     7      class hal animation
     8      interface android.hardware.graphics.allocator@3.0::IAllocator default
     9      user system
    10      group graphics drmrpc
    11      capabilities SYS_NICE
    12      onrestart restart surfaceflinger
    13
    14  ###example2, core
    15  service shutdownanim /system/bin/bootanimation shutdown
    16      #core 一般是早启动,最晚结束的一些系统核心程序
    17      class core
    18      user graphics
    19      group graphics audio
    20      disabled
    21      oneshot
    22
    23
    24  ###example3, main
    25  service wpa_supplicant /vendor/bin/hw/wpa_supplicant \
    26      /vendor/etc/wifi/wpa_config.txt
    27  #   we will start as root and wpa_supplicant will switch to user wifi
    28  #   after setting up the capabilities required for WEXT
    29  #   user wifi
    30  #   group wifi inet keystore
    31      interface android.hardware.wifi.supplicant@1.0::ISupplicant default
    32      interface android.hardware.wifi.supplicant@1.1::ISupplicant default
    33      interface android.hardware.wifi.supplicant@1.2::ISupplicant default
    34      interface android.hardware.wifi.supplicant@1.3::ISupplicant default
    35      #class main 一般为framework层进程
    36      class main
    37      socket wpa_wlan0 dgram 660 wifi wifi
    38      disabled
    39      oneshot
    40
    41
    42  ###example4, late_start
    43  service bugreport /system/bin/dumpstate -d -p -B -z \
    44          -o /data/user_de/0/com.android.shell/files/bugreports/bugreport
    45      #late_start: 一般在初始化最后阶段才需要启动的程序
    46      class late_start
    47      disabled
    48      oneshot
    49      keycodes 114 115 116
    
  • console [<console>] 用于指定该服务输出 是否要打印到dmesg。 默认输出到/dev/console, 而/dev/console可以通过设置androidboot.console来指定。

     1#@*.rc
     2service recovery /sbin/recovery
     3    console
     4    seclabel u:r:recovery:s0
     5#@BoardConfig_*.mk
     6 BOARD_KERNEL_CMDLINE := androidboot.wificountrycode=CN androidboot.hardware=rk30board androidboot.console=ttyFIQ0 firmware_class.path=/vendor/etc/firmware init=/init rootwait ro init=/init
     7
     8#@device 可以查看console相关属性:
     9$ getprop |grep conso                                                                                                                                                               
    10[init.svc.console]: [running]
    11[ro.boot.console]: [ttyFIQ0]
    12[ro.boottime.console]: [3672952642]
    13[ro.consoleable]: [1]
    
  • critical用于说明关键服务,当该服务4分钟内或者在开机完成前退出超过4次,将会导致设备进入bootloader模式。

    1service ueventd /sbin/ueventd
    2      #指明是关键服务
    3      critical
    4      seclabel u:r:ueventd:s0
    
  • file <path> <type> 打开文件,并将它的fd传递给进程,C 层可使用android_get_control_file获取到fd。 type类为:“r”, “w” ,“rw”。

     1service charger /system/bin/charger
     2      class charger
     3      seclabel u:r:charger:s0
     4      user system
     5      group system wakelock input
     6      capabilities SYS_BOOT
     7      file /dev/kmsg w
     8      file /sys/fs/pstore/console-ramoops-0 r
     9      file /sys/fs/pstore/console-ramoops r
    10      file /proc/last_kmsg r
    
  • interface <interface name> <instance name>关联HIDL接口,名称必须是完整的,这样才能方便hwservicemanager快速启动这些HIDL服务。可关联多个HIDL 接口。

    1service wpa_supplicant /vendor/bin/hw/wpa_supplicant -Dnl80211 -iwlan0 -c/vendor/etc/wifi/wpa_supplicant.conf -g@android:wpa_wlan0
    2      interface android.hardware.wifi.supplicant@1.0::ISupplicant default
    3      interface android.hardware.wifi.supplicant@1.1::ISupplicant default
    4      interface android.hardware.wifi.supplicant@1.2::ISupplicant default
    5      interface android.hardware.wifi.supplicant@1.3::ISupplicant default
    6      socket wpa_wlan0 dgram 660 wifi wifi
    7      group system wifi inet
    8      oneshot
    9      disabled
    
  • keycodes <keycode> [ <keycode>\* ] 设置keycode,当同时触发这些按键事件时,服务将启动。常用于bugreport service。

    1service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service.ranchu
    2      class hal
    3      user audioserver
    4      # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
    5      group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
    6      capabilities BLOCK_SUSPEND
    7      ioprio rt 4
    8      task_profiles ProcessCapacityHigh HighPerformance
    9      onrestart restart audioserver
    
  • onrestart 当该service重启时,运行命令

    1# bugreport is triggered by holding down volume down, volume up and power
    2service bugreport /system/bin/dumpstate -d -p -B -z \
    3          -o /data/user_de/0/com.android.shell/files/bugreports/bugreport
    4      class late_start
    5      disabled
    6      oneshot
    7      keycodes 114 115 116
    

2.5Imports

import <path>导入一个新的rc文件内容,如果path是个目录,则会导入该目录下所有rc文件内容,仅导入当前目录,不支持递归,不能导入子目录下的rc文件。

import关键字并不是一个命令,它遵循以下规则

1. 开机时,加载根目录下的/init.rc 或者加载 `ro.boot.init_rc` 中指定的脚本。
2. 在加载/init.rc之后mount {system,vendor,odm}的时候就加载对应的 /{system,vendor,odm}/etc/init/ 下的rc文件。

关于加载顺序

 1fn Import(file)
 2  Parse(file)
 3  for (import : file.imports)
 4    Import(import)
 5
 6Import(/init.rc)
 7Directories = [/system/etc/init, /vendor/etc/init, /odm/etc/init]
 8for (directory : Directories)
 9  files = <Alphabetical order of directory's contents>
10  for (file : files)
11    Import(file)
  1. /init.rc 先被解析加载,同时在它内部import的rc文件会被递归加载。
  2. /system/etc/init/下的rc文件按名字的字母排序排序后加载进来,加载一个的同时递归加载import进来的rc文件。
  3. 再重复2继续处理r /vendor/etc/init 之后 /odm/etc/init 的rc文件。

2.6一点点补充关于属性

ctl.[<target>_]<command> 以ctl打头的这个格式的属性能够触发init的响应,且该属性是只用于set而不用于read的。<target>是可选的,一般为一个service的option,只能指定一个option。<commands>只能为start restart stop 中的一个。这个属性的value就是对应的service名称。

 1##就会运行logd的start option。
 2SetProperty("ctl.start", "logd")
 3#就会启动一个提供了 `aidl aidl_lazy_test_1`接口 的service 的start option. 		
 4SetProperty("ctl.interface_start", "aidl/aidl_lazy_test_1")
 5#按oneshort启动,如果进程挂掉不再重启。
 6SetProperty("ctl.oneshot_one_start", "logd") 
 7# 进程挂掉后还要重新启动。
 8SetProperty("ctl.oneshot_off_start", "logd")
 9#发送SIGSTO给该服务。用于调试。
10SetProperty("ctl.sigstop_on_start", "logd")
11SetProperty("ctl.sigstop_off_start", "logd")

源码文件

https://github.com/YangYang48/project/tree/master/rc

参考

[1] 一切皆是定数, Android启动流程(四)——rc文件解析, 2023.

[2] astro-yang, init.rc语法详解, 2015.

[3] 面包派, Android init.rc整理, 2022.

[4] 时光如刀, Android 8.0 系统启动流程之init.rc语法规则(六), 2018.

[5] 安德路, init.rc深入学习, 2017.

[6] Eliot_shao, Init.rc妙用及语法说明, 2016.

[7] 疯人院的院长大人, Android系统init进程启动及init.rc全解析, 2022.

[8] 疯人院的院长大人, recovery下的init.rc语法解析, 2017.