來源:https://www.2cto.com/kf/201312/262252.html
對於android系統的學習掌握,除了對一些語言基礎的要求,如C,C++,java,shell,makefile等,更要整體去把握系統的架構。對於架構的熟悉入門,首先應該分析android的編譯系統結構。而對於系統的啟動流程的掌握,最好是深入分析init.rc、init.xx.rc等文件。這些文件相對來說代碼量少,比較簡單,而且對系統的整體認識有很大的幫助。以前在工作中經常要用到init.rc相關的知識,但是沒有系統的去分析整體,最近寫成了筆記,分享出來!
關於init.rc的幾點說明:
1).在android源碼目錄下面jb\system\core\init\readme.txt文件中有init.rc語法的詳細定義
注意:readme.txt沒有和android的版本一起更新,所以在新版本的android中,增加了一些commands、options等,在readme.txt中 沒有介紹。 還是看init目錄下面的源碼最為準確
2).解析init.rc,init.xx.rc的相關文件目錄system/core/init/
3).init.c 、init.rc init.xx.rc 等最終會編譯到ramdisk.img(根文件系統)中,和kernel一起打包成boot.img。android啟動後每次都會從boot.img中解壓出init.c等文件到內存,所以要修改必須修改替換boot.img。
4).在init.rc中啟動的服務,都是以一個進程的形式運行,屬於android的本地服務。通過在終端輸入PS命令可以查看在運行的相應進程,他們的ppid都為1,代表init進程。 init進程也是android系統啟動的第一個應用進程
5).init.rc中所有的語句都是以行為單位的(每個語句都是單獨寫在一行裡面)
6).註釋行以「#」開頭
7).Actions 和 Services表示一個新的段落section的開始。
所有的commands和options 都是歸屬於上方最近的一個段落。在第一個段落之前的commands和options是無效的。
8).Actions and Services
不能重名,如果重名,後面的定義會被忽略(readme.txt說明)。
但是實際項目中同一個init.xx.rc中有重名的action,也可以正常使用。多個init.xx.rc中action也允許有重名, 比如 boot,init 等在多個rc文件中出現。services應該不能重名
init.rc (Android Init Language)語法詳解:
1.init語法的四個組成原件:
Actions :動作 ,使用格式: on ,下面行跟各種command
Commands :命令
Services :服務 使用格式 : service [ ]* ,下面行可以添加Options
Options : 選項
2.init.rc中三大模塊:
1). import 導入其他的init.xx.rc文件。
2). 以action動作為觸發點的一系列命令
3). 帶有各種Options的一系列services的定義
import /init.${ro.hardware}.rc
通過cat proc/cpuinfo可以查看ro.hardware的值=Hardware的值
on //action 模型
....
service [ ]* (services可以帶有多個參數和選項)
...
3.對Actions官方描述的一些理解 :
當action的trigger被匹配後,action會被加入到動作執行隊列中,在隊列中的action按隊列順序被執行,每個action下面的command也是按順序執行。按這個理論,在init.rc中action、command、service的執行順序主要是和它們的觸發時間有關,如果都是開機啟動時執行,應該也和代碼順序有關。(有興趣可以驗證一下、想深入瞭解解析過程,可以查看源碼目錄init下面的init_parser.c等文件)
4.Triggers : 跟在on後面的動作名,用來觸發action下面command的執行
1).android常用的triggers的名字:
early-init,init,early-fs,fs,post-fs,early-boot,boot (這些都是在init.c中觸發)
2).可以自定義一些triggers,並選擇合適的觸發方式 (例如:關機充電功能,可以只啟動charger服務進程)
3).= 形式,如:on property:ro.debuggable=1
4). device-added-
device-removed-
Triggers of these forms occur when a device node is added or removed
一個設備節點/dev/XXX添加或者刪除時可以觸發一個action,這個可以很好的去利用
5).service-exited-
Triggers of this form occur when the specified service exits.
當某個服務退出時,可以觸發一個action
5.option 選項:(用於services下面)
android新版本上增加的一些options可以通過源碼查看對應作用
init_parser.c--》lookup_keyword(const char *s)--》parse_line_service() 或者 --》parse_line_action()
1).class
說明服務屬於class_name這個類。缺省值service屬於 「default」 類。同一個class下面的服務可以一起啟動或停止。
2).disabled
表示當這個服務所在的class啟動的時候,服務不會自動啟動,
要用start server_name 或 property_set("ctl.start", server_name);才能啟動。
3).oneshot
當服務退出後,不會再重新啟動,如果沒有加這個option,則服務默認退出後又會重新重啟
4).user
執行服務之前,先聲明服務的用戶名,缺省值應該為root用戶.
如果你的進程要求具有linux內核能力,必須保證它的用戶為root(沒有完全明白,實例?)
5).group [ ]*
執行服務之前,先聲明服務所屬組名,可以一次聲明屬於多個組。
聲明多個組時,除第一個組名外,其他的為服務的補充組名(調用接口 setgroups()).
6).onrestart + command
服務重啟的時,會執行onrestart後面的command.
eg:onrestart restart media 重啟名為media的服務
7).setenv
在當前服務進程中設置環境變量name的值為value。
注意:setenv定義的環境變量僅在本進程內生效,退出該進程,或者關閉相應的程序運行窗口,該環境變量即無效)
程序中可通過getenv("name")接口獲取這個環境變量的值
setenv和export 的區別:
setenv csh ,本進程生效,退出後,變量無效
export bash ,全局生效,一直存在
格式:
export key=value
setenv key value
8).critical
聲明為設備的循環服務。如果服務在四分鐘內退出了四次,則設備會進入recovery模式
使用實例servicemanager、ueventd等服務
9).socket [ [ ] ]
創建名為/dev/socket/的unix domain socket ,並把它的句柄fd傳給本服務進程
必須為 "dgram", "stream" or "seqpacket".User and group default to 0 ,也就是root.
6.command :(action下面的一系列命令)
常用命令:
1).import
導入init.XX.rc、xxx.conf等文件
Parse an init config file, extending the current configuration.
2).chmod
Change file access permissions.
3).chown
Change file owner and group.
4).chdir
Change working directory.
5).chroot
改變進程根目錄
6).insmod
加載XX.ko驅動模塊
7).start
Start a service running if it is not already running.
8).stop
Stop a service from running if it is currently running.
9).class_start
Start all services of the specified class if they are not already running.
10).class_stop
Stop all services of the specified class if they are currently running.
class_reset //重啟class下面所有的服務
11).setprop
Set system property to .
通過getprop命令可以查看當前系統的屬性值
12).export
設置全局環境變量,這個變量值可以被所有進程訪問(全局的,一直存在)
在代碼中通過value = getenv("name")接口可以獲取這個環境變量的值
13).mkdir [mode] [owner] [group]
創建目錄,後面項缺省值為 mode,owner,group: 0755 root root
14).trigger
Trigger an action. Used to queue an action from another action.
例:trigger post-fs-data
15).exec [ ]*
執行指定的Program,並可以帶有執行參數。
exec在調用進程內部執行一個可執行文件,並會阻塞當前進程,直到運行完成。
最好避免和那些builtin commands一樣使用exec命令,否則容易造成阻塞 or stuck ( maybe there should be a timeout?)
16).ifup
啟動某個網絡接口,使其為up狀態,通過netcfg可以查看,ifup eth0 等價於 netcfg eth0 up 功能一樣
17).hostname
設置設備的主機名,一般默認設置為localhost,可以在終端通過hostname new_name進行修改
18).domainname
設置網絡域名localdomain
19).mount
[ ]*
把device掛接到dir目錄下面,文件系統類型為type。
s include "ro", "rw", "remount", "noatime", 「nosuid」......,具體可查看linux的mount命令說明
20).setkey
TBD == to be determined 暫時沒有使用
21).setrlimit
設置本服務進程的資源上限值。(使用例子??)
22).symlink
path 鏈接到 ---》target ;創建符號鏈接
23).sysclktz
設置系統時區(0 if system clock ticks in GMT)
24).wait [ ]
輪詢查找給定的文件path是否存在,如果找到或者超時則返回默認超時為5秒。(使用實例???)
25).write [ ]*
打開一個文件,利用write命令寫入一個或多個字符串
7. Properties
----------
Init updates some system properties to provide some insight into
what it's doing:
init.action
Equal to the name of the action currently being executed or "" if none
init.command
Equal to the command being executed or "" if none.
init.svc.
State of a named service ("stopped", "running", "restarting")
屬性狀態,getprop命令可以查看。property_set接口函數、ctl.start、ctl.stop來設置
Place your comment