1. 程式人生 > >走進Android Binder機制(驅動篇上)

走進Android Binder機制(驅動篇上)

由於篇幅限制,驅動篇文章分為上下兩章,還請大家注意,此篇是上篇。

Binder的實現是比較複雜的,想要完全弄明白是怎麼一回事,並不是一件容易的事情。

這裡面牽涉到好幾個層次,每一層都有一些模組和機制需要理解。這部分內容預計會分為三篇文章來講解。本文是第一篇,首先會對整個Binder機制做一個架構性的講解,然後會將大部分精力用來講解Binder機制中最核心的部分:Binder驅動的實現。

Binder機制簡介

Binder源自Be Inc公司開發的OpenBinder框架,後來該框架轉移的Palm Inc,由Dianne Hackborn主導開發。OpenBinder的核心部分已經合入Linux Kernel 3.19。

Android Binder是在OpneBinder上的定製實現。原先的OpenBinder框架現在已經不再繼續開發,可以說Android上的Binder讓原先的OpneBinder得到了重生。

Binder是Android系統中大量使用的IPC(Inter-process communication,程序間通訊)機制。無論是應用程式對系統服務的請求,還是應用程式自身提供對外服務,都需要使用到Binder。

因此,Binder機制在Android系統中的地位非常重要,可以說,理解Binder是理解Android系統的絕對必要前提。

在Unix/Linux環境下,傳統的IPC機制包括:

  • 管道

  • 訊息佇列

  • 共享記憶體

  • 訊號量

  • Socket

Android系統中對於傳統的IPC使用較少(但也有使用,例如:在請求Zygote fork程序的時候使用的是Socket IPC),大部分場景下使用的IPC都是Binder。

Binder相較於傳統IPC來說更適合於Android系統,具體原因的包括如下三點:

  1. Binder本身是C/S架構的,這一點更符合Android系統的架構

  2. 效能上更有優勢:管道,訊息佇列,Socket的通訊都需要兩次資料拷貝,而Binder只需要一次。要知道,對於系統底層的IPC形式,少一次資料拷貝,對整體效能的影響是非常之大的。

  3. 安全性更好:傳統IPC形式,無法得到對方的身份標識(UID/GID),而在使用Binder IPC時,這些身份標示是跟隨呼叫過程而自動傳遞的。Server端很容易就可以知道Client端的身份,非常便於做安全檢查。

整體架構

Binder整體架構如下所示:


從圖中可以看出,Binder的實現分為這麼幾層:

  • Framework層

    • Java部分

    • JNI部分

    • C++部分

  • 驅動層

驅動層位於Linux核心中,它提供了最底層的資料傳遞,物件標識,執行緒管理,呼叫過程控制等功能。驅動層是整個Binder機制的核心

Framework層以驅動層為基礎,提供了應用開發的基礎設施。

Framework層既包含了C++部分的實現,也包含了Java部分的實現。為了能將C++的實現複用到Java端,中間通過JNI進行銜接。

開發者可以在Framework之上利用Binder提供的機制來進行具體的業務邏輯開發。其實不僅僅是第三方開發者,Android系統中本身也包含了很多系統服務都是基於Binder框架開發的。

既然是“程序間”通訊就至少牽涉到兩個程序,Binder框架是典型的C/S架構。在下文中,我們把服務的請求方稱之為Client,服務的實現方稱之為Server。

Client對於Server的請求會經由Binder框架由上至下傳遞到核心的Binder驅動中,請求中包含了Client將要呼叫的命令和引數。請求到了Binder驅動之後,在確定了服務的提供方之後,會再從下至上將請求傳遞給具體的服務。整個呼叫過程如下圖所示:


對網路協議有所瞭解的讀者會發現,這個資料的傳遞過程和網路協議是如此的相似。

初識ServiceManager

前面已經提到,使用Binder框架的既包括系統服務,也包括第三方應用。因此,在同一時刻,系統中會有大量的Server同時存在。那麼,Client在請求Server的時候,是如果確定請求傳送給哪一個Server的呢?

這個問題,就和我們現實生活中如何找到一個公司/商場,如何確定一個人/一輛車一樣,解決的方法就是:每個目標物件都需要一個唯一的標識。並且,需要有一個組織來管理這個唯一的標識。

而Binder框架中負責管理這個標識的就是ServiceManager。ServiceManager對於Binder Server的管理就好比車管所對於車牌號碼的的管理,派出所對於身份證號碼的管理:每個公開對外提供服務的Server都需要註冊到ServiceManager中(通過addService),註冊的時候需要指定一個唯一的id(這個id其實就是一個字串)。

Client要對Server發出請求,就必須知道服務端的id。Client需要先根據Server的id通過ServerManager拿到Server的標示(通過getService),然後通過這個標示與Server進行通訊。

整個過程如下圖所示:


如果上面這些介紹已經讓你一頭霧水,請不要過分擔心,下面會詳細講解這其中的細節。

下文會以自下而上的方式來講解Binder框架。自下而上未必是最好的方法,每個人的思考方式不一樣,如果你更喜歡自上而下的理解,你也按這樣的順序來閱讀。

對於大部分人來說,我們可能需要反覆的查閱才能完全理解。

驅動層

原始碼路徑(這部分程式碼不在AOSP中,而是位於Linux核心程式碼中):

/kernel/drivers/android/binder.c
/kernel/include/uapi/linux/android/binder.h

或者

/kernel/drivers/staging/android/binder.c
/kernel/drivers/staging/android/uapi/binder.h

Binder機制的實現中,最核心的就是Binder驅動。 Binder是一個miscellaneous型別的驅動,本身不對應任何硬體,所有的操作都在軟體層。 binder_init函式負責Binder驅動的初始化工作,該函式中大部分程式碼是在通過debugfs_create_dirdebugfs_create_file函式建立debugfs對應的檔案。 如果核心在編譯時打開了debugfs,則通過adb shell連上裝置之後,可以在裝置的這個路徑找到debugfs對應的檔案:/sys/kernel/debug。Binder驅動中建立的debug檔案如下所示:

# ls -l /sys/kernel/debug/binder/                                     total 0
-r--r--r-- 1 root root 0 1970-01-01 00:00 failed_transaction_log
drwxr-xr-x 2 root root 0 1970-05-09 01:19 proc
-r--r--r-- 1 root root 0 1970-01-01 00:00 state
-r--r--r-- 1 root root 0 1970-01-01 00:00 stats
-r--r--r-- 1 root root 0 1970-01-01 00:00 transaction_log
-r--r--r-- 1 root root 0 1970-01-01 00:00 transactions

這些檔案其實都在記憶體中的,實時的反應了當前Binder的使用情況,在實際的開發過程中,這些資訊可以幫忙分析問題。例如,可以通過檢視/sys/kernel/debug/binder/proc目錄來確定哪些程序正在使用Binder,通過檢視transaction_logtransactions檔案來確定Binder通訊的資料。

binder_init函式中最主要的工作其實下面這行:

ret = misc_register(&binder_miscdev);

該行程式碼真正向核心中註冊了Binder裝置。binder_miscdev的定義如下:

static struct miscdevice binder_miscdev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "binder",
	.fops = &binder_fops};

這裡指定了Binder裝置的名稱是“binder”。這樣,在使用者空間便可以通過對/dev/binder檔案進行操作來使用Binder。

binder_miscdev同時也指定了該裝置的fops。fops是另外一個結構體,這個結構中包含了一系列的函式指標,其定義如下:

static const struct file_operations binder_fops = {
	.owner = THIS_MODULE,
	.poll = binder_poll,
	.unlocked_ioctl = binder_ioctl,
	.compat_ioctl = binder_ioctl,
	.mmap = binder_mmap,
	.open = binder_open,
	.flush = binder_flush,
	.release = binder_release,};

這裡除了owner之外,每一個欄位都是一個函式指標,這些函式指標對應了使用者空間在使用Binder裝置時的操作。例如:binder_poll對應了poll系統呼叫的處理,binder_mmap對應了mmap系統呼叫的處理,其他類同。

這其中,有三個函式尤為重要,它們是:binder_openbinder_mmapbinder_ioctl。 這是因為,需要使用Binder的程序,幾乎總是先通過binder_open開啟Binder裝置,然後通過binder_mmap進行記憶體對映。

在這之後,通過binder_ioctl來進行實際的操作。Client對於Server端的請求,以及Server對於Client請求結果的返回,都是通過ioctl完成的。

這裡提到的流程如下圖所示:


主要結構

Binder驅動中包含了很多的結構體。為了便於下文講解,這裡我們先對這些結構體做一些介紹。

驅動中的結構體可以分為兩類:

一類是與使用者空間共用的,這些結構體在Binder通訊協議過程中會用到。因此,這些結構體定義在binder.h中,包括:

結構體名稱 說明
flat_binder_object 描述在Binder IPC中傳遞的物件,見下文
binder_write_read 儲存一次讀寫操作的資料
binder_version

相關推薦

走進Android Binder機制驅動

由於篇幅限制,驅動篇文章分為上下兩章,還請大家注意,此篇是上篇。 Binder的實現是比較複雜的,想要完全弄明白是怎麼一回事,並不是一件容易的事情。 這裡面牽涉到好幾個層次,每一層都

Binder機制非常好理解

Binder是一種程序間通訊機制,用來實現不同程序之間的通訊。 Binder機制主要由四大塊組成,分別是客戶空間的client、server,serverManager,還有核心的Binder驅動。 下面我先看下圖,利於理解Binder內部工作機制: 伺服器端。一

mysql實操總結基礎-

基礎篇--SQL介紹及MySQL安裝一、結構化查詢語句(Structured Query Language)簡稱SQL1)啟動MySQL:$sudo service mysql start$mysql -u root2)檢視資料庫:mysql > show databa

Android Binder機制原理最強理解,沒有之一

