Android專用驅(qū)動_第1頁
Android專用驅(qū)動_第2頁
Android專用驅(qū)動_第3頁
Android專用驅(qū)動_第4頁
Android專用驅(qū)動_第5頁
已閱讀5頁,還剩52頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Android專用驅(qū)動Logger、Binder、Ashmem羅升陽http:/ Me 老羅的Android之旅博客作者 Android系統(tǒng)源代碼情景分析書籍作者 博客:http:/ 微博:http:/ Android專用驅(qū)動概述 Android Logger驅(qū)動系統(tǒng) Android Binder驅(qū)動系統(tǒng) Android Ashmem驅(qū)動系統(tǒng)Android專用驅(qū)動概述 以Linux驅(qū)動形式實現(xiàn)在內(nèi)核空間 不是為了驅(qū)動硬件設(shè)備工作 而是為了獲得特權(quán)管理系統(tǒng) 為Android Runtime Framework服務(wù) 高效的日志服務(wù) 高效的進程間通信機制 以組件為目標的進程管理機制 在整個系統(tǒng)中廣泛

2、和頻繁地使用Android Logger驅(qū)動系統(tǒng) 日志系統(tǒng)的作用和特點 開發(fā)期間調(diào)試程序功能 發(fā)布期間記錄程序運行 頻繁和廣泛地使用 傳統(tǒng)日志系統(tǒng)以文件為輸出 從用戶空間切換至內(nèi)核空間 在內(nèi)核空間執(zhí)行磁盤IO操作 Android日志系統(tǒng)以內(nèi)核緩沖區(qū)為輸出 從用戶空間切換至內(nèi)核空間 直接內(nèi)存操作 Android日志系統(tǒng)更高效Android Logger驅(qū)動系統(tǒng)(續(xù)) 以緩沖區(qū)為輸出的日志系統(tǒng)要解決的問題 不能占用過多的內(nèi)存 次要日志不能覆蓋重要日志 頻繁寫入的日志不能覆蓋不頻繁寫入的日志 以上三個問題的解決方案 環(huán)形緩沖區(qū),新日志覆蓋舊日志 日志分類,不同類的日志寫在不同的緩沖區(qū)Android

3、Logger驅(qū)動系統(tǒng)(續(xù)) 整體架構(gòu)圖Android Logger驅(qū)動系統(tǒng)(續(xù))日志分類 Main,記錄應(yīng)用程序類型日志,次要,文本格式 /dev/log/main System,記錄系統(tǒng)類型日志,重要,文本格式 /dev/log/system Radio,記錄無線相關(guān)日志,頻繁 ,文本格式 /dev/log/radio Event,記錄系統(tǒng)事件日志,特殊用途,二進制格式 /dev/log/events每一類日志對應(yīng)一個設(shè)備文件 Main:/dev/log/main System: /dev/log/system Radio:/dev/log/radio Event:/dev/log/even

4、ts 每一類日志對應(yīng)一個環(huán)形緩沖區(qū),大小256KAndroid Logger驅(qū)動系統(tǒng)(續(xù)) 文本類型日志格式 Priority,優(yōu)先級,整數(shù) VERBOSE、DEBUG、INFO、WARN、ERROR、FATAL Tag,標簽,字符串 自定義 Msg,日志內(nèi)容,字符串 自定義Android Logger驅(qū)動系統(tǒng)(續(xù)) 二進制類型日志格式 Tag,標簽,整數(shù) 自定義 Msg,日志內(nèi)容,二進制數(shù)據(jù)塊 Type:整數(shù)(1),長整數(shù)(2),字符串(3),列表(4) Value:自定義Android Logger驅(qū)動系統(tǒng)(續(xù)) 二進制日志格式由/system/etc/event-log-tags文件描述

5、 日志標簽tag number對應(yīng)的文本描述為tag name 日志內(nèi)容格式 name:名稱 data type:數(shù)據(jù)類型 data unit:數(shù)據(jù)單位Android Logger驅(qū)動系統(tǒng)(續(xù)) 二進制日志格式描述示例 日志2722表示日志標簽值,battery_level是其對應(yīng)的文件描述 標簽值等于2722的日志內(nèi)容由三個值組成,它們分別是level、voltage和temperature level 、voltage和temperature的數(shù)據(jù)類型均是整數(shù)(1) level的單位是百分比(6) voltage和temperature的單位均為對象數(shù)量(1)2722 battery_le

