Android系統(tǒng)啟動之init.rc文件解析過程

image.png

目錄

第一篇:Android系統(tǒng)啟動之bootloader
第二篇:Android系統(tǒng)啟動之Init流程(上)
第三篇:Android系統(tǒng)啟動之Init流程(下)
第四篇:Android系統(tǒng)啟動之init.rc文件解析過程
第五篇:Android系統(tǒng)啟動之zyogte進(jìn)程
第六篇:Android系統(tǒng)啟動之zyogte進(jìn)程java(上)
第七篇:Android系統(tǒng)啟動之zyogte進(jìn)程java(下)
第八篇:Android系統(tǒng)啟動之SystemServer

什么是init.rc

Android init.rc文件由系統(tǒng)第一個啟動的init程序解析。是啟動系統(tǒng)服務(wù)使用的文件。

rc規(guī)則

主要包含了四種類型的語句:

  1. Action
  2. Commands
  3. Services
  4. Options.

Action和services顯式聲明了一個語句塊,而commands和options屬于最近聲明的語句塊。

在第一個語句塊之前 的commands和options會被忽略.

基本規(guī)則如下:

在init.rc文件中一條語句通常是占據(jù)一行.
單詞之間是通過空格符來相隔的.
如果需要在單詞內(nèi)使用空格,那么得使用轉(zhuǎn)義字符"",如果在一行的末尾有一個反斜杠,那么是換行折疊符號,應(yīng)該和下一行合并成一起來處理,與C語言中的含義是一致的。
注釋是以#號開頭。

關(guān)鍵字

關(guān)鍵字 含義
token 計(jì)算機(jī)語言中的一個單詞,就跟英文中的單詞幾乎相同一人概念.
Section 語句塊,相當(dāng)于C語言中大括號內(nèi)的一個塊。一個Section以Service或On開頭的語句塊.以Service開頭的Section叫做服務(wù),而以O(shè)n開頭的叫做動作(Action).
services 服務(wù).
Action 動作
commands 命令.
options 選項(xiàng).
trigger 觸發(fā)器?;蛘呓凶鲇|發(fā)條件.
class 類屬,即能夠?yàn)槎鄠€service指定一個同樣的類屬,方便操作同一時候啟動或停止.

動作(Action)

動作表示了一組命令(commands)組成.動作包括一個觸發(fā)器,決定了何時運(yùn)行這個動作。

注意:當(dāng)觸發(fā)器的條件滿足時,這個動作會被增加到已被運(yùn)行的隊(duì)列尾。假設(shè)此動作在隊(duì)列中已經(jīng)存在,那么它將不會運(yùn)行.

一個動作所包括的命令將被依次運(yùn)行。

on  <trigger>      ## 觸發(fā)條件
    <command>      ##執(zhí)行命令
    <command1>     ##可以執(zhí)行多個命令

觸發(fā)器(trigger)

在"動作"(action)里面的,on后面跟著的字符串是觸發(fā)器(trigger),trigger是一個用于匹配某種事件類型的字符串,它將對應(yīng)的Action的執(zhí)行。

觸發(fā)器(trigger)有幾種格式:

1、最簡單的一種是一個單純的字符串。比如“on boot”。這種簡單的格式可以使用命令"trigger"來觸發(fā)。
2、還有一種常見的格式是"on property<屬性>=<值>"。如果屬性值在運(yùn)行時設(shè)成了指定的值,則"塊"(action)中的命令列表就會執(zhí)行。

常見的格式:

格式 含義
on early-init 在初始化早期階段觸發(fā)
on init 在初始化階段觸發(fā)
on late-init 在初始化晚期階段觸發(fā)
on boot/charger 當(dāng)系統(tǒng)啟動/充電時觸發(fā)
on property 當(dāng)屬性值滿足條件時觸發(fā)

commands(命令)

command是action的命令列表中的命令,或者是service中的選項(xiàng) onrestart 的參數(shù)命令.

命令將在所屬事件發(fā)生時被一個個地執(zhí)行.

常見命令:

命令 描寫敘述
exec <path> [ <argument> ]* 運(yùn)行指定路徑下的程序,并傳遞參數(shù).
export <name> <value> 設(shè)置全局環(huán)境參數(shù)。此參數(shù)被設(shè)置后對全部進(jìn)程都有效.
ifup <interface> 使指定的網(wǎng)絡(luò)接口"上線",相當(dāng)激活指定的網(wǎng)絡(luò)接口
import <filename> 導(dǎo)入一個額外的init配置文件.
hostname <name> 設(shè)置主機(jī)名
chdir <directory> 改變工作文件夾.
chmod <octal-mode> <path> 改變指定文件的讀取權(quán)限.
chown <owner> <group> <path> 改變指定文件的擁有都和組名的屬性.
chroot <directory> 改變進(jìn)行的根文件夾.
class_start <serviceclass> 啟動指定類屬的全部服務(wù),假設(shè)服務(wù)已經(jīng)啟動,則不再反復(fù)啟動.
class_stop <serviceclass> 停止指定類屬的所胡服務(wù).
domainname <name> 設(shè)置域名
insmod <path> 安裝模塊到指定路徑.
mkdir <path> [mode] [owner] [group] 用指定參數(shù)創(chuàng)建一個文件夾,在默認(rèn)情況下,創(chuàng)建的文件夾讀取權(quán)限為755.username為root,組名為root.
mount <type> <device> <dir> [ <mountoption> ]* 類似于linux的mount指令
setkey TBD(To Be Determined), 待定.
setprop <name> <value> 設(shè)置屬性及相應(yīng)的值.
setrlimit <resource> <cur> <max> 設(shè)置資源的rlimit(資源限制),不懂就百度一下rlimit
start <service> 假設(shè)指定的服務(wù)未啟動,則啟動它.
stop <service> 假設(shè)指定的服務(wù)當(dāng)前正在執(zhí)行。則停止它.
symlink <target> <path> 創(chuàng)建一個符號鏈接.
sysclktz <mins_west_of_gmt> 設(shè)置系統(tǒng)基準(zhǔn)時間.
trigger <event> Trigger an event. Used to queue an action from another action. 這名話沒有理解,望高手指點(diǎn).
write <path> <string> [ <string> ]* 往指定的文件寫字符串.

服務(wù)(services)

服務(wù)是指那些須要在系統(tǒng)初始化時就啟動或退出時自己主動重新啟動的程序.

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

解釋一下各個參數(shù):

參數(shù) 含義
<name> 表示此服務(wù)的名稱
<pathname> 此服務(wù)所在路徑因?yàn)槭强蓤?zhí)行文件,所以一定有存儲路徑。
<argument> 啟動服務(wù)所帶的參數(shù)
<option> 對此服務(wù)的約束選項(xiàng)

選項(xiàng)(option)

options是Service的修訂項(xiàng)。它們決定一個服務(wù)何時以及如何運(yùn)行.

選項(xiàng) 描述
critical 據(jù)設(shè)備相關(guān)的關(guān)鍵服務(wù),如果在4分鐘內(nèi),此服務(wù)重復(fù)啟動了4次,那么設(shè)備將會重啟進(jìn)入還原模式。
disabled 服務(wù)不會自動運(yùn)行,必須顯式地通過服務(wù)器來啟動。
setenv 設(shè)置環(huán)境變量
socket [ [ ] ] 在/dev/socket/下創(chuàng)建一個unix domain的socket,并傳遞創(chuàng)建的文件描述符fd給服務(wù)進(jìn)程.其中type必須為dgram或stream,seqpacket. 用戶名和組名默認(rèn)為0
user 在執(zhí)行此服務(wù)之前先切換用戶名。當(dāng)前默認(rèn)為root.
group [ ]* 類似于user,切換組名
oneshot 當(dāng)此服務(wù)退出時不會自動重啟.
class 給服務(wù)指定一個類屬,這樣方便操作多個服務(wù)同時啟動或停止.默認(rèn)情況下為default.
onrestart 當(dāng)服務(wù)重啟時執(zhí)行一條指令,

使用例子:

service bootanim /system/bin/bootanimation
    class core  //給服務(wù)指定一個類屬,這樣方便操作多個服務(wù)同時啟動或停止
    user graphics //在執(zhí)行此服務(wù)之前先切換用戶名
    group graphics audio
    disabled  //服務(wù)不會自動運(yùn)行
    oneshot  //當(dāng)此服務(wù)退出時不會自動重啟

rc文件實(shí)例

# 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函數(shù)在文件core/init/init_parser.cpp140行:

bool Parser::ParseConfig(const std::string& path) {
    if (is_dir(path.c_str())) {
        return ParseConfigDir(path);
    }
    return ParseConfigFile(path);
}

ParseConfigFile函數(shù):

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;
}

參考

Android init.rc文件淺析
安卓系統(tǒng)啟動--3init.rc解析
init.rc深入學(xué)習(xí)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容