Android系統啟動:.rc文件
reference : https://www.jianshu.com/p/a4c17f0110d0
以init.rc為例。
.rc文件
init.rc文件由系統第一個啟動的init程序解析。是啟動系統服務使用的文件。
rc規則主要包含了四種類型的語句:
- Action
- Commands
- Services
- Options.
Action和services顯式聲明了一個語句塊,而commands和options屬於最近聲明的語句塊。
在第一個語句塊之前 的commands和options會被忽略.
基本規則如下(基本上與bash語法一樣):
注釋是以
#
開頭。在init.rc文件中一條語句通常是占據一行.
單詞之間是通過空格符來相隔的.如果需要在單詞內使用空格,那么得使用轉義字符"",
如果在一行的末尾有一個反斜杠,那么是換行折疊符號,應該和下一行合並成一起來處理,與C語言中的含義是一致的。
關鍵字
關鍵字 | 含義 |
---|---|
token | 在計算機身份認證中是令牌(臨時)的意思,在詞法分析中是標記的意思。一般作為邀請、登錄系統使用。 |
Section | 語句塊,相當於C語言中大括號內的一個塊。一個Section以Service或On開頭. 以Service開頭的Section叫做服務 而以On開頭的叫做動作(Action). |
services | 服務 |
Action | 動作 |
commands | 命令 |
options | 選項 |
trigger | 觸發條件 |
class | 類屬,即能夠為多個service指定一個同樣的類屬,方便操作同一時候啟動或停止. |
Action(動作)
動作表示了一組命令(commands)組成.動作包括一個觸發器,決定了何時運行這個動作。
注意:當觸發器的條件滿足時,這個動作會被增加到已被運行的隊列尾。假設此動作在隊列中已經存在,那么它將不會運行.
一個動作所包括的命令將被依次運行。
on <trigger> ## 觸發條件
<command> ##執行命令
<command1> ##可以執行多個命令
trigger(觸發器)
在"動作"(action)里面的,on后面跟着的字符串是觸發器(trigger),trigger是一個用於匹配某種事件類型的字符串,它將對應的Action的執行。
觸發器(trigger)有幾種格式:
1、最簡單的一種是一個單純的字符串。比如“on boot”。這種簡單的格式可以使用命令"trigger"來觸發。
2、還有一種常見的格式是"on property<屬性>=<值>"。如果屬性值在運行時設成了指定的值,則"塊"(action)中的命令列表就會執行。
常見的格式:
格式 | 含義 |
---|---|
on early-init | 在初始化早期階段觸發 |
on init | 在初始化階段觸發 |
on late-init | 在初始化晚期階段觸發 |
on boot/charger | 當系統啟動/充電時觸發 |
on property | 當屬性值滿足條件時觸發 |
例如:
on property:vendor.sys.boot_mode=normal
write ${persist.vendor.mmi.misc_dev_path} "normal"
on boot
chown bluetooth bluetooth /sys/module/bluetooth_power/parameters/power
chown bluetooth net_bt /sys/class/rfkill/rfkill0/type
chown bluetooth net_bt /sys/class/rfkill/rfkill0/state
chown bluetooth bluetooth /proc/bluetooth/sleep/proto
commands(命令)
command是action的命令列表中的命令,或者是service中的選項 onrestart 的參數命令.
命令將在所屬事件發生時被一個個地執行.
常見命令:
命令 | 描寫敘述 |
---|---|
exec <path> [ <argument> ]* |
運行指定路徑下的程序,並傳遞參數 |
export <name> <value> |
設置全局環境參數。此參數被設置后對全部進程都有效 |
ifup <interface> |
使指定的網絡接口"上線",相當激活指定的網絡接口 |
import <filename> |
導入一個額外的init配置文件 |
hostname <name> |
設置主機名 |
chdir <directory> |
改變工作文件夾 |
chmod <octal-mode> <path> |
改變指定文件的讀取權限 |
chown <owner> <group> <path> |
改變指定文件的擁有都和組名的屬性 |
chroot <directory> |
改變進行的根文件夾 |
`class_start
|
啟動指定類屬的全部服務,假設服務已經啟動,則不再反復啟動 |
class_stop <serviceclass> |
停止指定類屬的所有服務 |
domainname <name> |
設置域名 |
insmod <path> |
安裝模塊到指定路徑 |
mkdir <path> [mode] [owner] [group] |
用指定參數創建一個文件夾,在默認情況下,創建的文件夾讀取權限為755 username為root,組名為root. |
mount <type> <device> <dir> [ <mountoption> ]* |
類似於linux的mount指令 |
setkey TBD(To Be Determined), |
待定 |
setprop <name> <value> |
設置屬性及相應的值 |
setrlimit <resource> <cur> <max> |
設置資源的rlimit(資源限制),不懂就百度一下rlimit |
start <service> |
假設指定的服務未啟動,則啟動它 |
stop <service> |
假設指定的服務當前正在執行,則停止它 |
symlink <target> <path> |
創建一個符號鏈接 |
sysclktz <mins_west_of_gmt> |
設置系統基准時間 |
trigger <event> |
觸發一個事件,Used to queue an action from another action. |
write <path> <string> [ <string> ]* |
往指定的文件寫字符串 |
services(服務)
服務是指那些須要在系統初始化時就啟動或退出時自己主動重新啟動的程序
service <name><pathname> [ <argument> ]*
<option>
<option>
解釋一下各個參數:
參數 | 含義 |
---|---|
name | 表示此服務的名稱 |
pathname | 此服務所在路徑因為是可執行文件,所以一定有存儲路徑。 |
argument | 啟動服務所帶的參數 |
option | 對此服務的約束選項 |
option(選項)
options是Service的修訂項。它們決定一個服務何時以及如何運行.
選項 | 描述 | |
---|---|---|
critical | 據設備相關的關鍵服務,如果在4分鍾內,此服務重復啟動了4次,那么設備將會重啟進入還原模式。 | |
disabled | 服務不會自動運行,必須顯式地通過服務器來啟動。 | |
setenv | 設置環境變量 | |
socket [ [ ] ] | 在/dev/socket/下創建一個unix domain的socket,並傳遞創建的文件描述符fd給服務進程.其中type必須為dgram或stream,seqpacket. | 用戶名和組名默認為0 |
user | 在執行此服務之前先切換用戶名。當前默認為root. | |
group [ ]* | 類似於user,切換組名 | |
oneshot | 當此服務退出時不會自動重啟. | |
class | 給服務指定一個類屬,這樣方便操作多個服務同時啟動或停止.默認情況下為default. | |
onrestart | 當服務重啟時執行一條指令, |
使用例子:
service bootanim /system/bin/bootanimation
class core //給服務指定一個類屬,這樣方便操作多個服務同時啟動或停止
user graphics //在執行此服務之前先切換用戶名
group graphics audio
disabled //服務不會自動運行
oneshot //當此服務退出時不會自動重啟
rc文件實例
# not complete -- just providing some examples of usage
#
on boot
export PATH /sbin:/system/sbin:/system/bin
export LD_LIBRARY_PATH /system/lib
mkdir /dev
mkdir /proc
mkdir /sys
mount tmpfs tmpfs /dev
mkdir /dev/pts
mkdir /dev/socket
mount devpts devpts /dev/pts
mount proc proc /proc
mount sysfs sysfs /sys
write /proc/cpu/alignment 4
ifup lo
hostname localhost
domainname localhost
mount yaffs2 mtd@system /system
mount yaffs2 mtd@userdata /data
import /system/etc/init.conf
class_start default
service adbd /sbin/adbd
user adb
group adb
service usbd /system/bin/usbd -r
user usbd
group usbd
socket usbd 666
service zygote /system/bin/app_process -Xzygote /system/bin --zygote
socket zygote 666
service runtime /system/bin/runtime
user system
group system
on device-added-/dev/compass
start akmd
on device-removed-/dev/compass
stop akmd
service akmd /sbin/akmd
disabled
user akmd
group akmd
rc文件解析
源碼路徑system/core/init/init.cpp
中:
parser.ParseConfig("/init.rc");
開始解析rc文件.
ParseConfig函數在文件core/init/init_parser.cpp
140行:
bool Parser::ParseConfig(const std::string& path) {
if (is_dir(path.c_str())) {
return ParseConfigDir(path);
}
return ParseConfigFile(path);
}
ParseConfigFile函數:
bool Parser::ParseConfigFile(const std::string& path) {
LOG(INFO) << "Parsing file " << path << "...";
Timer t;
std::string data;
if (!read_file(path, &data)) {
return false;
}
data.push_back('\n'); // TODO: fix parse_config.
ParseData(path, data);
for (const auto& sp : section_parsers_) {
sp.second->EndFile(path);
}
LOG(VERBOSE) << "(Parsing " << path << " took " << t << ".)";
return true;
}