6、vel (level|1|6),(voltage|1|1),(temperature|1|1)Android Logger驅(qū)動系統(tǒng)(續(xù)) 用戶空間日志庫Android Logger驅(qū)動系統(tǒng)(續(xù))_android_log_assert、_android_log_vprint、_android_log_print 寫入類型為main的日志記錄_android_log_btwrite、_android_log_bwrite 寫入類型為event的日志記錄_android_log_buf_print 寫入任意類型的日志記錄_android_log_write、_android_log_buf_writ

7、e 日志標簽以“RIL”開頭或者于“HTC_RIL”、“AT”、“GSM”、“STK”、“CDMA”、“PHONE”或“SMS”,那么會被認為是radio類型的日志記錄write_to_log 函數(shù)指針,負責最終的日志寫入 開始時指向_write_to_log_init 初始化成功后指向_write_to_log_kernel 初始化失敗后指向_write_to_log_nullAndroid Logger驅(qū)動系統(tǒng)(續(xù)) C/C+日志寫入接口 LOGV、LOGD、LOGI、LOGW、LOGE SLOGV、SLOGD、SLOGI、SLOGW、SLOGE LOG_EVENT_INT、LOG_EVE

8、NT_LONG、LOG_EVENT_STRING Java日志寫入接口 android.util.Log android.util.Slog android.util.EventLogAndroid Logger驅(qū)動系統(tǒng)(續(xù)) 日志讀取工具- logcat adb logcat -helpAndroid Binder驅(qū)動系統(tǒng) 傳統(tǒng)的IPC ,例如Pipe和Socket,執(zhí)行一次通信需要兩次數(shù)據(jù)拷貝 內(nèi)存共享機制雖然只需要執(zhí)行一次數(shù)據(jù)拷貝,但是它需要結(jié)合其它IPC來做進程同步,效率同樣不理想Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder是一種高效且易用的IPC機制 一次數(shù)據(jù)拷貝 Cli

9、ent/Server通信模型 既可用作進程間通信,也可用作進程內(nèi)通信Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder驅(qū)動為每一個進程分配4M的內(nèi)核緩沖區(qū),用作數(shù)據(jù)傳輸 4M內(nèi)核緩沖區(qū)所對應(yīng)的物理頁面是按需要分配的,一開始只有一個物理頁被被映射 4M內(nèi)核緩沖區(qū)所對應(yīng)的物理頁面除了映射在內(nèi)核空間之外,還會被映射在進程的用戶空間Android Binder驅(qū)動系統(tǒng)(續(xù)) 進程間的一次數(shù)據(jù)拷貝Android Binder驅(qū)動系統(tǒng)(續(xù)) Client/Server通信模型 Server進程啟動時,將在本進程內(nèi)運行的Service注冊到Service Manager中,并且啟動一個Binder線程

10、池,用來接收Client進程請求 Client進程向Service Manager查詢所需要的Service,并且獲得一個Binder代理對象,通過該代理對象即可向Service發(fā)送請求Android Binder驅(qū)動系統(tǒng)(續(xù)) Service注冊 BBinder:Service在用戶空間的描述 binder_node:Service在內(nèi)核空間的描述 binder_ref:Service代理在內(nèi)核空間的描述(一個整數(shù)句柄值)Android Binder驅(qū)動系統(tǒng)(續(xù)) Service代理獲取 BpBinder:Service代理在用戶空間的描述(一個整數(shù)句柄值)Android Binder驅(qū)動系

11、統(tǒng)(續(xù)) Service Manager注冊及其代理獲得 一個特殊Service,它的代理句柄值永遠等于0Android Binder驅(qū)動系統(tǒng)(續(xù)) Client和Server的通信過程Android Binder驅(qū)動系統(tǒng)(續(xù)) binder_transaction:通信數(shù)據(jù)描述Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder對象(flat_binder_object)的類型 BINDER_TYPE_BINDER BINDER_TYPE_WEAK_BINDER BINDER_TYPE_HANDLE BINDER_TYPE_WEAK_HANDLE BINDER_TYPE_FDAndroi

