android HAL淺探


又挖一個坑,好久沒寫了,看得代碼多而繁亂,又沒有專精一塊,到頭來還是困惑叢生,不管了,做個筆記,寫寫自己對android hal層的一點理解。

涉及的代碼來自android-4.0版本。

1.概念和原因

android hal的概念和存在的原因,不必多說,其實就兩點。1.隔離具體驅動接口的變化,2.保護硬件廠商的關鍵信息。

通過這一層的封裝

1.各類硬件(fb,gps,sensor)只需要實現規定的接口即可,驅動接口的不兼容(比如各種硬件設備的ioctl,很可能是廠商自己規定的命令),可以隔離變化。

2.硬件廠商在封裝的接口,只需提供一個so即可,使用時,用dlopen hook到相關的接口,不用開放源代碼,可以保護一些敏感信息。

總體來說,這層位於kernel/driver之上,framework層之下。

(都是廢話,沒有干貨,呵呵)

2.硬件相關代碼位置

在hardware/libhardware/include/hardware目錄里面,可以看到目前使用這種方式抽象的硬件種類大致有如下幾種。(btw,android貌似還有另外的方式操作硬件,具體的我沒看明白,貌似wifi的方式就不太一樣,好像是通過協議棧來操作的,對這塊不熟悉,只是隨便看了看)

audio(聲卡,我姑且這么叫,這塊驅動層次都有若干標准,讓人頭暈眼花,比如oss/alsa/jack/等等等。。。這還不是最可惡的,他們還可以互為后端,比oss接口封裝成alsa,或者反過來,我去。。。)

camera(攝像頭,不多說, 主要我也不太懂,這塊linux到是有標准接口,v4l2--->video for linux 2,移植所需要做的工作就是把v4l2接口封裝成android規定的,呵呵)

gps(定位,這個真是一點沒研究過了)

sensor(傳感器,指南針,重力加速度,壓力,位置,。。。)

lights(背光,調節背光強弱的)

display(顯示相關的幾個設備,fb-->framebuffer,應該對應的是屏幕,僅僅是屏幕,不包括顯存,gralloc這個設備,才對應的是真正的顯存及其操作,hwcomposer,其實就是overlay了,播放視頻時需要,ps:這里的display僅僅指lcd,不包括hdmi,vga等等,呵呵)

 3.display設備被調用的方式

我主要看了display所需要的硬件設備,其他設備,精力和興趣的原因,沒有多看。

android display最終的顯示的數據都會交給surfaceflinger(直譯,屏幕投遞者,呵呵),所以操作display硬件的代碼這里一定會有。

在framework/base/services/surfaceflinger/displayhardware目錄下面,封裝了這部分接口,我們可以通過研究這塊接口封裝,來看到具體硬件是如何被抽象的。

首先,我對surfaceflinger也沒非常通徹的理解,只了解一個大概,所以,我只說流程,不說細節。

1.先看surfaceflinger構造函數能不能發現什么,貌似沒有發現new displayhardware之類的語句,那這些操作在哪里?我們知道surfaceflinger從Thread和sp繼承,那還有兩個地方可以去瞧瞧。

1).onfirstref,sp模板構造出來的類,這個函數是首先會被調用的,不過貌似這里也沒有,只有一個run(啟動線程)

2).readyToRun,這個函數,在run之前一定會被調用一把的,進去一看,發現我們想要的DisplayHardware* const hw = new DisplayHardware(this, dpy)語句,哈哈,這里構造了display硬件的對應的類。

2.DisplayHardware構造函數

這個類上面所說的三類硬件,又歸結了兩類,

1).FramebufferNativeWindow(這個對應了fb與gralloc,抽象的具體代碼在framework/base/libs/ui,這個庫里面包括了ui相關所有東西,顯示,輸入消息,按鍵映射等等),

2).HWComposer(這個對應了hwcomposer)

(感覺都是一堆廢話,都明白的東西,居然還沒講到如何調用)

好吧,我們再簡單一點,直接進去看hwcomposer是如何調用的

hardware.h里面給了兩個函數,

hw_get_module

hw_get_module_by_class

具體就是,你傳一個硬件id(每種硬件,對應一個id,id是字符串,各不相同)下來,我把這個module對應的接口給你。

來看hwcomposer的構造函數。里面調用了hw_get_module,他對應的id是HWC_HARDWARE_MODULE_ID,

在hardware/libhardware/include/hwcomposer.h看到 #define HWC_HARDWARE_MODULE_ID "hwcomposer"

同時其他對應的文件里面,fb的id是      #define GRALLOC_HARDWARE_FB0 "fb0"

        gralloc的id是    #define GRALLOC_HARDWARE_MODULE_ID "gralloc"

我們看看最關鍵的地方hw_get_module是如何實現的。這個關鍵點在於load函數。

load函數dlopen相關的vendor庫,然后通過dlsym找一個HAL_MODULE_INFO_SYM_AS_STR的全局變量(#define HAL_MODULE_INFO_SYM_AS_STR  "HMI",其實就是對應了HAL_MODULE_INFO_SYM這個)

這個我認為是最關鍵的點,就找這個全局變量,所有設備編譯出來的so庫,都要包括這個hmi的變量,可以通過查看代碼來驗證這個猜測。

這個地方找到之后,就完全了軟硬件合體了。

這里不僅可以找到common的open接口,也可以找到各種私有接口,

比如fb就規定了六個接口

int (*setSwapInterval)(struct framebuffer_device_t* window,int interval);

int (*setUpdateRect)(struct framebuffer_device_t* window,int left, int top, int width, int height);

int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer);

int (*compositionComplete)(struct framebuffer_device_t* dev);

void (*dump)(struct framebuffer_device_t* dev, char *buff, int buff_len);

int (*enableScreen)(struct framebuffer_device_t* dev, int enable);

底層實現這幾個接口即可。

看完overlay硬件的抽象方式,再按這個思路去看fb,gralloc,gps,會發現他們的過程完全一致。也許大家一直這么做的,但是我是從android里面知道這樣的隔離變化方案的,很好很強大。謝謝谷歌。

over。

有點亂,過程就是這樣了,自己的筆記,不喜勿噴。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM