当前位置: 首页 > news >正文

Android init.rc详解2

上一章节的Android init.rc 详解1介绍了.rc中Actions中常见的Trigger/Service,本章节介绍修饰Service的Options和Command。

 1 Options

Options是用来修饰Services,指定how和when初始化运行这些services。

  • class <name> [ <name>\* ]

  1. 指定Service所属的类别class,同一个class name的所有服务可以一起启动或者停止。如果未指定class的service,则默认在“default”类下。
  2. 第二个name一般用于对服务进行分组。
  3. 常见的class分组有:core, main
  • critical [window=<fatal crash window mins>] [target=<fatal reboot target>]

  1. 指定Service是一个设备关键型的服务,fatal crash window mins默认值4分钟,fatal reboot target默认值bootloader,还可取值recovery,shutdown(关机),coldboot(正常重启系统)。
  2. 当该service在4min中崩溃退出超过4次,或者系统启动完成前崩溃多次,则设备会进入bootloader(fastboot)模式。
  3. 防止底层关键service反馈crash导致设备无法使用,并提供一种“安全退出”机制,引导用户进入可修复状态(刷机,恢复出厂设置,重启)。
  • disabled

指定Service不随着所属class自动启动,必须通过服务名(eg: start vold)或者接口名显式启动。

  • group <groupname>  [<groupname>\*]

  1. 在执行该service之前,切换到指定的groupname。
  2. 第一个组名是必须的,代表主组,后边的组名用于设置service的补充组。当前默认组为root。
  3. 常见系统组及其用途
    组名用途
    root超级权限,可访问几乎所有设备和文件(不推荐滥用)
    system系统服务常用组
    shelladb shell 用户所属组
    net_raw允许创建 RAW 套接字(如 ping、tcpdump)
    inet网络访问权限
    sdcard_r / sdcard_rw外部存储读写权限
    graphicsGPU、SurfaceFlinger 相关权限
    camera访问摄像头设备节点
    input读取输入设备(如 /dev/input/event*)常见系统组及其用途
  • interface <interfacename> <instance name>

  1. 将service与其提供的AIDL或者HIDL服务接口关联起来。该机制用于让servicemanager(AIDL)或hwservicemanager(HIDL)能够按需懒加载启动服务(lazy start),即如果该服务未运行,servicemanager会自动触发init启动该服务。
  2. 当一个service提供多个接口时,需要多次使用interface。
  3. HIDL 接口:interface <package>@<version>::<interface> <instance_name>
    eg:interface vendor.foo.bar@1.0::IBaz default
  4. AIDL 接口interface aidl <instance name>
    AIDL 接口的 instance name 是注册到 servicemanager 中的名称,可通过 adb shell dumpsys -l 查看所有已注册的 AIDL 服务列表。
  5. 配合disabled使用,实现懒加载。
    service vendor.myhal.camera@2.0 /vendor/bin/hw/camera@2.0-serviceclass haldisabledinterface vendor.myhal.camera@2.0::ICameraProvider default

        该service(vendor.myhal.camera@2.0)不会自动启动。
        当应用打开相机时,ICameraProvider.getService() 触发 → 自动拉起该Service。

  • ioprio <calss> <priority>

  1. 为Service设置I/O优先级(IO priority)和I/O优先级类(IO priority class)。

  2. class取值:“rt”-实时(最高优先级,IO请求优先处理),"be"-尽力而为(默认,优先级有priority的值决定),“idle”-空闲(最低优先级,仅当系统无其他IO请求时才执行)。
  3. priority:必须是0-7的整数,0优先级最高,7最低。
  • namespace <pid|mnt>

为服务创建独立的PID命名空间和mount命名空间,实现进程或文件系统的隔离。init无法直接管理该服务的子进程,通常用于生命周期明确、自我管理的服务。

  • oneshot

当该Service退出时,init不会重启它。核心关键服务不能用oneshot修饰。

  • onrestart <command>

当该Service被重启时,执行onrestart后的指令。

eg: 当surfaceflinger服务重启时,要重启zygote

///Project_14/LA.QSSI.14.0.r1/LINUX/android/frameworks/native/services/surfaceflinger/surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflingerclass core animationuser systemgroup graphics drmrpc readproccapabilities SYS_NICEonrestart restart --only-if-running zygotetask_profiles HighPerformancesocket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
  • oom_score_adjust <value>

  1. 设置该Service的子进程的/proc/self/oom_score_adj为指定值,取值在-1000到1000之间。该值影响在内存不足时进程被kill的优先级。
  2. 值越小,被kill的概率越低。保护critical进程,避免因内存不足被回收。
  • priority <value>

设置Service的CPU调度优先级(scheduling priority,即nice值),其值必须在-20到19之间,默认优先级在0,数值越小,优先级越大。

  • reboot_on_failture <target>

  1. 如果该Service启动失败,或者程序退出的信号类型不是CLD_EXITED(子进程正常退出),而是列入SIGSEGV、SIGKILL等,则使用指定的target重启系统。
  2. <target> 支持的目标格式:与 sys.powerctl 一致,常见值包括:
    target 值含义
    reboot正常重启系统
    reboot,bootloader重启进入 Fastboot 模式
    reboot,recovery重启进入 Recovery 模式
    reboot,fastboot同 bootloader(较新命名)
    shutdown关机
    reboot,fastboot-unicorn厂商自定义模式(如小米的“EDL”)
  • setenv <name> <value>

设置Service的环境变量。

  • shutdown <shutdown_behavior>

  1. 定义Service在系统关机或者重启过程中的行为,例如是否立即终止。
  2. <behavior>的值包括
behavior值含义
不设置值,默认空

默认,系统进入关机流程时,iinit会向所有服务发送:

  • SIGTERM(请求优雅退出)

  • 等待一段时间(通常几秒)

  • 发送 SIGKILL(强制终止)

critical

在关机初期,该Service不会立即被kill,允许继续运行,关机流程超时会强制杀死所有进程。

如果该Service未启动运行,init会先启动,然后再进入关机流程

  • capabilities [ <capability> * ]

  1. 为该Service设置其能力(即权限),实现精细化授权。

  2. 常见capability取值由:

capability 值含义
NET_ADMIN配置网络接口(如设置 IP、路由)
SYS_TIME修改系统时间
CHOWN更改文件所有者
DAC_OVERRIDE绕过文件读写权限检查
SYS_NICE调整进程优先级(如 setpriority
SETPCAP设置自身或其他进程的能力(高危!)
  • socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]

  1. 创建一个名为 /dev/socket/<name> 的 UNIX 域套接字(UNIX domain socket),并在服务启动时将其文件描述符(fd)传递给该进程。Socket是用来进行进程间通信的。
  2.  参数详解
参数说明
<name>套接字名称,最终路径为 /dev/socket/<name>。例如 socket adbd stream 660 → /dev/socket/adbd
<type>套接字类型:<br>• dgram:UDP 风格,无连接,数据报<br>• stream:TCP 风格,面向连接,字节流<br>• seqpacket:有序、可靠、基于消息的数据包(类似 dgram 但保证顺序)
<perm>套接字文件的权限(八进制, rwx-三个用户类),如 660666777
<user>套接字所有者用户,默认 0(root)
<group>套接字所属组,默认 0(root)
<seclabel>SELinux 安全上下文,如 u:object_r:adbd_socket:s0
  • task_profiles <profile> [ <profile> * ]

  1. 设置任务(task)性能配置文件。在 Android U (14)之前:这些配置文件仅应用于服务的主线程(main thread)。从 Android U 及以后版本开始:这些配置文件将应用于整个服务进程的所有线程。
  2. 该属性旨在取代writepid选项,后者是用于将进程(或线程)移动到特定的 cgroup(控制组)中,但由于需要具体的cgroup路径,设备差异大,难以维护,因此启用。writepid的使用,以蓝牙举例:
  3. service vendor.bluetooth-1-0-qti /vendor/bin/hw/android.hardware.bluetooth@1.0-service-qti-lazyinterface android.hardware.bluetooth@1.0::IBluetoothHci defaultoneshotdisabledclass halcapabilities BLOCK_SUSPEND NET_ADMIN SYS_NICEuser bluetoothgroup bluetooth system wakelock oem_2901 net_raw oem_2912writepid /dev/stune/foreground/tasks
  4. <profile>的取值不是枚举的硬编码,而是由系统通过task_profiles.json配置文件定义。我们项目里源码路径在/Project_14/LA.QSSI.14.0.r1/LINUX/android/
    system/core/libprocessgroup/profiles/task_profiles.json下,以下是部分profile的定义:
    "Profiles": [{"Name": "HighEnergySaving","Actions": [{"Name": "JoinCgroup","Params":{"Controller": "cpu","Path": "background"}}]},...
    {"Name": "NormalPerformance","Actions": [{"Name": "JoinCgroup","Params":{"Controller": "cpu","Path": "system"}}]},{"Name": "ServicePerformance","Actions": [{"Name": "JoinCgroup","Params":{"Controller": "cpu","Path": "system-background"}}]},{"Name": "HighPerformance","Actions": [{"Name": "JoinCgroup","Params":{"Controller": "cpu","Path": "foreground"}}]},{"Name": "MaxPerformance","Actions": [{"Name": "JoinCgroup","Params":{"Controller": "cpu","Path": "top-app"}}]},{"Name": "RealtimePerformance","Actions": [{"Name": "JoinCgroup","Params":{"Controller": "cpu","Path": "rt"}}]},{"Name": "CameraServicePerformance","Actions": [{"Name": "JoinCgroup","Params":{"Controller": "cpu","Path": "camera-daemon"}}]},{"Name": "AudioAppPerformance","Actions" : [{"Name" : "JoinCgroup","Params" :{"Controller": "schedtune","Path": "audio-app"}}]}
    }