12、d Binder驅(qū)動系統(tǒng)(續(xù)) BINDER_TYPE_BINDER和BINDER_TYPE_WEAK_BINDER類型的flat_binder_object傳輸發(fā)生在:Server進程主動向Client進程發(fā)送Service (匿名Service )Server進程向Service Manager進程注冊Service BINDER_TYPE_HANDLE和BINDER_TYPE_WEAK_HANDLE類型的flat_binder_object傳輸發(fā)生在:一個Client向另外一個進程發(fā)送Service代理 BINDER_TYPE_FD類型的flat_binder_object傳輸發(fā)生在:一

13、個進程向另外一個進程發(fā)送文件描述符Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder驅(qū)動對類型BINDER_TYPE_BINDER 的Binder對象(flat_binder_object)的 處理: 在源進程中找到對應(yīng)的binder_node。如果不存在,則創(chuàng)建。 根據(jù)上述binder_node在目標進程中找到對應(yīng)的binder_ref。如果不存在,則創(chuàng)建。 增加上述binder_ref的強引用計數(shù)和弱引用計數(shù) 構(gòu)造一個類型為BINDER_TYPE_HANDLE的flat_binder_object對象。 將上述flat_binder_object對象發(fā)送給目標進程。Android B

14、inder驅(qū)動系統(tǒng)(續(xù)) Binder驅(qū)動對類型BINDER_TYPE_WEAK_BINDER 的Binder對象(flat_binder_object)的 處理: 在源進程中找到對應(yīng)的binder_node。如果不存在,則創(chuàng)建。 根據(jù)上述binder_node在目標進程中找到對應(yīng)的binder_ref。如果不存在,則創(chuàng)建。 增加上述binder_ref的弱引用計數(shù)。 構(gòu)造一個類型為BINDER_TYPE_WEAK_HANDLE的flat_binder_object對象。 將上述flat_binder_object對象發(fā)送給目標進程。Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder驅(qū)動

15、對類型BINDER_TYPE_HANDLE 的Binder對象(flat_binder_object)的 處理: 在源進程中找到對應(yīng)的binder_ref。 如果上述binder_ref所引用的binder_node所在進程就是目標進程: 增加上述binder_node的強引用計數(shù)和弱引用計數(shù) 構(gòu)造一個類型為BINDER_TYPE_BINDER的flat_binder_object 將上述flat_binder_object發(fā)送給目標進程 如果上述binder_ref所引用的binder_node所在進程不是目標進程: 為目標進程創(chuàng)建一個binder_ref,該binder_ref與上述bin

16、der_ref引用的是同一個binder_node 增加上述新創(chuàng)建的binder_ref的強引用計數(shù)和弱引用計數(shù) 構(gòu)造一個類型為BINDER_TYPE_HANDLE的flat_binder_object 將上述flat_binder_object發(fā)送給目標進程Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder驅(qū)動對類型BINDER_TYPE_WEAK_HANDLE 的Binder對象(flat_binder_object)的 處理: 在源進程中找到對應(yīng)的binder_ref。 如果上述binder_ref所引用的binder_node所在進程就是目標進程: 增加上述binder_node

17、的弱引用計數(shù) 構(gòu)造一個類型為BINDER_TYPE_WEAK_BINDER的flat_binder_object 將上述flat_binder_object發(fā)送給目標進程 如果上述binder_ref所引用的binder_node所在進程不是目標進程: 為目標進程創(chuàng)建一個binder_ref,該binder_ref與上述binder_ref引用的是同一個binder_node 增加上述新創(chuàng)建的binder_ref的弱引用計數(shù) 構(gòu)造一個類型為BINDER_TYPE_WEAK_HANDLE的flat_binder_object 將上述flat_binder_object發(fā)送給目標進程Android

18、 Binder驅(qū)動系統(tǒng)(續(xù)) Binder驅(qū)動對類型BINDER_TYPE_FD 的Binder對象(flat_binder_object)的 處理: 在源進程中找到對應(yīng)的struct file結(jié)構(gòu)體 將上述struct file結(jié)構(gòu)體 保存在目標進程的打開文件列表中 構(gòu)造一個類型為BINDER_TYPE_FD的flat_binder_object 將上述flat_binder_object發(fā)送給目標進程Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder對象的引用計數(shù) BBinder:位于用戶空間,通過智能指針管理,有mStrong和mWeak兩個引用計數(shù) BpBinder:位于用戶空間

