Android-ServiceManager

ServiceManager在init進程啓動以後啓動,用來管理系統中的service,那麼首先理解一下在init進程啓動以後啓動這句話類:node

通常開機過程分爲三個階段:linux

  1. OS級別,由bootloader載入linux內核後,內核開始初始化,並載入built-in的驅動程序,內核完成開機後,載入init process,切換至user-space後,結束內核的循序過程,進入排成模式。
  2. Android-level,由init process開始,讀取init.rc,Mative服務啓動,並啓動重要的外部程序,例如servicemanager、zygote以及system service。
  3. Zygote-Mode,Zygote啓動完System Service後,進入Zygote Mode,在Socket等候命令,隨後,使用者將看到一個桌面環境,桌面環境由一個名爲Launcher的應用程序負責提供。

image

在ServiceManager中有兩個比較重要的方法:add_service和check_service,系統的service須要經過add_service把本身的信息註冊到servicemanager中,當須要使用時,經過check_service檢查該service是否存在。看它的main函數的源碼:緩存

image

三件事:app

  1. 打開Binder設備,並在內存中映射128k的空間

首先看一下struct binder_state這個結構體函數

struct binder_state{
    int fd;            //文件描述符,打開/dev/binder設備
    void* mapped;    //把設備文件/dev/binder映射到進程空間的起始地址
    unsigned mapsize;  //映射內存空間的大小
}
  1. 告訴Binder驅動程序,本身是Binder上下文管理者oop

  2. 進入循環,不停去讀Binder設備,看是否有對service的請求,若是有的話就去調用svcmgr_handller函數回調處理請求。ui

下面就來看一下servicemanager是怎麼循環等待客戶端的請求,並進行註冊服務、服務獲取這一系列活動的。spa

等待客戶端請求

ServiceManager進程經過binder_loop方法進入循環等待客戶端的請求中,當有客戶端請求時,進程ServiceManager被喚醒並調用svcmgr_handler來處理客戶端的請求。線程

image

  1. ServiceManager進程在進入循環前,調用binder_write()方法,經過ioctl系統調用設置Binder線程的運行狀態爲BINDER_LOOPER_STATE_ENTERED,看下binder_write()方法的源碼:

image

首先設置binder_write_read結構體變量的值,而後經過ioctl傳遞到Binder驅動程序中,此時控制命令爲BINDER_WRITE_READ,binder_ioctl函數中對BINDER_WRITE_READ命令的處理過程爲:code

image

在binder_thread_write方法中,對BC_ENTER_LOOPER Binder協議的處理以下:

image

此處僅僅設置了binder_thread結構體變量中的線程運行狀態looper爲BINDER_LOOPER_STATE_ENTERED,表示當前的binder線程進入循環狀態。

2. 睡眠等待客戶端請求

在沒有客戶端請求時,當前進程就進入休眠狀態,等待請求到來再喚醒。

總結一哈?

ServiceManager進程的啓動首先打開binder驅動並開闢內核緩存區,同時將緩存區的物理頁面同時映射到內核虛擬地址空間及進程虛擬地址空間中,而後在內核中建立屬於servicemanager進程的binder_node實體節點,接着設置處理客戶端請求的binder線程運行狀態,因爲此時沒有客戶端的請求,servicemanager進程進入睡眠等待中,直到客戶端請求的到來時,喚醒servicemanager進程,再繼續往下執行。

服務註冊

直接來看,當有service請求時,調用的回到函數svcmgr_handler函數。
image

若是請求註冊,就執行紅色框中的代碼,咱們再來看一下具體實現do_add_service()方法是怎麼實現的:

image

image

看代碼中的三個紅框,首先會檢查是否有權限註冊service,若是沒有權限就直接返回不能註冊;而後去檢查該service是否已經註冊過了,若是已經註冊過,那就不能再註冊;再判斷內存是否夠用。若是都沒有問題,就會註冊該service,加入到svcList中來,(在servicemanager中維護service信息的地方就是svcList,裏面存了service的name和handler)。經過以上幾步,service就算註冊成功了。

服務獲取

若是是服務獲取,就會執行代碼中的黃色框,並將返回的數據寫入reply,返回給客戶端,do_find_service函數中主要執行service的查找,看源碼:

image

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息