2 Command

  • bootchart [start|stop]

  1. 启动或停止bootcharting(系统启动性能分析),bootcharting只有在文件/data/bootchart/enabled 存在时才会激活,斗则将不执行任何操作。
  2. bootchart是一个收集和分析Android系统启动过程性能数据的工具,通过采样CPU、I/O、进程活动等信息,生成可视化的启动时序图(.png.svg),帮助开发者优化开机时间。
  3. bootchart start:在启动早期(如 on init 阶段)调用,启动数据采集。
  4. bootchart stop:在启动后期(如 on property:sys.boot_completed=1)调用,停止采集并生成日志。
  5. init.rc中使用该command的举例:
    on post-fs-data# Start bootcharting as soon as possible after the data partition is# mounted to collect more data.mkdir /data/bootchart 0755 shell shell encryption=Requirebootchart starton property:sys.boot_completed=1bootchart stop# Setup per_boot directory so other .rc could start to use it on boot_completedexec - system system -- /bin/rm -rf /data/per_bootmkdir /data/per_boot 0700 system system encryption=Require key=per_boot_refsetprop ro.vendor.qti.per_boot_created 1

Android 系统的关键启动时间指标(如 bootanimation 显示、sys.boot_completed=1)主要取决于:

  • class_start main
  • class_start late_start
  • 关键服务(如 zygotesystem_server)的启动速度。
  • chmod <octal-mode> <path>

  1. 更改指定文件或者目录的访问权限(读/写/执行),使用8进制表示法。
  2. 使用举例:
# set system-background to 0775 so SurfaceFlinger can touch it
chmod 0775 /dev/cpuset/system-backgroundchmod 0664 /dev/cpuset/foreground/tasks
chmod 0664 /dev/cpuset/background/tasks
chmod 0664 /dev/cpuset/system-background/tasks
chmod 0664 /dev/cpuset/top-app/tasks
  • chown <owner> <group> <path>

  1. 改变文件的所有者和用户组。
  2. 使用举例
 # change permissions for all cpusets we'll touch at runtime
chown system system /dev/cpuset
chown system system /dev/cpuset/foreground
chown system system /dev/cpuset/background
chown system system /dev/cpuset/system-background

✅ 总结

指令作用典型用途注意事项
bootchart [start|stop]控制启动性能分析优化开机时间需手动创建 /data/bootchart/enabled 启用
chmod <mode> <path>修改文件权限设置可执行、保护敏感文件使用八进制权限,最小权限原则
chown <owner> <group> <path>修改文件所有者和组确保服务能访问资源与 chmod 配合使用
  • class _start <serviceclass>

  1. 启动指定类别(service class)的所有服务,前提是这些服务尚未运行。将同一类别的service集中管理,便于延迟启动或者统一控制。
  2. 他是一个批量启动服务的指令,常见的service class由
service class 值含义
main

系统运行所必需的核心服务:zygote, bluetoothbd, storaged, 

core核心服务,servicemanager, console,ueventd, bootanim
late_start非关键、耗时或可延迟的服务(优化启动时间的关键,可以缩短sys.boot_completed时间)
early_hal需要在main之前启动的服务
hal指Android HAL层的服务,用于与底层通信。
charger和充电有关的service,例如charger,hw-health-service,在on charger触发的services
  • class_stop <serviceclass>

  1. 关闭指定类型的services。
  2. 使用举例
# Healthd can trigger a full boot from charger mode by signaling this
# property when the power button is held.
on property:sys.boot_from_charger_mode=1class_stop chargertrigger late-init
  • class_restart [ --only--enabled ] <serviceclass>

  1. 重启指定类别的所有services。
  2. 如果指定了--only--enabled,则跳过被禁用的服务(即disabled修饰的service)。
  3. 如果没有指定该选项,则会尝试重启该类别下的所有服务(包括disabled和oneshort修饰的service),如果服务正在运行,则先stop,然后再start;如果服务没运行,直接start。

✅ 总结

指令作用是否阻塞典型触发时机
class_start <class>启动指定类别中尚未运行的服务否(异步)on booton property:
class_stop <class>停止指定类别中正在运行的所有服务否(异步)用户切换、省电模式、调试
class_restart [--only-enabled] <class>先停止,再重新启动该类所有服务否(异步)错误恢复、配置重载、调试
  • start <service>

如果指定的服务尚未运行,则启动该服务。如果该服务已运行,start不会重复启动。

  • stop <service>

停止运行指定的service。

  • restart [ --only-if-running ] <service>

  1. 停止并重启一个正在运行的service。
  2. 如果该service处于重启过程中,则不执行任何操作
  3. 如果该服务未运行,则直接启动该服务(相当于start <service>);
  4. 如果指定了--only-if-running选项,则仅当服务正在运行时才执行重启。如果服务未运行,则不做任何操作。

exec_start <service>

  1. 启动指定的服务,并暂停后续init指令,知道该service执行完成并返回。
  2. 他是惟一能阻塞init进程的同步指令,允许在关键启动中精确控制执行顺序,确保某些service必须启动完成。
  3. 使用举例:
on zygote-start && property:ro.crypto.state=unencrypted# wait OTA signature verifcation wait_for_prop odsign.verification.done 1# A/B update verifier that marks a successful boot.exec_start update_verifier_nonencryptedstart statsdstart netdstart zygotestart zygote_secondary
  • A/B update:又称无缝更新,设备上由两套系统分区:A和B,当前系统允许在分区A,分区B可以后台静默更新,更新完成后,下次重启就切换到B分区。 
  • 首次启动B系统,则必须标记本次启动成功,如果启动成功,则B被永久标注为“新系统”,如果启动失败,下次自动切换A分区。
  • A/B update verifier:检查当前系统是否时首次从新系统启动,如果是则将successful标志置为1
  • enable <servicename>

  1. 将一个disabled的service转化成enable,即激活service。
  2. enable本身不启动服务,他只是激活service,当service的启动条件满足时才会被启动,即使他是disabled。

✅ 总结

指令作用是否阻塞 init典型使用场景注意事项
start <servic>启动一个已定义的服务

 否

(异步)

正常启动服务,如 start zygote若服务已在运行,不会重复启动
stop <servic>停止一个正在运行的服务

(异步)

关机、切换模式时停止服务服务进程退出后不再自动重启(除非有 respawning)
restart <servic>先 stop,再 start 服务

(异步)

配置变更后重载服务,如 restart adbd等价于 stop + start,服务会短暂中断
exec_start <servic>同步执行一个 oneshot 服务,并等待其完成

(同步)

关键初始化任务,如标记 OTA 成功、运行配置脚本仅适用于 oneshot 服务;init 会等待其退出后再执行后续命令
enable <service>激活一个被 disabled 的服务,使其可被 start 或自动启动

(异步)

根据属性动态启用服务,如 enable watchdogd when ro.boot.quiescent=1服务必须先定义为 disabledenable 后若满足条件(如属于 main class 且已 class_start),会立即启动
  • exec [ <seclabel> [ <user> [ <group> *] ] ] -- <command> [ <argument> *]

fork一个子进程并在指定的上下文(SELinux权限以及user/group)下执行。

该指令是一个同步的,会阻塞init进程。在该指令执行完成前,init将暂停后续所有指令。

参数解释说明
<seclabel>

SELinux 安全上下文,如 u:r:init:s0

用 - 表示默认

<user>执行用户,如 rootsystemshell
<group>*零个或多个补充组,如 inetlogsystem
--分隔符,表示前面是执行上下文,后面是命令
<command>要执行的可执行文件路径
[argument]*命令参数,支持属性展开 ${prop}
  • exec_backgroud [ <seclabel> [ <user> [ <group> *] ] ] -- <command> [ <argument> *]

  1. 与exec类似,fork一个子进程并在指定的上下文(SELinux权限以及user/group)下执行。
  2. 该指令是异步的,不会阻塞init,会继续执行后续指令。

✅ 总结

指令是否阻塞 init用途
exec✅ 是(同步)执行关键初始化任务,必须完成才能继续
exec_background❌ 否(异步)执行非关键、后台任务,不阻塞启动流程
  • setprop <name> <value>

  1. 给指定的系统属性赋值。

  2. 它是触发属性值为条件(on property:)的event,eg:
    on property:sys.boot_completed=1bootchart stop# Setup per_boot directory so other .rc could start to use it on boot_completedexec - system system -- /bin/rm -rf /data/per_bootmkdir /data/per_boot 0700 system system encryption=Require key=per_boot_refsetprop ro.vendor.qti.per_boot_created 1
  3. 常见的系统属性分类:
    前缀说明是否可写
    ro.*只读属性(Read-Only)❌ 仅在 init 阶段可设,之后不可改
    sys.*系统属性,可被 init 和系统服务修改✅ 可修改
    persist.*持久化属性,写入 /data/property/✅ 可修改,重启后保留
    ctl.*控制属性(如 ctl.startctl.stop✅ 触发服务控制
    debug.*调试属性✅ 开发者可设symlink <target> <path>
  • trigger <event>

触发一个事件,用于从一个Action执行完成后,主动触发另一个Action。

  • symlink <target> <path>

在指定path创建一个指向target的符号链接(相当于软连接,即ln -s <target> <path>)。

  • wait_for_prop <name> <value>

  1. 等待指定系统属性的值变成指定value,如果该属性值等于value,则立即执行后续命令。

  2. 他是init中用于同步控制的关键指令,setprop会触发该指令往后执行。

http://www.dtcms.com/a/331094.html

相关文章:

  • 前端vue框架
  • 算法题Day1
  • Ubuntu 22.04 远程桌面设置固定密码的方法
  • 使用colmap自制3DGaussian_Splatting数据集
  • OpenCV 形态学操作
  • spring mvc HttpMessageConverter 消息转换器
  • 性能测试环境的软硬件配置
  • SpringMVC基本原理和配置
  • 进程、进程命令、进程相关编程
  • 19. 什么是 TypedArray
  • Subarray Sums II
  • EtherCAT概念介绍
  • Python入门第1课:环境搭建与第一个程序“Hello World”
  • python学习DAY41打卡
  • 前端已死,AI技术正在重塑前端软件工程师
  • 护照查验接口牢筑跨境场景安全防线-JavaScript集成示例
  • Elasticsearch ABAC 配置:实现动态、细粒度的访问控制
  • 玩转Docker | 使用Docker部署JSON格式化工具ZJSON
  • Java-数构map和set
  • 高效解决 pip install 报错 SSLError: EOF occurred in violation of protocol
  • P5967 [POI 2016] Korale 题解
  • Transformer之多头注意力机制和位置编码(二)
  • Canon PowerShot D30相机 CHDK 固件 V1.4.1
  • 5.Ansible-playbook-模块介绍(知识点补充)
  • 【Postgresql】实现 PostgreSQL 全量审计日志:记录所有 SQL 操作及来源
  • 【C++】细说继承(2w字详解)
  • ROS机器人云实践案例博客建议和范文-AI版本
  • imx6ull-驱动开发篇24——Linux 中断API函数
  • MATLAB绘制各种心形曲线
  • window显示驱动开发—在混合系统中使用跨适配器资源