Binder是Android系統程序間通訊(IPC)方式之一。Linux已經擁有的程序間通訊IPC手段包括(Internet Process Connection): 管道(Pipe)、訊號(Signal)和跟蹤(Trace)、插口(Socket)、報文佇列(Messag

Android Binder機制原理最強理解,沒有之一

Binder是Android系統程序間通訊(IPC)方式之一。Linux已經擁有的程序間通訊IPC手段包括(Internet Process Connection): 管道(Pipe)、訊號(Signal)和跟蹤(Trace)、插口(Socket)、報文佇列(Messa

Android Handler 訊息機制解惑

Android中的訊息處理機制概述 大家對於Android中的訊息處理機制的用法一定都比較熟悉,至於工作原理估計不少人有研究。就像我們自己寫的類我們用起來比較熟悉一樣,如果我們熟悉了訊息處理機制的具體實現,那麼我們用起來肯定也會事半功倍。 博主之前只是稍有涉

Android進階]Binder學習初始

Android中Binder學習(初始篇) 本篇部落格學習自侯亮的部落格,地址為: 1 什麼是Binder? 簡單地說,Binder是Android平臺上的一種跨程序互動技術。該技術最早並不是由Google公司提出的,它的前身是Be Inc

android Binder機制

pro end abs close 概念 exp 是的 一切都 實例化 Binder 架構設計 Binder 被設計出來是解決 Android IPC(進程間通信) 問題的。Binder 將兩個進程間交互的理解為 Client 向 Server 進行通信。 如下:binde

Android系統移植:驅動

音視頻 理念 rom 利用 定時 垃圾回收 ipc track 進程間 【導語】在Android系統移植中,有很重要的一個部分工作,就是為新平臺上的硬件設備移植驅動程序。因為Android系統是基於Linux kernel內核構建,所以這裏說的移植驅動程序,其實就是

原創:聊Python小白如何系統自學成為Python大牛基礎

Python Python學習 Python開發 Python自學 原創:聊Python小白如何系統自學成為Python大牛(基礎篇一)上 支持原創 本文章,由頭條py柯西發表,禁止轉載,希望大家支持原創 歡迎大家點擊復制鏈接看原文https://www.toutiao.com/i654581

深入理解Java異常處理機制 籠統

throw 種類型 綜合 IV 算術 其它 wid all 作用 開篇 1.異常處理(Exception Handling):   就是一種解決這一問題的機制,能夠較好地處理程序不能正常運行的情況。 2.異常(Exception):   是程序在運行時可能出現的

android binder筆記

ati ima ger 取數 manager nat 機構 聲明 tar 最近在看韋老師的android binder視頻 ,記錄下個人對視頻學習的理解。 學習需要記錄與分享,如果有誤,希望得到大家的指正! IPC:兩個進程間數據通信的一種方式 RPC:一個進

Pro Android學習筆記一五五 感測器5 磁場感測器和方位

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android Binder機制淺析

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android IPC機制2

前言 本章主要講解Android中IPC的通訊方式。。。 1.Bundle Bundle實現了Parcelable介面,且四大元件中Activity、Service、Receiver都支援在Intent中傳遞Bundle。傳輸的資料必須能夠被序列化,如基本型別、實現了了P

Android Binder機制原理

Binder是Android系統程序間通訊(IPC)方式之一。Linux已經擁有的程序間通訊IPC手段包括(Internet Process Connection): 管道(Pipe)、訊號(Signal)和跟蹤(Trace)、插口(Socket)、報文佇列(Messag

Android訊息機制Handler、MessageQueue和Looper三者的工作原理

Android的訊息機制主要是指Handler的執行機制以及Handler所附帶的MessageQueue和Looper的工作過程。messagequeue意思是訊息佇列,它內部儲存一組訊息,有插入和刪除的功能,其實內部是以單鏈表的形式來實現佇列功能的。looper的意思是迴圈,它的主要功能是迴

Android IPC機制1

前言 本系列主要介紹Android的IPC機制,Android中多程序的概念以及多程序開發的注意事項,程序間通訊的方式等。 1.IPC簡介 IPC是Inter-Process Communication的縮寫,含義為程序間通訊或者跨程序通訊,指兩個程序間進行資

學習MongoDB 十一: MongoDB聚合Aggregation Pipeline基礎

一、Aggregate簡介                  db.collection.aggregate()是基於資料處理的聚合管道,每個文件通過一個由多個階段(stage)組成的管道,可以對每個階段的管道進行分組、過濾等功能,然後經過一系列的處理,輸出相應的結果。

【Baiduluckyboy的專欄 說到做到 這是我的品牌 華天正210 6410 專職代理 】Real 210技術交流群 220901638 baiduman團隊外接android的開發驅動 應用

Baiduman的簡歷 Baiduman畢業於解放軍電子工程學院 專業是電子資訊工程 目前是在深圳的一家方案設計公司做Android驅動架構工程師,Baiduman有幸在學校裡遇見一位恩師,團長級別的教授,在他的引導下Baiduman開始了電子大賽的征程,Baiduma