走進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系統,具體原因的包括如下三點:
-
Binder本身是C/S架構的,這一點更符合Android系統的架構
-
效能上更有優勢:管道,訊息佇列,Socket的通訊都需要兩次資料拷貝,而Binder只需要一次。要知道,對於系統底層的IPC形式,少一次資料拷貝,對整體效能的影響是非常之大的。
-
安全性更好:傳統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_dir
和debugfs_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_log
和transactions
檔案來確定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_open
,binder_mmap
和binder_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 |