19、,通過智能指針管理,有mStrong和mWeak兩個引用計數(shù) binder_node:位于內(nèi)核空間,有internal_strong_refs、local_weak_refs和local_strong_refs三個引用計數(shù),以及一個binder_ref引用列表refs binder_ref:位于內(nèi)核空間,有strong和weak兩個引用計數(shù)Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder對象之間的引用關(guān)系A(chǔ)ndroid Binder驅(qū)動系統(tǒng)(續(xù)) Binder對象引用關(guān)系小結(jié) BBinder被binder_node引用 binder_node被binder_ref引用 binder_r

20、ef被BpBinder引用 BBinder和BpBinder運行在用戶空間 binder_node和binder_ref運行在內(nèi)核空間 內(nèi)核空間足夠健壯,保證binder_node和binder_ref不會異常銷毀 用戶空間不夠健壯,BBinder和BpBinder可能會異常銷毀 BpBinder異常銷毀不會引發(fā)致命問題,但是BBinder異常銷毀會引發(fā)致命問題 需要有一種方式來監(jiān)控BBinder和BpBinder的異常銷毀Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder對象異常銷毀監(jiān)控 所有執(zhí)行Binder IPC的進程都需要打開/dev/binder文件 進程異常退出的時候,內(nèi)核保

21、證會釋放未正常關(guān)閉的它打開的/dev/binder文件,即調(diào)用與/dev/binder文件所關(guān)聯(lián)的release回調(diào)函數(shù) Binder驅(qū)動通過實現(xiàn)/dev/binder文件的release回調(diào)函數(shù)即可監(jiān)控Binder對象的異常銷毀,進而執(zhí)行清理工作Android Binder驅(qū)動系統(tǒng)(續(xù)) BBinder異常銷毀的時候,不單止Binder驅(qū)動需要執(zhí)行清理工作,引用了它的BpBinder所在的Client進程也需要執(zhí)行清理工作 需要有一種BBinder死亡通知機制 Client進程從Binder驅(qū)動獲得一個BpBinder Client進程向Binder驅(qū)動注冊一個死亡通知,該死亡通知與上述Bp

22、Binder所引用的BBinder相關(guān)聯(lián) Binder驅(qū)動監(jiān)控到BBinder所在進程異常退出的時候,檢查該BBinder是否注冊有死亡通知 Binder驅(qū)動向注冊的死亡通知所關(guān)聯(lián)的BpBinder所運行在的Client進程發(fā)送通知 Client進程執(zhí)行相應(yīng)的清理工作Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder線程池 在Server進程中,Client進程發(fā)送過來的Binder請求由Binder線程進行處理 每一個Server進程在啟動的時候都會創(chuàng)建一個Binder線程池,并且向里面注冊一個Binder線程 之后Server進程可以無限地向Binder線程池注冊新的Binder線程

23、 Binder驅(qū)動發(fā)現(xiàn)Server進程沒有空間的Binder線程時,會主動向Server進程請求注冊新的Binder線程 Binder驅(qū)動主動請求Server進程注冊新的Binder線程的數(shù)量可以由Server進程設(shè)置,默認是16Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder線程調(diào)度機制 在Binder驅(qū)動中,每一個Server進程都有一個todo list,用來保存Client進程發(fā)送過來的請求,這些請求可以由其Binder線程池中的任意一個空閑線程處理 在Binder驅(qū)動中,每一個Binder線程也有一個todo list,用來保存Client進程發(fā)送過來的請求,這些請求只可以由

24、該Binder線程處理 Binder線程沒事做的時候,就睡眠在Binder驅(qū)動中,直至它所屬的Server進程的todo list或者它自己的todo list有新的請求為止 每當Binder驅(qū)動將Client進程發(fā)送過來的請求保存在Server進程的todo list時,都會喚醒其Binder線程池的空閑Binder線程池,并且讓其中一個來處理 每當Binder驅(qū)動將Client進程發(fā)送過來的請求保存在Binder線程的todo list時,都會將其喚醒來處理Android Binder驅(qū)動系統(tǒng)(續(xù)) 默認情況下, Client進程發(fā)送過來的請求都是保存在Server 進程的todo lis

