天天看點

七、Binder 機制初探

Binder 機制初探

Read The Fucking Source Code

0. 準備工作

首先問自己幾個問題:

- 為什麼要跨程序通信(IPC)? (程序之間是不可以通信的嗎)

- 怎麼做到跨程序通信? (怎樣用正常的方式在兩個程序之間進行通信呢)

- 為什麼是 Binder ? (為什麼正常的跨程序方式不行,而要專門使用 Binder)

回答這幾個問題,我們得先了解一下幾個概念。為後面做鋪墊。

Android 系統是基于 Linux 核心的,是以有必要了解一些相關知識。

0.1 程序隔離

程序隔離是為保護作業系統中程序互不幹擾而設計的一組不同硬體和軟體的技術。這個技術是為了避免 程序A 寫入 程序B 的情況發生。 程序的隔離實作,使用了虛拟位址空間。程序A 的虛拟位址和 程序B 的虛拟位址不同,這樣就防止 程序A 将資料資訊寫入 程序B。

以上來自維基百科:程序隔離的安全性通過禁止程序間記憶體的通路可以友善實作。相比之下,一些不安全的作業系統(例如DOS)能夠允許任何程序對其他程序的記憶體進行寫操作。

虛拟記憶體和實體記憶體了解

根據以上描述,我們可以知道 作業系統的不同程序之間,資料是不共享的,即禁止程序間記憶體的通路。是以我們可以回答第一個問題。

Q:為什麼要跨程序通信

A:根據上述可以得知,進場之間是不可以進行通信的,是以我們需要有某種方式來完成 跨程序通信。

0.2 使用者空間 / 核心空間

詳細解釋可參考 Kernel Space Definition

Linux 系統記憶體可以分為兩個不同的區域:核心空間和使用者空間。

核心空間是核心(即作業系統的核心)執行(即運作)并提供其服務的地方。

使用者空間是指 使用者程序(即核心以外的所有内容)運作的記憶體位置集。

Linux Kernel 是作業系統的核心,獨立于普通的應用程式,可以通路受保護的記憶體空間,也有通路底層硬體裝置的所有權限。 核心的一個角色是管理這個空間中的各個使用者程序,并防止它們互相幹擾。

對于Kernel這麼一個高安全級别的東西,顯然是不容許其它的應用程式随便調用或通路的,是以需要對Kernel提供一定的保護機制,這個保護機制用來告訴那些應用程式,你隻可以通路某些許可的資源,不許可的資源是拒絕被通路的,于是就把Kernel和上層的應用程式抽像的隔離開,分别稱之為Kernel Space和User Space。

簡單了解就是:

核心空間可以執行任意指令,調用系統的一切資源;

使用者空間隻能執行簡單的運算,不能直接調用系統資源;

那麼使用者空間肯定會有想 調用系統資源 的需求,比如應用程式通路檔案的等。

根據 Kernel Space Definition 這篇文字的詳細說明,我們可以得知:

Kernel space can be accessed by user processes only through the use of system calls.

隻有通過使用系統調用,使用者程序才能通路核心空間。

0.3 系統調用 / 核心态 / 使用者态

使用者空間通路核心空間的唯一方式就是 系統調用;通過這個統一入口接口,所有的資源通路都是在核心的控制下執行,以免導緻使用者程式對系統資源的越權通路,進而保障了系統的安全和穩定。使用者軟體良莠不齊,要是它們亂搞把系統玩壞了怎麼辦?是以對于某些特權操作必須交給安全可靠的核心來執行。

當一個任務(程序)執行系統調用而陷入核心代碼中執行時,我們就稱程序處于核心運作态(或簡稱為核心态)此時處理器處于特權級最高的(0級)核心代碼中執行。當程序在執行使用者自己的代碼時,則稱其處于使用者運作态(使用者态)。即此時處理器在特權級最低的(3級)使用者代碼中運作。處理器在特權等級高的時候才能執行那些特權CPU指令。

0.4 記憶體映射 之 mmap 方法

https://www.cnblogs.com/huxiao-tee/p/4660352.html#_label0

mmap 是 記憶體映射檔案 的一種方法。即将一個檔案或者其它對象映射到程序的位址空間。實作檔案磁盤位址和程序虛拟位址空間中一段虛拟位址的一一對應關系。

Linux 核心使用一個 vm_area_struct 結構體來表示一個獨立的虛拟記憶體區域。

vm_area_struct 内包含一個 vm_ops 指針,其内部可引出所有針對這個區域可以使用的系統調用函數。

mmap 函數就是要建立一個新的 vm_area_struct 結構體,并将其與檔案的實體磁盤位址相連。

總而言之,正常檔案操作需要從磁盤到頁緩存(處于核心空間)再到使用者主存的兩次資料拷貝。而mmap操控檔案,隻需要從磁盤到使用者主存的一次資料拷貝過程。

具體的分析可檢視如下文章

Gityuan Binder 系列

Binder 學習指南

Android 接口定義語言 (AIDL)

老羅的 Android 之旅

Android Bander設計與實作 - 設計篇

相見恨晚 Binder 機制

以上連結如有通路不了的,請科學上網。