原文出處: http://fanli7.net/a/JAVAbiancheng/shejimoshi/20130218/308209.html
Android Telephony涉及的框架結構如圖1所示。
圖1 Android Telephony框架結構
通過圖1可以發現Android Telephony框架結構的一些規律,具體如下。
1 系統運行庫層的HAL層
HAL(Hardware Abstraction Layer,硬件抽象層)在Linux和Windows操作系統平台下有不同的實現方式。
Windows下的HAL位於操作系統的最底層,它直接操作物理硬件設備,使用抽象接口來隔離不同硬件的具體實現,为上層的操作系統和設備驅動程序提供一個統一接口,起到對硬件的抽象作用。這样更換硬件時,編寫硬件的驅動只要實現符合HAL定義的標准接口即可,而上層應用並不會受到影響,不必關心具體來實現的是什麼硬件。
Linux 下的HAL與Windows下的HAL不太一样,HAL並不是位於操作系統的最底層直接操作硬件,相反,它位於操作系統核心層和驅動程序之上,是一個運行在User Space用戶空間中的服務程序。
2 簡析HAL結構
通過前面的學習,我們知道Android是基於Linux Kernel的開源智能手機操作系統,所以在這裏重點介紹Linux下的HAL,就不單獨介紹Windows下的HAL結構了。
要想知道HAL結構,先看看來自於HAL 0.4.0 Specification的框架圖吧,如圖1-4所示(引用自http://people.redhat.com/davidz/hal-spec/hal-spec.html)。
圖2 HAL 0.4.0 Specification框架結構
HAL是一個位於操作系統和驅動程序之上,運行在用戶空間中的服務程序。其目的是为上層應用提供一個統一的查詢硬件設備的接口。我們都知道,抽象就是为了隔離變化,那麼這裏的HAL可以帶给我們什麼?首先,有了HAL接口,可以提前開始應用的開發,而不必關心具體實現的是什麼硬件;其次,硬件廠家如果需要更改硬件設備,只要按照HAL接口規範和標准提供對應的硬件驅動,而不需要改變應用;最後,HAL簡化了應用程序查詢硬件的邏輯,把這一部分的复雜性轉移给HAL統一處理,這样當一些應用程序使用HAL時,可以把對不同硬件的實際操作的复雜性也交给不同硬件廠家提供的庫函數來處理。
總之,HAL所謂的抽象並不提供對硬件的實際操作,對硬件的操作仍然由具體的驅動程序來完成。
3 Android为什麼引入HAL
HAL的一些優勢在前面章節已經提到,這裏回顧一下。Android引入HAL不僅因为其自身的優勢,而且還有一個非常重要的原因,就是为了保障在Android平台基於Linux開發的硬件驅動和應用程序不必遵循GPL(General Public License)許可而保持封閉,這保障了更多廠家的利益。我們都知道,Linux Kernel是開源的而且遵循GPL許可證,根據GPL許可證規定,對源碼的任何修改都必須向社會開源。
那麼Android是如何做到的呢?Linux Kernel和Android的許可證不一样,Linux Kernel是GPL許可證,Android是ASL(Apache Software License)許可證。ASL許可證規定,可以隨意使用源碼,不必開源,所以建立在Android之上的硬件驅動和應用程序都可以保持封閉。也就是說,只要把關鍵的驅動處理相關的主要邏輯轉移到Android平台內,在LinuxKernel中僅保留基礎的通信功能,即使開源一部分代碼,對廠家來講也不會有什麼損失。
Google選擇了這样做,並且特意修改Kernel,原本應該包括在Linux Kernel中的某些驅動關鍵處理邏輯,被轉移到了HAL層之中而達到了不必開源的目的。
4 Android中HAL的運行結構
Android源碼中實現了一部分HAL,包括Wi-Fi、GPS、RIL、Sensor等,這些代碼主要儲存於以下目錄:
在Android中,HAL的運行機制是什麼样的呢?它有兩種運行機制,老式HAL和新式HAL,如圖3所示。
圖3 Android中HAL兩種運行結構
從圖3中不難看出,左邊是老的HAL結構,應用或框架通過so動態鏈接庫調用而達到對硬件驅動的訪問。在so動態鏈接庫裏,實現了對驅動的訪問邏輯處理。我們重點學習和理解HAL Stub方式, RIL也采用了此方式的設計思想。
HAL Stub 是一種Proxy代理概念,Stub雖然仍是以 *.so 的形式存在,但 HAL 已經將 *.so 的具體實現隱藏了起來。 Stub 向 HAL 提供operations方法,Runtime通過Stub提供的so獲取它的 operations方法,並告知Runtime的callback方法。這样Runtime和Stub都有對方調用的方法,一個應用的請求通過Runtime調用Stub的operations方法,而Stub響應operations方法並完成後,再調用Runtime的callback方法進行返回。這裏可能有一點繞,根據前面的描述再結合圖4所示會更容易理解。
圖4 HAL Stub結構
上層通過HAL提供的functions調用底層硬件,而底層硬件處理完成上層請求後或硬件狀態發生變化後,HAL層通過Runtime提供的callback接口回調上層應用。
HAL Stub 有一種包含關系,即 HAL 裏包含了很多的 Stub。 Runtime 只要說明請求類型,就可以取得並操作Stub對應的operations。其實現主要在 hardware.c 和 hardware.h 文件中,實質也是通過dlopen方法加載 .so動態鏈接庫,從而呼叫 *.so 裏的符號( symbol )實現。
------------------------------
本文節選自《深入理解Android : Telephony原理剖析與最佳實踐》,作者:楊青平。
|