25、t中,然而有一種特殊情況: 源進程P1的線程A向目標進程發(fā)起了一個請求T1,該請求被分發(fā)給目標進程P2的線程B處理 源進程P1的線程A等待目標進程P2的線程B處理處理完成請求T1 目標進程P2的線程B在處理請求T1的過程中,需要向源進程P1發(fā)起另一個請求T2 源進程P1除了線程A是處于空閑等待狀態(tài)之外,還有另外一個線程C處于空閑等待狀態(tài) 這時候請求T2應(yīng)該分發(fā)給線程A處理,還是線程C處理? 如果分發(fā)給線程C處理,則線程A仍然是處于空閑等待狀態(tài) 如果分發(fā)給線程A處理,則線程 C可以處理其它新的請求Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder線程的事務(wù)堆棧Android Binder驅(qū)

26、動系統(tǒng)(續(xù))T1:From P1 to P2 BC_TRANSACTION:T1-from_parent = NULLT1-from = Thread(A)Thread(A)-transaction_stack = T1Thread(A)-proc = P1 BR_TRANSACTION:T1-to_parent = NULLT1-to_thread = Thread(B)Thread(B)- transaction_stack = T1T2:From P2 to P1 BC_TRANSACTION:T2-form_parent = T1T2-from = Thread(B)Thread(B)

27、-transaction_stack = T2Thread(B)-proc = P2 BR_TRANSACTIONT2-to_parent = T1T2-to_thread = Thread(A)Thread(A)-transaction_stack = T2Android Binder驅(qū)動系統(tǒng)(續(xù)) 同步請求優(yōu)先于異步請求 同一時刻,一個BBinder只能處理一個異步請求 第一個異步請求將被保存在目標進程的todo list中 第一個異步請求未被處理前,其它的異步請求將被保存在對應(yīng)的 binder_node的async todo list中 第一個異步請求被處理之后,第二個異步請求將從bin

28、der_node的async todo list轉(zhuǎn)移至目標進程的todo list等待處理 依次類推 此外,所有同時進行的異步請求所占用的內(nèi)核緩沖區(qū)大小不超過目標進程的總內(nèi)核緩沖區(qū)大小的一半Android Binder驅(qū)動系統(tǒng)(續(xù)) 與請求相關(guān)的三個線程優(yōu)先級 源線程的優(yōu)先級 目標線程的優(yōu)先級 目標binder_node的最小優(yōu)先級(注冊Service時設(shè)置) Binder線程處理同步請求時的優(yōu)先級 取源線程,目標binder_node,目標線程的最高優(yōu)先級 保證目標線程以不低于源線程優(yōu)先級或者binder_node最小優(yōu)先級的優(yōu)先級運行 Binder線程處理異步請求時的優(yōu)先級 取目標bind

29、er_node,目標線程的最高優(yōu)先級 保證目標線程以不低于binder_node最小優(yōu)先級的優(yōu)先級運行Android Binder驅(qū)動系統(tǒng)(續(xù)) Binder進程間通信機制的Java接口 每一個Java層的Binder本地對象(Binder)在C+層都對應(yīng)有一個JavaBBinder對象,后者是從C+層的BBinder繼承下來的 每一個Java層的Binder代理對象(BinderProxy)在C+層都對應(yīng)有一個BpBinder對象 于是Java層的Binder進程間通信實際上就是通過C+層的BpBinder和BBinder來進行的,與C+層的Binder進程間通信 一致Android Ashmem驅(qū)動系統(tǒng) 傳統(tǒng)的Linux共享內(nèi)存機制 System V:shmget、shmctl、shmat、shmdt 用一個整數(shù)ID來標志一塊共享內(nèi)存 不能動態(tài)釋放部分共享內(nèi)存 Posix:shm_open、ftruncate、mmap、munmap 用一個文件描述符來標一塊共享內(nèi)存 不能動態(tài)釋放部分共享內(nèi)存 Android匿名共享內(nèi)存 open、ioctl、mmap、munm

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論