Android Binder驅動的工作機制之要旨

來源:互聯網
上載者:User

Android Binder驅動的工作機制之要旨

最近,看了不少Android核心分析的書籍、文章及Android來源程式。感覺自己對Android Binder的工作機制算是有了個徹底的理解。

 

但是,自己是花了很多時間和精力之後才達到這一點的。對於大多數人來說,恐怕不會象我這樣願意花這麼大的代價就為了弄明白這一點東西。所以,我想儘可能簡要的介紹一下Android Binder驅動的工作機制原理,以使大家不必花太多時間也能弄明白其要旨。

 

一、我們先介紹一下Binder Driver所要解決的問題。

Binder driver所要解決的是運行在同一個Android作業系統中的不同進程之間的小規模資料的傳遞問題。

注意,對於不同進程之間的大規模資料的傳遞問題,Android是用Android Shared Memory Driver來解決的。Binder Driver是針對小規模的資料傳遞的(比如幾十位元組到幾十KB的資料)。

Android Driver是整個Android Binder系統的核心部分。Android Binder系統的目標是提供一個運行在同一個Android作業系統中的不同處理序間通訊的物件導向的API,類似於Microsoft DCOM或者CORBA。為了提供這樣的物件導向的API, Android需要一種高效的處理序間通訊機制,這就是Android driver存在的目的。

 

二、那麼,為什麼不直接用Linux的共用記憶體機制來在進程間傳遞資料呢?

這是因為,除了傳遞資料之外,Android還需要這個Driver支援以下特性。

1. 安全機制:只有特定的使用者和進程才能訪問這塊資料。Linux共用記憶體不支援這樣的機制。

2. 引用計數:只有Client進程不再需要了,其對應的Server進程才能釋放相應的記憶體。Linux共用記憶體也不支援這樣的機制。

3. 另外,Android Binder driver還支援誇進程的描述符傳遞。這樣,一個進程可以直接讀另一個進程開啟的檔案,而不需要將檔案內容讀到記憶體後再複製給另一個進程。

 

三、Linux進程的虛擬記憶體空間

下面以x86 CPU的Linux實現為例,回顧一下Linux進程的虛擬記憶體空間的相關知識。

1. 每個進程有4G的虛擬記憶體空間

2.這4G空間分為兩部分。0~3G為使用者態空間(User Space),3~4G為核心態空間(Kernel Space)。

3.對於0~3G的使用者態空間,對於不同的進程,Linux會將其映射到不同的實體記憶體。比如,進程A的虛擬位址0x01234567所指向的物理地址與進程B的虛擬位址0x01234567所指向的物理地址是不同的。這就是所謂的進程隔離。

4.對於3~4G的核心態空間,對於所有的進程,Linux會將其映射到相同的實體記憶體。換句話說,進程A的虛擬位址0xC1234567與進程B的虛擬位址0xC1234567指向的是同一個物理地址。這部分虛擬記憶體空間,使用者態的進程是不能訪問的,只有切換到核心態的進程才能訪問一個進程的3~4G的核心態空間。

 

 

四、將資料從進程A傳遞到進程B的確切含義

所謂將資料從進程A傳遞到進程B,就是將進程A的某塊使用者空間(0~3G)的內容複寫到進程B的某塊使用者空間(0~3G)的記憶體中。

 

因此,為了將資料從一個進程A複製到另一個進程B,我們需要:

1. 切換到核心態。因為只有核心態才能訪問所有進程的使用者態空間。

2. 將資料從進程A的使用者態空間讀出。

3. 在進程B的使用者態空間中找一塊記憶體空間,為其分配實體記憶體,然後將資料複製到該實體記憶體處。

4. 然後,進程B就可以從其使用者空間讀到資料了。

 

五、Binder Driver是如何在進程間傳遞資料的

其實,Binder driver要做的事情就是上面我們所列出的那幾個步驟。

不過,對於每個進程,Binder driver會在進程開啟binder driver後,通過ioctl系統調用為每個進程預先找一塊使用者態和核心態的記憶體空間,做為Binder buffer使用。

請注意,對於一個進程而言,其Binder buffer在使用者態和核心態的記憶體被映射到了同樣的實體記憶體地址。

 

下面我們看看利用Binder進行通訊的兩個進程之間是如何傳遞資料的:

1. Client進程有一塊記憶體內容需要傳遞給Server進程

2. 切換到核心態

3. Binder driver讀Client進程的使用者態空間(0~3G)的這塊記憶體內容

4. Binder driver將讀出的內容複寫到Server進程的Binder buffer中

5. 然後,當Server進程執行時,就能夠在其使用者態空間(0~3G)讀傳過來的內容了。因為Binder Buffer也被映射到了Server進程的使用者態空間。

6. 當Server進程處理完讀出的訊息後,然後需要將處理的結果存放在一塊使用者態空間的記憶體中,希望將其返回給Client進程

7. 切換到核心態

8. Binder driver讀Server進程的使用者態空間(0~3G)的處理結果

4. Binder driver將讀出的內容複寫到Client進程的Binder buffer中

5. 然後,當Client進程執行時,就能夠在其使用者態空間(0~3G)讀傳過來的內容了。因為Binder Buffer也被映射到了Client進程的使用者態空間。

 

這就是Binder driver如何?處理序間通訊的。

至於其中的細節,比如安全機制的實現,就不多說了。感興趣的請參考老羅的鴻篇巨著《Android系統原始碼情景分析》,裡邊有兩百餘頁的篇幅講Binder系統。不過,要看懂這些內容,需要有較深的Linux Kernel知識。

 



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.