<Android开发> Android内核系统开发-启动过程详解(第1部分 init.rc语法详解)
前言: android系统开发有关代码详解流程等,均以高通8155为例,代码则是以对厂商开放的LA 1.1基线代码为例(基线代码等只有高通授权厂商才有权下载)。 Android设备的启动必须经历3个阶段过程,包含bootloader、Linux Kernel、和Android系统服务,每个阶段过程都有其对应的启动界面。由启动阶段过程可看出,Android系统实际上是运行在Linux内核上的一系列的“服务进程”,并不算一个完整意义上的“操作系统”。这些“服务进程”则是维持设备正常工作的关键所在,而这些进程的“始祖”就是init进程,init进程则是Linux kernel 启动的第一个进程。 init作为第一个被启动的进程,其进程PID值为0;进程init通过解析init.rc脚本来构建出系统的初始运行形态;android中的大多数系统服务都是由init.rc来启动的。所以init.rc的编写实现是每个厂商控制自己研发设备启动状态的利剑。 在详细熟悉init.rc的内容之前,先来看看".rc"文件书写的语法格式。所以本小节主要讲解 init.rc的语法 。
init.rc的语法
在高通的LA1.1基线代码中,对init.rc的注释比较少,在源码目录中有文档“system\core\init\README.md”对源码进行分析。 一个完整的init.rc脚本由4中类型的声明组成,即: * Actions (动作) * Commands (命令) * Service (服务) * Options (选项) 第一步,我们先来了解一些语法的通用规则方法: 》注释,以井号(“#”)开头; 》关键字和参数之间用空格分隔,语句的执行以行为单位; 》c语言风格的反斜杠转义字符(“\”)可以用来为参数添加空格; 》字符串中包含空格,可使用双引号括起来; 》行尾加反斜杠(“\”)表示当前行 与 下一行 合并为1行 》Actions(动作) 和 Server(服务)暗示着一个新语句的开始,这两个关键字后面跟着的Commands(命令)或者options(选项)都是是属于这个新语句的部分; 》Actions(动作) 和 Server(服务)有唯一的名字,如果出现和已有动作或服务重名的,将会被当成错误忽略掉;
下面详细分析各组成的元素…
1、Actions(动作) 动作的一般格式如下所示:
on <trigger> #触发的条件
<command 1> #在触发条件满足的条件下,执行该命令
<command 2> #在触发条件满足的条件下,执行该命令
<command 3> #在触发条件满足的条件下,执行该命令 可连续执行多个命令
.......
由上述可知,每一个Action其实是响应某事件的过程。即当所描述的触发事件产生时,依次执行各种command(命令)(同一个事件可以对应多个命令)。从系统源码实现的角度来说,当相应的事件发生后,系统会对init.rc中的各进行匹配,只要发现符合条件的Actions,就会把它加入“命令执行队列”的尾部(除非这个actions在队列中已经存在,存在则不重复加入),然后系统再对这些命令按顺序执行。
2、Commands(命令) 命令将在所属事件发生时被一个一个的执行。 init中定义的一些常见事件,如表2-1: 表:2-1 init.rc中常见的触发事件
Trigger | Description |
---|
boot | 这是init程序启动后触发的第一个事件 | <name> | 当属性满足特定<vaule>时触发。 | boot | 这是init程序启动后触发的第一个事件 | device-added-<path> 或者 device-removed-<path> | 当设备节点添加/删除时触发此事件 | service-exited-<name> | 当指定的服务存在时触发 |
针对上面所描述的事件,有如下表2-2所示命令可供使用。
表2-2 init.rc中常见命令
Command | Description |
---|
exec <path> [<argument>] * | Fork并执行一个程序,其路径为<path>。这条命令将阻塞直到该程序启动完成,因此它有可能造成init程序在某个点不停的等待 | export <name><value> | 设置某个环境变量<name>的值为<value>。这对全局有效的,即其后所有进程都将继承这个变量 | ifup <interface> | 使网络接口<interface>成功连接 | import <filename> | 解析另一个配置文件,名为<filename>,以扩展当前配置 | hostname <name> | 设置主机名为<name> | chdir <directory> | 更改工作目录为<directory> | chmod <octal-mode> <path> | 更改文件访问权限 | chown<owne><group> <path> | 更改文件所有者和组群 | chroot <directory> | 更改根目录位置 | class_start<serviceclass> | 启动由<serviceclass>类指定的所有相关服务,如果它们不在运行状态的话 | class_stop<serviceclass> | 停止由<serviceclass>类指定的服务,如果它们正在运行状态的话 | domainname<name> | 设置域名 | insmod<path> | 在<path>路径上安装一个模块 | mkdir<path> [mode] [owner] [group] | 在<path>路径上新建一个目录 | mount<type><device> <dir>[<mountoption>]* | 尝试在指定路径挂在一个设备 | setkey | 目前未定义 | setprop<name><value> | 设置系统属性<name>的值为<value> | setlimit<resource><cur><max> | 设置一种资源的使用限制,这个概念亦存在与Linux系统中,<cur>表示软限制,<max>表示硬限制。更多详情请参考Linux资料 | start<service> | 这个命令将启动一个服务,如果它没有处于运行状态的话 | stop<service> | 这个命令将停止一个服务,如果它正处于运行状态的话 | symlink<target><path> | 创建一个<path>路径的链接,目标为<target> | syslktz<mins_west_of_gmt> | 设置基准时间,如果当前时间是GMT,这个值是0 | trigger<event> | 触发一个事件 | write<path><string> [<string>]* | 打开一个文件,并写入一个或多个字串 |
3、Services(服务) Services其实就医一个可执行的程序,它们在特定选项的约束下会被init程序运行或者重启。Services可以在配置中指定是否需要退出时重启,这样当Services出现异常crash时就可以有机会复原。 Services的一般格式如下:
service <name><pathname> [<agument>]*
<option>
<option>
<option>
........
参数详解: <name> :表示此service的名称; <pathname>:此service所在的路径,因为时可执行文件,所以一定存在存储路径; <agument>:启动service所带的参数; <option>:对此service的约束选项(在后面讲解)
4、Options(选项) 在前面service中的选项有如下表4-1选项可选。 表4-1 service中的可用选项
Option | Description |
---|
criical | 表明这是设备至关重要的一个服务,如果它在4分钟内退出超过4次,则设备将重启进入恢复模式 | disabled | 此服务不会自动启动,而是需要通过显示调用服务名来启动 | setenv <name> <value> | 设置环境变量<name>为某个值<value> | socket<name><type> <perm> [<user> [<group>] ] | 创建一个名为/dev/socket/<name>的unix domain socket,然后将它fd值传给启动它的进程。有效的<type> 值包括dgram,stream和seqpacket。而user和group的默认值是0 | user<username> | 在启动服务前将用户切换至<username>,默认情况下用户都是root | group<groupname> | 在启动服务前将用户组切换至<groupname> | oneshot | 当此服务退出时,不要主动去重启它 | class <name> | 为该服务指定一个class名,同一个class的所有服务必须同时启动或者停止。默认情况下服务的class名是“default”。 | onrestart | 当此服务重启时,执行某些命令 | priority<priority> | 设置服务进程的优先级.优先级取值范围为-20~19,默认是0.可以通过setpriority()设置 | shutdown <shutdown_behavior> | 设置服务进程的关闭行为。如果未指定此选项,则在关闭过程中通过使用SIGTERM和SIGKILL终止服务。shutdown_behavior为"critical"时,服务在关闭期间不会被杀死,直到关闭超时为止。当服务进程关闭超时时,即使标记为"shutdown critical"的服务也将被杀死。当shutdown行为启动时,标有"shutdown critical"的服务未运行时,它将启动。 | oom_score_adjust <value> | 将子进程的/proc/self/oom_score_adj设置为指定的值,该值的范围必须为-1000到1000 | memcg.swappiness <value> | 将子进程的memory.swappiness设置为指定值(仅在安装了memcg时),该值必须等于或大于0 | writepid <file> [ <file>* ] | fork时将子进程的pid写入给定文件。 | seclabel <seclabel> | 在执行此服务之前,更改为" seclabel"。主要供rootfs运行的服务使用,例如 ueventd,adbd。系统分区上的服务可以根据其文件安全性上下文使用策略定义的转换。如果未指定并且策略中未定义任何过渡,则默认为init上下文。 | capabilities <capability> [ <capability>* ] | 执行此服务时设置功能。“capabilities"应该是不带前缀” CAP_“的Linux功能,例如” NET_ADMIN"或" SETPCAP"。请参看http://man7.org/linux/man-pages/man7/capabilities.7.html上列出的Linux功能列表。 |
综上分析发现,init.rc的语法可以用一个统一的形式来理解,如下:
on <SOMETHING-HAPPEND>
<WHAT-TO-DO>
对于Actions来说,它是当<trigger>发生时去执行命令;而对于Services来说,它是always发生的(不需要启动触发条件);然后去启动指定的可执行文件(并且由Option来限制执行条件)。
5、init.rc实例分析 下面是对高通8155-LA1.1基线代码的init.rc文件部分内容分析,通过分析进一步理解它的语法规则。源码路径:system\core\rootdir\init.rc
on init #init事件
sysclktz 0 #设置基准时间为0
# Mix device-specific information into the entropy pool
# 将设备特定信息混合到熵池中s
copy /proc/cmdline /dev/urandom #将 cmdline 复制 到 urandom 中
copy /system/etc/prop.default /dev/urandom #将 prop.default 复制 到 urandom 中
symlink /proc/self/fd/0 /dev/stdin #创建一个 /proc/self/fd/0 路径的链接,目标为 /dev/stdin , 即 标准输入
symlink /proc/self/fd/1 /dev/stdout #创建一个 /proc/self/fd/1 路径的链接,目标为 /dev/stdout ,即 标准输出
symlink /proc/self/fd/2 /dev/stderr #创建一个 /proc/self/fd/2 路径的链接,目标为 /dev/stderr , 即 标准错误
symlink /system/bin /bin #创建一个 /system/bin 路径的链接,目标为 /bin
symlink /system/etc /etc #创建一个 /system/etc 路径的链接,目标为 /etc
# Backward compatibility.
# 向后兼容性。
symlink /sys/kernel/debug /d #创建一个 /sys/kernel/debug 路径的链接,目标为 /d
# Link /vendor to /system/vendor for devices without a vendor partition.
# 对于没有供应商分区的设备,将 /vendor 链接到 /system/vendor。
symlink /system/vendor /vendor #创建一个 /system/vendor 路径的链接,目标为 /vendor
# Create energy-aware scheduler tuning nodes
# 创建能量感知调度器调优节点
mkdir /dev/stune/foreground #创建目录
mkdir /dev/stune/background #创建目录
mkdir /dev/stune/top-app #创建目录
mkdir /dev/stune/rt #创建目录
chown system system /dev/stune #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/foreground #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/background #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/top-app #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/rt #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/foreground/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/background/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/top-app/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/stune/rt/tasks #更改文件所有者为 system 和 组群为 system
chmod 0664 /dev/stune/tasks #更改文件访问权限为 0664
chmod 0664 /dev/stune/foreground/tasks #更改文件访问权限为 0664
chmod 0664 /dev/stune/background/tasks #更改文件访问权限为 0664
chmod 0664 /dev/stune/top-app/tasks #更改文件访问权限为 0664
chmod 0664 /dev/stune/rt/tasks #更改文件访问权限为 0664
# Create blkio group and apply initial settings.
# This feature needs kernel to support it, and the
# device's init.rc must actually set the correct values.
#创建 blkio 组并应用初始设置。
#此功能需要内核支持,设备的 init.rc 必须实际设置正确的值。
mkdir /dev/blkio/background #创建目录
chown system system /dev/blkio #更改文件所有者为 system 和 组群为 system
chown system system /dev/blkio/background #更改文件所有者为 system 和 组群为 system
chown system system /dev/blkio/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/blkio/background/tasks #更改文件所有者为 system 和 组群为 system
chmod 0664 /dev/blkio/tasks #更改文件访问权限为 0664
chmod 0664 /dev/blkio/background/tasks #更改文件访问权限为 0664
write /dev/blkio/blkio.weight 1000 #将 1000 写入文件 blkio.weight
write /dev/blkio/background/blkio.weight 500 #将 500 写入文件 blkio.weight
write /dev/blkio/blkio.group_idle 0 #将 0 写入文件 blkio.group_idle
write /dev/blkio/background/blkio.group_idle 0 #将 0 写入文件 blkio.group_idle
restorecon_recursive /mnt #递归的恢复<path>指出的目录树中file_contexts配置指定的安全级别。 path不要用shell可写或app可写的目录,如/data/locla/temp,/data/data,或者有类似前缀的(目录)。
mount configfs none /config nodev noexec nosuid #尝试挂载 none 到/config,none 可能有mtd@name形式,以指定名为name的mtd块设备。 <mountoption>包括 "ro", "rw", "remount", "noatime",
chmod 0770 /config/sdcardfs #更改文件访问权限为 0770
chown system package_info /config/sdcardfs #更改文件所有者为 system 和 组群为 package_info
mkdir /mnt/secure 0700 root root #创建目录 权限为0700 所有者为 root 组群为 root
mkdir /mnt/secure/asec 0700 root root #创建目录 权限为0700 所有者为 root 组群为 root
mkdir /mnt/asec 0755 root system #创建目录 权限为0755 所有者为 root 组群为 system
mkdir /mnt/obb 0755 root system #创建目录 权限为0755 所有者为 root 组群为 system
mkdir /mnt/media_rw 0750 root media_rw #创建目录 权限为0750 所有者为 root 组群为 media_rw
mkdir /mnt/user 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/user/0 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/expand 0771 system system #创建目录 权限为0771 所有者为 system 组群为 system
mkdir /mnt/appfuse 0711 root root #创建目录 权限为0711 所有者为 root 组群为 root
# Storage views to support runtime permissions
# 存储视图以支持运行时权限
mkdir /mnt/runtime 0700 root root #创建目录 权限为0700 所有者为 root 组群为 root
mkdir /mnt/runtime/default 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/runtime/default/self 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/runtime/read 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/runtime/read/self 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/runtime/write 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/runtime/write/self 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/runtime/full 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
mkdir /mnt/runtime/full/self 0755 root root #创建目录 权限为0755 所有者为 root 组群为 root
# Symlink to keep legacy apps working in multi-user world
# Symlink 让遗留应用程序在多用户世界中工作
symlink /storage/self/primary /sdcard #创建一个 /sdcard 路径的链接,目标为/storage/self/primary 类是 :ln -s /storage/self/primary /sdcard ???
symlink /storage/self/primary /mnt/sdcard
symlink /mnt/user/0/primary /mnt/runtime/default/self/primary
write /proc/sys/kernel/panic_on_oops 1 #将 1 写入文件 panic_on_oops
write /proc/sys/kernel/hung_task_timeout_secs 0 #将 0 写入文件 hung_task_timeout_secs
write /proc/cpu/alignment 4 #将 4 写入文件 alignment
# scheduler tunables
# Disable auto-scaling of scheduler tunables with hotplug. The tunables
# will vary across devices in unpredictable ways if allowed to scale with
# cpu cores.
#调度程序可调参数
#使用热插拔禁用调度程序可调参数的自动缩放。 如果允许随 cpu 内核扩展,则可调参数将以不可预测的方式因设备而异。
write /proc/sys/kernel/sched_tunable_scaling 0 #将 0 写入文件
write /proc/sys/kernel/sched_latency_ns 10000000 #将 10000000 写入文件
write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000 #将 2000000 写入文件
write /proc/sys/kernel/sched_child_runs_first 0 #将 0 写入文件
write /proc/sys/kernel/randomize_va_space 2 #将 2 写入文件
write /proc/sys/vm/mmap_min_addr 32768 #将 32768 写入文件
write /proc/sys/net/ipv4/ping_group_range "0 2147483647" #将 "0 2147483647" 写入文件
write /proc/sys/net/unix/max_dgram_qlen 600 #将 600 写入文件
write /proc/sys/kernel/sched_rt_runtime_us 950000 #将 950000 写入文件
write /proc/sys/kernel/sched_rt_period_us 1000000 #将 1000000 写入文件
# Assign reasonable ceiling values for socket rcv/snd buffers.
# These should almost always be overridden by the target per the
# the corresponding technology maximums.
#为套接字 rcv/snd 缓冲区分配合理的上限。
#根据相应的技术最大值,这些几乎总是被目标覆盖。
write /proc/sys/net/core/rmem_max 262144 #将 262144 写入文件
write /proc/sys/net/core/wmem_max 262144 #将 262144 写入文件
# reflect fwmark from incoming packets onto generated replies
# 将传入数据包中的 fwmark 反映到生成的回复上
write /proc/sys/net/ipv4/fwmark_reflect 1 #将 1 写入文件
write /proc/sys/net/ipv6/fwmark_reflect 1 #将 1 写入文件
# set fwmark on accepted sockets
# 在接受的套接字上设置 fwmark
write /proc/sys/net/ipv4/tcp_fwmark_accept 1 #将 1 写入文件
# disable icmp redirects
# 禁用 icmp 重定向
write /proc/sys/net/ipv4/conf/all/accept_redirects 0 #将 0 写入文件
write /proc/sys/net/ipv6/conf/all/accept_redirects 0 #将 0 写入文件
# /proc/net/fib_trie leaks interface IP addresses
# /proc/net/fib_trie 泄露接口 IP 地址
chmod 0400 /proc/net/fib_trie #更改文件访问权限为 0400
# Create cgroup mount points for process groups
# 为进程组创建 cgroup 挂载点
chown system system /dev/cpuctl #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuctl/tasks #更改文件所有者为 system 和 组群为 system
chmod 0666 /dev/cpuctl/tasks #更改文件访问权限为 0666
write /dev/cpuctl/cpu.rt_period_us 1000000 #将 1000000 写入文件
write /dev/cpuctl/cpu.rt_runtime_us 950000 #将 950000 写入文件
# sets up initial cpusets for ActivityManager
# this ensures that the cpusets are present and usable, but the device's
# init.rc must actually set the correct cpus
#为 ActivityManager 设置初始 cpuset
# 这确保 cpusets 存在且可用,但设备的 init.rc 必须实际设置正确的 cpus
mkdir /dev/cpuset/foreground #创建目录
copy /dev/cpuset/cpus /dev/cpuset/foreground/cpus #将 /dev/cpuset/cpus 复制 到 /dev/cpuset/foreground/cpus 中
copy /dev/cpuset/mems /dev/cpuset/foreground/mems #将 /dev/cpuset/mems 复制 到 /dev/cpuset/foreground/mems 中
mkdir /dev/cpuset/background #创建目录
copy /dev/cpuset/cpus /dev/cpuset/background/cpus #将 /dev/cpuset/cpus 复制 到 /dev/cpuset/background/cpus 中
copy /dev/cpuset/mems /dev/cpuset/background/mems #将 /dev/cpuset/mems 复制 到 /dev/cpuset/background/mems 中
# system-background is for system tasks that should only run on
# little cores, not on bigs
# to be used only by init, so don't change system-bg permissions
# system-background 用于仅应在小内核上运行的系统任务,而不是仅由 init 使用的大内核,因此不要更改 system-bg 权限
mkdir /dev/cpuset/system-background #创建目录
copy /dev/cpuset/cpus /dev/cpuset/system-background/cpus #将 /dev/cpuset/cpus 复制 到 /dev/cpuset/system-background/cpus 中
copy /dev/cpuset/mems /dev/cpuset/system-background/mems #将 /dev/cpuset/mems 复制 到 /dev/cpuset/system-background/mems 中
# restricted is for system tasks that are being throttled
# due to screen off.
#受限用于因屏幕关闭而受到限制的系统任务。
mkdir /dev/cpuset/restricted #创建目录
copy /dev/cpuset/cpus /dev/cpuset/restricted/cpus #将 /dev/cpuset/cpus 复制 到 /dev/cpuset/restricted/cpus 中
copy /dev/cpuset/mems /dev/cpuset/restricted/mems #将 /dev/cpuset/mems 复制 到 /dev/cpuset/restricted/mems 中
mkdir /dev/cpuset/top-app #创建目录
copy /dev/cpuset/cpus /dev/cpuset/top-app/cpus #将 /dev/cpuset/cpus 复制 到 /dev/cpuset/top-app/cpus 中
copy /dev/cpuset/mems /dev/cpuset/top-app/mems #将 /dev/cpuset/mems 复制 到 /dev/cpuset/top-app/mems 中
# change permissions for all cpusets we'll touch at runtime
# 更改我们将在运行时接触的所有 cpuset 的权限
chown system system /dev/cpuset #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/foreground #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/background #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/system-background #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/top-app #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/restricted #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/foreground/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/background/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/system-background/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/top-app/tasks #更改文件所有者为 system 和 组群为 system
chown system system /dev/cpuset/restricted/tasks #更改文件所有者为 system 和 组群为 system
# set system-background to 0775 so SurfaceFlinger can touch it
# 将系统背景设置为 0775,以便 SurfaceFlinger 可以触摸它
chmod 0775 /dev/cpuset/system-background #更改文件访问权限为 0775
chmod 0664 /dev/cpuset/foreground/tasks #更改文件访问权限为 0664
chmod 0664 /dev/cpuset/background/tasks #更改文件访问权限为 0664
chmod 0664 /dev/cpuset/system-background/tasks #更改文件访问权限为 0664
chmod 0664 /dev/cpuset/top-app/tasks #更改文件访问权限为 0664
chmod 0664 /dev/cpuset/restricted/tasks #更改文件访问权限为 0664
chmod 0664 /dev/cpuset/tasks #更改文件访问权限为 0664
# make the PSI monitor accessible to others
# 让其他人可以访问 PSI 监视器
chown system system /proc/pressure/memory #更改文件所有者为 system 和 组群为 system
chmod 0664 /proc/pressure/memory #更改文件访问权限为 0664
# qtaguid will limit access to specific data based on group memberships.
# net_bw_acct grants impersonation of socket owners.
# net_bw_stats grants access to other apps' detailed tagged-socket stats.
# qtaguid 将根据组成员限制对特定数据的访问。
# net_bw_acct 允许模拟套接字所有者。
# net_bw_stats 允许访问其他应用程序的详细标记套接字统计信息。
chown root net_bw_acct /proc/net/xt_qtaguid/ctrl #更改文件所有者为 root 和 组群为 net_bw_acct
chown root net_bw_stats /proc/net/xt_qtaguid/stats #更改文件所有者为 root 和 组群为 net_bw_stats
# Allow everybody to read the xt_qtaguid resource tracking misc dev.
# This is needed by any process that uses socket tagging.
# 允许所有人阅读 xt_qtaguid 资源跟踪 misc dev。
# 这是任何使用套接字标记的进程都需要的。
chmod 0644 /dev/xt_qtaguid #更改文件访问权限为 0644
chown root root /dev/cg2_bpf #更改文件所有者为 root 和 组群为 root
chmod 0600 /dev/cg2_bpf #更改文件访问权限为 0600
mount bpf bpf /sys/fs/bpf nodev noexec nosuid #尝试挂载 bpf 到/sys/fs/bpf
# Create location for fs_mgr to store abbreviated output from filesystem
# checker programs.
# 为 fs_mgr 创建位置以存储文件系统检查程序的缩写输出。
mkdir /dev/fscklogs 0770 root system #创建目录 权限为 0770 所有者为 root 组群为 system
# pstore/ramoops previous console log
# pstore/ramoops 以前的控制台日志
mount pstore pstore /sys/fs/pstore nodev noexec nosuid #尝试挂载 pstore 到/sys/fs/pstore
chown system log /sys/fs/pstore #更改文件所有者为 system 和 组群为 log
chmod 0550 /sys/fs/pstore #更改文件访问权限为 0550
chown system log /sys/fs/pstore/console-ramoops #更改文件所有者为 system 和 组群为 log
chmod 0440 /sys/fs/pstore/console-ramoops #更改文件访问权限为 0440
chown system log /sys/fs/pstore/console-ramoops-0 #更改文件所有者为 system 和 组群为 log
chmod 0440 /sys/fs/pstore/console-ramoops-0 #更改文件访问权限为 0440
chown system log /sys/fs/pstore/pmsg-ramoops-0 #更改文件所有者为 system 和 组群为 log
chmod 0440 /sys/fs/pstore/pmsg-ramoops-0 #更改文件访问权限为 0440
# enable armv8_deprecated instruction hooks
# 启用 armv8_deprecated 指令挂钩
write /proc/sys/abi/swp 1 #将 1 写入文件
# Linux's execveat() syscall may construct paths containing /dev/fd
# expecting it to point to /proc/self/fd
# Linux 的 execveat() 系统调用可能会构建包含 /dev/fd 的路径,期望它指向 /proc/self/fd
symlink /proc/self/fd /dev/fd #创建一个 /dev/fd 路径的链接,目标为/proc/self/fd
export DOWNLOAD_CACHE /data/cache #设置环境变量 DOWNLOAD_CACHE 的值为 /data/cache
# set RLIMIT_NICE to allow priorities from 19 to -20
# 设置 RLIMIT_NICE 以允许从 19 到 -20 的优先级
setrlimit nice 40 40 #设置一种资源 nice 的使用限制,这个概念亦存在与Linux系统中,40 表示软限制, 40 表示硬限制
# Allow up to 32K FDs per process
# 每个进程最多允许 32K FD
setrlimit nofile 32768 32768 #设置一种资源 nofile 的使用限制,这个概念亦存在与Linux系统中,32768 表示软限制, 32768 表示硬限制
# This allows the ledtrig-transient properties to be created here so
# that they can be chown'd to system:system later on boot
# 这允许在此处创建 ledtrig-transient 属性,以便稍后在启动时将它们更改为 system:system
write /sys/class/leds/vibrator/trigger "transient" #将 "transient" 写入文件
# This is used by Bionic to select optimized routines.
# 这被 Bionic 用来选择优化的例程。
write /dev/cpu_variant:${ro.bionic.arch} ${ro.bionic.cpu_variant} #将 ${ro.bionic.cpu_variant} 写入文件
chmod 0444 /dev/cpu_variant:${ro.bionic.arch} #更改文件访问权限为 0444
write /dev/cpu_variant:${ro.bionic.2nd_arch} ${ro.bionic.2nd_cpu_variant} #将 ${ro.bionic.2nd_cpu_variant} 写入文件
chmod 0444 /dev/cpu_variant:${ro.bionic.2nd_arch} #更改文件访问权限为 0444
# Allow system processes to read / write power state.
# 允许系统进程读/写电源状态。
chown system system /sys/power/state #更改文件所有者为 system 和 组群为 system
chown system system /sys/power/wakeup_count #更改文件所有者为 system 和 组群为 system
chmod 0660 /sys/power/state #更改文件访问权限为 0660
# Start logd before any other services run to ensure we capture all of their logs.
# 在任何其他服务运行之前启动 logd 以确保我们捕获它们的所有日志。
start logd # 这个命令将启动一个服务 logd ,如果它没有处于运行状态的话
# Start essential services.
# 启动基本服务。
start servicemanager # 这个命令将启动一个服务 servicemanager ,如果它没有处于运行状态的话
start hwservicemanager # 这个命令将启动一个服务 hwservicemanager ,如果它没有处于运行状态的话
start vndservicemanager # 这个命令将启动一个服务 vndservicemanager ,如果它没有处于运行状态的话
# Healthd 可以通过在按住电源按钮时发出此属性信号来触发从充电器模式完全启动。
on property:sys.boot_from_charger_mode=1 # property 事件 并且 属性值sys.boot_from_charger_mode=1 才会产生事件
class_stop charger #停止由 charger 类指定的服务,如果它们正在运行状态的话
trigger late-init #触发一个事件 late-init
on load_persist_props_action # load_persist_props_action 事件
load_persist_props # 定义在property_service.cpp
start logd #这个命令将启动一个服务 logd ,如果它没有处于运行状态的话
start logd-reinit #这个命令将启动一个服务 logd-reinit ,如果它没有处于运行状态的话
# Indicate to fw loaders that the relevant mounts are up.
# 向 fw 加载器指示相关的挂载已启动。
on firmware_mounts_complete # firmware_mounts_complete 事件
rm /dev/.booting # 删除文件
# Mount filesystems and start core system services.
# 挂载文件系统并启动核心系统服务。
on late-init # late-init 事件
trigger early-fs #触发一个事件 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.
# 通过 mount_all 命令在 init.{$device}.rc 中挂载 fstab。
# 可以指定可选参数“--early”以跳过带有“latemount”的条目。
# /system 和 /vendor 必须在 fs 阶段结束时挂载,而 /data 是可选的。
trigger fs #触发一个事件 fs
trigger post-fs #触发一个事件 post-fs
.
.
.
.
on boot #boot事件
# basic network init
ifup lo #基本网络初始化,即建立lo网络连接
hostname localhost #设置主机名
domainname localdomain #设置域名
# IPsec SA default expiration length
write /proc/sys/net/core/xfrm_acq_expires 3600 #IPsec SA 默认到期长度3600 写入文件 xfrm_acq_expires
# Memory management. Basic kernel parameters, and allow the high
# level system server to be able to adjust the kernel OOM driver
# parameters to match how it is managing things.
#内存管理。 基本内核参数,并允许高级系统服务器能够调整内核 OOM 驱动程序参数以匹配它管理事物的方式。
write /proc/sys/vm/overcommit_memory 1 #将 1 写入文件 overcommit_memory
write /proc/sys/vm/min_free_order_shift 4 #将 4 写入文件 min_free_order_shift
chown root system /sys/module/lowmemorykiller/parameters/adj #更改文件所有者为root 和 组群为system
chmod 0664 /sys/module/lowmemorykiller/parameters/adj #更改文件访问权限为0664
chown root system /sys/module/lowmemorykiller/parameters/minfree #更改文件所有者为root 和 组群为system
chmod 0664 /sys/module/lowmemorykiller/parameters/minfree #更改文件访问权限为0664
# System server manages zram writeback
系统服务器管理 zram 回写
chown root system /sys/block/zram0/idle #更改文件所有者为root 和 组群为system
chmod 0664 /sys/block/zram0/idle #更改文件访问权限为0664
chown root system /sys/block/zram0/writeback #更改文件所有者为root 和 组群为system
chmod 0664 /sys/block/zram0/writeback #更改文件访问权限为0664
# Tweak background writeout
#调整背景写出
write /proc/sys/vm/dirty_expire_centisecs 200 #将 200 写入文件 dirty_expire_centisecs
write /proc/sys/vm/dirty_background_ratio 5 #将 5 写入文件 dirty_background_ratio
# F2FS tuning. Set cp_interval larger than dirty_expire_centisecs
# to avoid power consumption when system becomes mostly idle. Be careful
# to make it too large, since it may bring userdata loss, if they
# are not aware of using fsync()/sync() to prepare sudden power-cut.
#F2FS 调优。 将 cp_interval 设置为大于dirty_expire_centisecs 以避免系统大部分空闲时的功耗。
#小心让它太大,因为它可能会带来用户数据丢失,如果他们不知道使用 fsync()/sync() 来准备突然断电。
write /sys/fs/f2fs/${dev.mnt.blk.data}/cp_interval 200 #将 200 写入文件 cp_interval
write /sys/fs/f2fs/${dev.mnt.blk.data}/gc_urgent_sleep_time 50 #将 50 写入文件 gc_urgent_sleep_time
# limit discard size to 128MB in order to avoid long IO latency
# for filesystem tuning first (dm or sda)
# Note that, if dm-<num> is used, sda/mmcblk0 should be tuned in vendor/init.rc
#将丢弃大小限制为 128MB,以避免首先调整文件系统(dm 或 sda)的长 IO 延迟
#注意,如果使用 dm-<num>,则应在 vendor/init.rc 中调整 sda/mmcblk0
write /sys/devices/virtual/block/${dev.mnt.blk.data}/queue/discard_max_bytes 134217728 #将 134217728 写入文件 discard_max_bytes
# Permissions for System Server and daemons.
#系统服务器和守护程序的权限。
chown radio system /sys/android_power/state #更改文件所有者为radio 和 组群为system
chown radio system /sys/android_power/request_state #更改文件所有者为radio 和 组群为system
chown radio system /sys/android_power/acquire_full_wake_lock #更改文件所有者为radio 和 组群为system
chown radio system /sys/android_power/acquire_partial_wake_lock #更改文件所有者为radio 和 组群为system
chown radio system /sys/android_power/release_wake_lock #更改文件所有者为radio 和 组群为system
chown system system /sys/power/autosleep #更改文件所有者为system 和 组群为system
chown radio wakelock /sys/power/wake_lock #更改文件所有者为radio 和 组群为system
chown radio wakelock /sys/power/wake_unlock #更改文件所有者为radio 和 组群为system
chmod 0660 /sys/power/wake_lock #更改文件访问权限为0660
chmod 0660 /sys/power/wake_unlock #更改文件访问权限为0660
chown system system /sys/devices/system/cpu/cpufreq/interactive/timer_rate #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/timer_rate #更改文件访问权限为0664
chown system system /sys/devices/system/cpu/cpufreq/interactive/timer_slack #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/timer_slack #更改文件访问权限为0664
chown system system /sys/devices/system/cpu/cpufreq/interactive/min_sample_time #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/min_sample_time #更改文件访问权限为0664
chown system system /sys/devices/system/cpu/cpufreq/interactive/hispeed_freq #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/hispeed_freq #更改文件访问权限为0660
chown system system /sys/devices/system/cpu/cpufreq/interactive/target_loads #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/target_loads #更改文件访问权限为0660
chown system system /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load #更改文件访问权限为0660
chown system system /sys/devices/system/cpu/cpufreq/interactive/above_hispeed_delay #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/above_hispeed_delay #更改文件访问权限为0660
chown system system /sys/devices/system/cpu/cpufreq/interactive/boost #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/boost #更改文件访问权限为0660
chown system system /sys/devices/system/cpu/cpufreq/interactive/boostpulse #更改文件所有者为system 和 组群为system
chown system system /sys/devices/system/cpu/cpufreq/interactive/input_boost #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/input_boost #更改文件访问权限为0660
chown system system /sys/devices/system/cpu/cpufreq/interactive/boostpulse_duration #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/boostpulse_duration #更改文件访问权限为0660
chown system system /sys/devices/system/cpu/cpufreq/interactive/io_is_busy #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/io_is_busy #更改文件访问权限为0660
# Assume SMP uses shared cpufreq policy for all CPUs
#假设 SMP 对所有 CPU 使用共享 cpufreq 策略
chown system system /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq #更改文件所有者为system 和 组群为system
chmod 0660 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq #更改文件访问权限为0660
chown system system /sys/class/leds/vibrator/trigger #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/vibrator/activate #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/vibrator/brightness #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/vibrator/duration #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/vibrator/state #更改文件所有者为system 和 组群为system
chown system system /sys/class/timed_output/vibrator/enable #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/keyboard-backlight/brightness #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/lcd-backlight/brightness #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/button-backlight/brightness #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/jogball-backlight/brightness #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/red/brightness #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/green/brightness #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/blue/brightness #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/red/device/grpfreq #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/red/device/grppwm #更改文件所有者为system 和 组群为system
chown system system /sys/class/leds/red/device/blink #更改文件所有者为system 和 组群为system
chown system system /sys/module/sco/parameters/disable_esco #更改文件所有者为system 和 组群为system
chown system system /sys/kernel/ipv4/tcp_wmem_min #更改文件所有者为system 和 组群为system
chown system system /sys/kernel/ipv4/tcp_wmem_def #更改文件所有者为system 和 组群为system
chown system system /sys/kernel/ipv4/tcp_wmem_max #更改文件所有者为system 和 组群为system
chown system system /sys/kernel/ipv4/tcp_rmem_min #更改文件所有者为system 和 组群为system
chown system system /sys/kernel/ipv4/tcp_rmem_def #更改文件所有者为system 和 组群为system
chown system system /sys/kernel/ipv4/tcp_rmem_max #更改文件所有者为system 和 组群为system
chown root radio /proc/cmdline #更改文件所有者为root 和 组群为radio
# Define default initial receive window size in segments.
# 以段为单位定义默认的初始接收窗口大小。
setprop net.tcp.default_init_rwnd 60 #设置 系统属性 net.tcp.default_init_rwnd 的值为 60
# Start standard binderized HAL daemons
# 启动标准绑定 HAL 守护进程
class_start hal #启动由 hal 类指定的所有相关服务,如果它们不在运行状态的话
class_start core #启动由 core 类指定的所有相关服务,如果它们不在运行状态的话
总结:以上主要通过init.rc的实际源码,对比脚本组成部分声明类型,做详细的使用分析。各设备厂商根据自身设备的定制要求,可以编写特定设备的init.rc文件。
后续将继续分析具体启动流程…
|