ServiceManager在init進程啓動以後啓動,用來管理系統中的service,那麼首先理解一下在init進程啓動以後啓動這句話類:node
通常開機過程分爲三個階段:linux
在ServiceManager中有兩個比較重要的方法:add_service和check_service,系統的service須要經過add_service把本身的信息註冊到servicemanager中,當須要使用時,經過check_service檢查該service是否存在。看它的main函數的源碼:緩存
三件事:app
首先看一下struct binder_state這個結構體函數
struct binder_state{ int fd; //文件描述符,打開/dev/binder設備 void* mapped; //把設備文件/dev/binder映射到進程空間的起始地址 unsigned mapsize; //映射內存空間的大小 }
告訴Binder驅動程序,本身是Binder上下文管理者oop
進入循環,不停去讀Binder設備,看是否有對service的請求,若是有的話就去調用svcmgr_handller函數回調處理請求。ui
下面就來看一下servicemanager是怎麼循環等待客戶端的請求,並進行註冊服務、服務獲取這一系列活動的。spa
ServiceManager進程經過binder_loop方法進入循環等待客戶端的請求中,當有客戶端請求時,進程ServiceManager被喚醒並調用svcmgr_handler來處理客戶端的請求。線程
首先設置binder_write_read結構體變量的值,而後經過ioctl傳遞到Binder驅動程序中,此時控制命令爲BINDER_WRITE_READ,binder_ioctl函數中對BINDER_WRITE_READ命令的處理過程爲:code
在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的查找,看源碼: