ServiceManager在init進程啟動之後啟動,用來管理系統中的service,那麼首先理解一下在init進程啟動之後啟動這句話類: 一般開機過程分為三個階段: 1. OS級別,由bootloader載入linux內核後,內核開始初始化,並載入built in的驅動程式,內核完成開機後,載入 ...
ServiceManager在init進程啟動之後啟動,用來管理系統中的service,那麼首先理解一下在init進程啟動之後啟動這句話類:
一般開機過程分為三個階段:
- OS級別,由bootloader載入linux內核後,內核開始初始化,並載入built-in的驅動程式,內核完成開機後,載入init process,切換至user-space後,結束內核的循序過程,進入排成模式。
- Android-level,由init process開始,讀取init.rc,Mative服務啟動,並啟動重要的外部程式,例如servicemanager、zygote以及system service。
- Zygote-Mode,Zygote啟動完System Service後,進入Zygote Mode,在Socket等候命令,隨後,使用者將看到一個桌面環境,桌面環境由一個名為Launcher的應用程式負責提供。
在ServiceManager中有兩個比較重要的方法:add_service和check_service,系統的service需要通過add_service把自己的信息註冊到servicemanager中,當需要使用時,通過check_service檢查該service是否存在。看它的main函數的源碼:
三件事:
- 打開Binder設備,併在記憶體中映射128k的空間
首先看一下struct binder_state這個結構體
struct binder_state{
int fd; //文件描述符,打開/dev/binder設備
void* mapped; //把設備文件/dev/binder映射到進程空間的起始地址
unsigned mapsize; //映射記憶體空間的大小
}
告訴Binder驅動程式,自己是Binder上下文管理者
進入迴圈,不停去讀Binder設備,看是否有對service的請求,如果有的話就去調用svcmgr_handller函數回調處理請求。
下麵就來看一下servicemanager是怎麼迴圈等待客戶端的請求,併進行註冊服務、服務獲取這一系列活動的。
等待客戶端請求
ServiceManager進程通過binder_loop方法進入迴圈等待客戶端的請求中,當有客戶端請求時,進程ServiceManager被喚醒並調用svcmgr_handler來處理客戶端的請求。
- ServiceManager進程在進入迴圈前,調用binder_write()方法,通過ioctl系統調用設置Binder線程的運行狀態為BINDER_LOOPER_STATE_ENTERED,看下binder_write()方法的源碼:
首先設置binder_write_read結構體變數的值,然後通過ioctl傳遞到Binder驅動程式中,此時控制命令為BINDER_WRITE_READ,binder_ioctl函數中對BINDER_WRITE_READ命令的處理過程為:
在binder_thread_write方法中,對BC_ENTER_LOOPER Binder協議的處理如下:
此處僅僅設置了binder_thread結構體變數中的線程運行狀態looper為BINDER_LOOPER_STATE_ENTERED,表示當前的binder線程進入迴圈狀態。
2. 睡眠等待客戶端請求
在沒有客戶端請求時,當前進程就進入休眠狀態,等待請求到來再喚醒。
總結一哈?
ServiceManager進程的啟動首先打開binder驅動並開闢內核緩存區,同時將緩存區的物理頁面同時映射到內核虛擬地址空間及進程虛擬地址空間中,然後在內核中創建屬於servicemanager進程的binder_node實體節點,接著設置處理客戶端請求的binder線程運行狀態,由於此時沒有客戶端的請求,servicemanager進程進入睡眠等待中,直到客戶端請求的到來時,喚醒servicemanager進程,再繼續往下執行。
服務註冊
直接來看,當有service請求時,調用的回到函數svcmgr_handler函數。
如果請求註冊,就執行紅色框中的代碼,我們再來看一下具體實現do_add_service()方法是怎麼實現的:
看代碼中的三個紅框,首先會檢查是否有許可權註冊service,如果沒有許可權就直接返回不能註冊;然後去檢查該service是否已經註冊過了,如果已經註冊過,那就不能再註冊;再判斷記憶體是否夠用。如果都沒有問題,就會註冊該service,加入到svcList中來,(在servicemanager中維護service信息的地方就是svcList,裡面存了service的name和handler)。通過以上幾步,service就算註冊成功了。
服務獲取
如果是服務獲取,就會執行代碼中的黃色框,並將返回的數據寫入reply,返回給客戶端,do_find_service函數中主要執行service的查找,看源碼: