??ServiceManager在init進(jìn)程啟動(dòng)之后啟動(dòng),用來管理系統(tǒng)中的service,那么首先理解一下在init進(jìn)程啟動(dòng)之后啟動(dòng)這句話類:
一般開機(jī)過程分為三個(gè)階段:
1. OS級別,由bootloader載入linux內(nèi)核后,內(nèi)核開始初始化,并載入built-in的驅(qū)動(dòng)程序,內(nèi)核完成開機(jī)后,載入init process,切換至user-space后,結(jié)束內(nèi)核的循序過程,進(jìn)入排成模式。
2. Android-level,由init process開始,讀取init.rc,Mative服務(wù)啟動(dòng),并啟動(dòng)重要的外部程序,例如servicemanager、zygote以及system service。
3. Zygote-Mode,Zygote啟動(dòng)完System Service后,進(jìn)入Zygote Mode,在Socket等候命令,隨后,使用者將看到一個(gè)桌面環(huán)境,桌面環(huán)境由一個(gè)名為Launcher的應(yīng)用程序負(fù)責(zé)提供。

??在ServiceManager中有兩個(gè)比較重要的方法:add_service和check_service,系統(tǒng)的service需要通過add_service把自己的信息注冊到servicemanager中,當(dāng)需要使用時(shí),通過check_service檢查該service是否存在。看它的main函數(shù)的源碼:

三件事:
1. 打開Binder設(shè)備,并在內(nèi)存中映射128k的空間
首先看一下struct binder_state這個(gè)結(jié)構(gòu)體
struct binder_state{
int fd; //文件描述符,打開/dev/binder設(shè)備
void* mapped; //把設(shè)備文件/dev/binder映射到進(jìn)程空間的起始地址
unsigned mapsize; //映射內(nèi)存空間的大小
}
2. 告訴Binder驅(qū)動(dòng)程序,自己是Binder上下文管理者
3.進(jìn)入循環(huán),不停去讀Binder設(shè)備,看是否有對service的請求,如果有的話就去調(diào)用svcmgr_handller函數(shù)回調(diào)處理請求。
??下面就來看一下servicemanager是怎么循環(huán)等待客戶端的請求,并進(jìn)行注冊服務(wù)、服務(wù)獲取這一系列活動(dòng)的。
等待客戶端請求
??ServiceManager進(jìn)程通過binder_loop方法進(jìn)入循環(huán)等待客戶端的請求中,當(dāng)有客戶端請求時(shí),進(jìn)程ServiceManager被喚醒并調(diào)用svcmgr_handler來處理客戶端的請求。



??此處僅僅設(shè)置了binder_thread結(jié)構(gòu)體變量中的線程運(yùn)行狀態(tài)looper為BINDER_LOOPER_STATE_ENTERED,表示當(dāng)前的binder線程進(jìn)入循環(huán)狀態(tài)。
2. 睡眠等待客戶端請求
在沒有客戶端請求時(shí),當(dāng)前進(jìn)程就進(jìn)入休眠狀態(tài),等待請求到來再喚醒。
總結(jié)一哈?
??ServiceManager進(jìn)程的啟動(dòng)首先打開binder驅(qū)動(dòng)并開辟內(nèi)核緩存區(qū),同時(shí)將緩存區(qū)的物理頁面同時(shí)映射到內(nèi)核虛擬地址空間及進(jìn)程虛擬地址空間中,然后在內(nèi)核中創(chuàng)建屬于servicemanager進(jìn)程的binder_node實(shí)體節(jié)點(diǎn),接著設(shè)置處理客戶端請求的binder線程運(yùn)行狀態(tài),由于此時(shí)沒有客戶端的請求,servicemanager進(jìn)程進(jìn)入睡眠等待中,直到客戶端請求的到來時(shí),喚醒servicemanager進(jìn)程,再繼續(xù)往下執(zhí)行。
服務(wù)注冊
直接來看,當(dāng)有service請求時(shí),調(diào)用的回到函數(shù)svcmgr_handler函數(shù)。



服務(wù)獲取
??如果是服務(wù)獲取,就會(huì)執(zhí)行代碼中的黃色框,并將返回的數(shù)據(jù)寫入reply,返回給客戶端,do_find_service函數(shù)中主要執(zhí)行service的查找,看源碼:

紀(jì)念我的第一篇MarkDown文章
??寫了這么久的博客,一開始的時(shí)候就對文字輸入表示懷疑,為啥人家輸入代碼的時(shí)候輸入的這么溜,還能復(fù)制,而我只能截圖發(fā)上去,偶然讓我發(fā)現(xiàn)了MarkDown編譯器,感覺當(dāng)時(shí)的自己。。。。好白癡啊。。。。。