源碼基于:Android R
0. 前言
在Linux 系統(tǒng)中現(xiàn)有的進(jìn)程間通信(IPC)方式:
- 管道(PIPE):在創(chuàng)建時(shí)分配一個(gè)page大小的內(nèi)存,緩存區(qū)大小比較有限;
- 命名管道(FIFO):考慮 PIPE_BUF 和原子操作;
- 消息隊(duì)列:信息復(fù)制兩次,額外的CPU消耗;不合適頻繁或信息量大的通信;
- 共享內(nèi)存:?無(wú)須復(fù)制,共享緩沖區(qū)直接付附加到進(jìn)程虛擬地址空間,速度快;但進(jìn)程間的同步問(wèn)題操作系統(tǒng)無(wú)法實(shí)現(xiàn),必須各進(jìn)程利用同步工具解決;
- 套接字:?作為更通用的接口,傳輸效率低,主要用于不通機(jī)器或跨網(wǎng)絡(luò)的通信;
- 信號(hào)量:?常作為一種鎖機(jī)制,防止某進(jìn)程正在訪問(wèn)共享資源時(shí),其他進(jìn)程也訪問(wèn)該資源。因此,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段;?
- 信號(hào):?不適用于信息交換,更適用于進(jìn)程中斷控制,比如非法內(nèi)存訪問(wèn),殺死某個(gè)進(jìn)程等;
0.1 使用Binder 原因
0.1.1 性能
Socket 作為一款通用接口,其傳輸效率低,開(kāi)銷(xiāo)大,主要用在跨網(wǎng)絡(luò)的進(jìn)程間通信和本機(jī)上進(jìn)程間的低速通信。
消息隊(duì)列和管道采用存儲(chǔ)-轉(zhuǎn)發(fā)方式,即數(shù)據(jù)先從發(fā)送方緩存區(qū)拷貝到內(nèi)核開(kāi)辟的緩存區(qū)中,然后再?gòu)膬?nèi)核緩存區(qū)拷貝到接收方緩存區(qū),至少有兩次拷貝過(guò)程。
共享內(nèi)存雖然無(wú)需拷貝,但控制復(fù)雜,難以使用。
Binder 只需要一次數(shù)據(jù)拷貝,性能上僅次于共享內(nèi)存。
0.1.2 穩(wěn)定性
Binder 基于 C/S 架構(gòu),客戶(hù)端(Client)有什么需求就丟給服務(wù)端(Server)去完成,架構(gòu)清晰、職責(zé)明確又相互獨(dú)立,自然穩(wěn)定性更好。共享內(nèi)存雖然無(wú)需拷貝,但是控制負(fù)責(zé),難以使用。
從穩(wěn)定性的角度講,Binder 機(jī)制是優(yōu)于內(nèi)存共享的。
0.1.3 安全性
Android 為每個(gè)安裝好的 APP 分配了自己的 UID,故而進(jìn)程的 UID 是鑒別進(jìn)程身份的重要標(biāo)志。傳統(tǒng)的 IPC 只能由用戶(hù)在數(shù)據(jù)包中填入 UID/PID,但這樣不可靠,容易被惡意程序利用。可靠的身份標(biāo)識(shí)只有由 IPC 機(jī)制在內(nèi)核中添加。其次傳統(tǒng)的 IPC 訪問(wèn)接入點(diǎn)是開(kāi)放的,只要知道這些接入點(diǎn)的程序都可以和對(duì)端建立連接,不管怎樣都無(wú)法阻止惡意程序通過(guò)猜測(cè)接收方地址獲得連接。同時(shí) Binder 既支持實(shí)名 Binder,又支持匿名 Binder,安全性高。
2. Binder 劃分
在Android 8.0 之前,Binder機(jī)制比較簡(jiǎn)單,只有一個(gè)驅(qū)動(dòng)設(shè)備"/dev/binder",一個(gè)守護(hù)進(jìn)行"/system/bin/servicemanager",一個(gè)binder庫(kù)"/system/lib64/libbinder.so".
在Android 8.0開(kāi)始,Android引入了Treble的機(jī)制,為了方便Android系統(tǒng)的快速移植、升級(jí),提升系統(tǒng)穩(wěn)定性,Binder機(jī)制被拓展成了"/dev/binder", "/dev/hwbinder","/dev/vndbinder"。
我們?cè)仁褂玫?/dev/binder",成為框架進(jìn)程的專(zhuān)有節(jié)點(diǎn),這意味著供應(yīng)商進(jìn)程無(wú)法再訪問(wèn)此節(jié)點(diǎn)。供應(yīng)商進(jìn)程可以訪問(wèn) /dev/hwbinder,但必須將其 AIDL 接口轉(zhuǎn)為使用 HIDL。
對(duì)于想要繼續(xù)在供應(yīng)商進(jìn)程之間使用 AIDL 接口的供應(yīng)商,需要使用 /dev/vndbinder(而非 /dev/binder)。
Android8.0 及之后的Binder域如下圖所示:
3. 三種 binder 介紹
??
??
??
3.1 vndbinder 和 binder
vnbinder 和binder 使用的是一個(gè)ServiceManager 和libbinder,只不過(guò)在選擇的時(shí)候會(huì)區(qū)分open /dev/binder 還是/dev/vnbinder:
??
??
frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
ps->setThreadPoolMaxThreadCount(0);
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
..
}
代碼中根據(jù)參數(shù)選擇性的將driver 傳入進(jìn)行open,詳細(xì)看ProcessState::initWithDriver() 函數(shù)。
通常,供應(yīng)商進(jìn)程不直接打開(kāi) Binder 驅(qū)動(dòng)程序,而是鏈接到打開(kāi) Binder 驅(qū)動(dòng)程序的 libbinder 用戶(hù)空間庫(kù)。為 ::android::ProcessState() 添加方法可為 libbinder 選擇 Binder 驅(qū)動(dòng)程序。供應(yīng)商進(jìn)程應(yīng)該在調(diào)用 ProcessState、IPCThreadState 或發(fā)出任何普通 Binder 調(diào)用之前調(diào)用此方法。要使用該方法,請(qǐng)?jiān)诠?yīng)商進(jìn)程(客戶(hù)端和服務(wù)器)的 main() 后放置以下調(diào)用:
ProcessState::initWithDriver("/dev/vndbinder");
dev/binder和dev/vndbinder無(wú)法在一個(gè)進(jìn)程中同時(shí)使用
binder和vndbiner 的機(jī)制共用一套libbinder,因此兩者使用時(shí),每次只能指定一個(gè)設(shè)備節(jié)點(diǎn),不能同時(shí)使用。
3.2 hwbinder
hwbinder 獨(dú)立于binder和vndbinder,擁有獨(dú)立的驅(qū)動(dòng)設(shè)備 /dev/hwbinder,獨(dú)立的hwservicemanager (system/hwservicemanager/ 目錄) 和獨(dú)立的binder 庫(kù)libhwbinder (system/libhwbinder/ 目錄)。
android 8.0 以后采用了treble 的架構(gòu),framework 和HAL 是獨(dú)立的,在不同的 fw 和 HAL 進(jìn)程中,進(jìn)程間通信使用的是 HIDL 語(yǔ)言,而不在使用 AIDL 語(yǔ)言,因此使用了不同的 binder 驅(qū)動(dòng)設(shè)備
3.3 binder 庫(kù)的變化
binder |
vndbinder |
hwbinder |
|
lib binder 位置 |
frameworks/native/libs/binder |
frameworks/native/libs/binder |
system/libhwbinder |
service manager 位置 |
frameworks/native/cmds/servicemanager文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-494967.html |
frameworks/native/cmds/servicemanager |
system/hwservicemanager文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-494967.html |
到了這里,關(guān)于Android Binder通信原理(一):簡(jiǎn)介的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!