Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Binder驅動的工作機制之要旨

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

編輯:關於Android編程

最近,看了不少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知識。

\

 


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved