Android硬件抽(chou)象層(ceng)(HAL)深入剖析(一)
時間:2018-09-26 來源:未知(zhi)
本(ben)文內容是(shi)基于Android4.0源碼分析得到。
android HAL是什么?為什么有它?
硬件抽(chou)象(xiang)層(ceng)(ceng)是介于android內核kernel和(he)上層(ceng)(ceng)之(zhi)間的(de)抽(chou)象(xiang)出來的(de)一層(ceng)(ceng)結構。他是對linux驅動的(de)一個封裝(zhuang),對上層(ceng)(ceng)提供統一接口(kou),上層(ceng)(ceng)應用不必知道(dao)下(xia)層(ceng)(ceng)硬件具體(ti)怎么實現(xian)工(gong)作(zuo)的(de),它屏蔽了底層(ceng)(ceng)的(de)實現(xian)細節。
它(ta)在(zai)整個(ge)android架構中(zhong)的位置如(ru)下(xia)圖所(suo)示:

傳(chuan)統(tong)的(de)(de)linux對硬件(jian)的(de)(de)操(cao)作基本上在內核空間的(de)(de)linux驅(qu)動(dong)程(cheng)序(xu)中實現了,那么(me)現在為(wei)什(shen)么(me)那么(me)多(duo)此一舉(ju)把對硬件(jian)的(de)(de)操(cao)作分為(wei)兩部分,hal和linux驅(qu)動(dong)呢?
而且hal屬于(yu)用(yong)戶空(kong)間(jian),linux驅動屬于(yu)內核(he)空(kong)間(jian)。其實并(bing)不多(duo)余。那么(me)為什么(me)要高出(chu)這么(me)個東西,理由是很多(duo)的:
1.谷歌搭好了(le)hal的(de)(de)框架(jia),為上層framework打通(tong)過(guo)jni調用hal提供了(le)統(tong)一(yi)的(de)(de)api,硬件開(kai)發商或者移(yi)植人員只需(xu)要(yao)按照框架(jia)開(kai)發即可(ke),無需(xu)話費精力在(zai)與上層的(de)(de)交互(hu)上的(de)(de)實現上,將(jiang)精力放在(zai)hal層本身的(de)(de)實現上即可(ke)。
2.從商業角度(du),許多硬件廠商不(bu)愿意將(jiang)自己硬件相關一(yi)(yi)些(xie)核(he)(he)心的(de)(de)東西(xi)開(kai)(kai)源(yuan)出去(qu),假(jia)如將(jiang)對自己硬件的(de)(de)驅動程(cheng)(cheng)序全部(bu)放入內(nei)核(he)(he)空(kong)間驅動程(cheng)(cheng)序實現,那么必須遵循(xun)GPL協議(yi),是必需開(kai)(kai)源(yuan)的(de)(de)。有(you)了HAL層之(zhi)(zhi)后,他們可以(yi)把一(yi)(yi)些(xie)核(he)(he)心的(de)(de)算法之(zhi)(zhi)類的(de)(de)東西(xi)的(de)(de)實現放在HAL層,而hal層位于用(yong)戶(hu)空(kong)間,不(bu)屬于linux內(nei)核(he)(he),和(he)android源(yuan)碼一(yi)(yi)樣遵循(xun)的(de)(de)是appache協議(yi),這(zhe)個(ge)是可以(yi)開(kai)(kai)源(yuan)或(huo)者不(bu)開(kai)(kai)的(de)(de)。
搞清楚了(le)hal的(de)存在意義,下面來根據hal層源碼(ma)分(fen)析一(yi)下hal到底(di)是(shi)怎么樣個架(jia)構和實現原(yuan)理,深入剖析一(yi)下。
android hal層的代碼主要位于(yu)/hardware/libhardware下面(mian)我們從上往下走。
在hal層(ceng)中(zhong),各類(lei)硬(ying)(ying)件(jian)的(de)(de)都是(shi)以(yi)硬(ying)(ying)件(jian)模塊的(de)(de)形式(shi)描述(shu)的(de)(de)hal層(ceng)中(zhong)是(shi)用hw_module_t結(jie)構(gou)體來(lai)描述(shu)的(de)(de),而每一(yi)類(lei)硬(ying)(ying)件(jian)模塊中(zhong)又有(you)各個獨立的(de)(de)硬(ying)(ying)件(jian),hal中(zhong)是(shi)用hw_device_t結(jie)構(gou)體來(lai)描述(shu)的(de)(de)。
上層app通過jni調用硬(ying)件(jian)時,首(shou)先得獲取到hw_module_t結構體,也即(ji)是硬(ying)件(jian)模(mo)塊,有了這(zhe)個才能再對硬(ying)件(jian)進行(xing)操作(zuo)。那(nei)么我們(men)來(lai)看(kan)(kan)看(kan)(kan)看(kan)(kan)看(kan)(kan)這(zhe)兩個結構體定(ding)義是什么樣子(zi)的。
它(ta)們的定義(yi)在(zai)/hardware/libhardware/include/hardware/hardware.h里面。
a. hw_module_t表示硬件模塊,它主要包(bao)含了一些硬件模塊的信(xin)息(xi),結構體的定義:
/**
* Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
* and the fields of this data structure must begin with hw_module_t
* followed by module specific information.
*/
typedef struct hw_module_t {
/** tag must be initialized to HARDWARE_MODULE_TAG */
uint32_t tag; //tag,根據(ju)引文注釋可(ke)以看到必(bi)須被初(chu)始化為HARDWARE_MODULE_TAG
/** major version number for the module */
uint16_t version_major;//主版本(ben)號
/** minor version number of the module */
uint16_t version_minor;//次版(ban)本(ben)號
/** Identifier of module */
const char *id;//模塊id字(zi)符串
/** Name of this module */
const char *name;//模塊(kuai)名
/** Author/owner/implementor of the module */
const char *author;//作者
/** Modules methods */
struct hw_module_methods_t* methods;//硬件模塊方法結構體
/** module's dso */
void* dso;//打開硬件(jian)模塊的庫時(shi)得到的句柄
/** padding to 128 bytes, reserved for future use */
uint32_t reserved[32-7];
} hw_module_t;
前面(mian)tag,name那幾個成員屬性就不說了(le),看(kan)(kan)(kan)了(le)注釋相信(xin)大家都(dou)知道(dao)了(le),下面(mian)看(kan)(kan)(kan)看(kan)(kan)(kan)hw_module_methods_t,這個指針methods它指向的(de)是與本硬件模塊相關的(de)方法的(de)結構體,里面(mian)不用(yong)看(kan)(kan)(kan)可以(yi)猜(cai)出肯(ken)定有一些函數(shu)指針,但(dan)是它里面(mian)只有一個函數(shu)指針。可以(yi)看(kan)(kan)(kan)看(kan)(kan)(kan)定義:
1 typedef struct hw_module_methods_t {
2 /** Open a specific device */
3 int (*open)(const struct hw_module_t* module, const char* id,//打(da)開(kai)硬件(jian)設備函(han)數指針
4 struct hw_device_t** device);
5 } hw_module_methods_t;
我們可以看到確實只有(you)一個函數指針,open它(ta)是打開硬件(jian)模塊中硬件(jian)設(she)備的函數。
然后是成(cheng)員void* dso,它是打(da)開硬件模(mo)塊相關的額設備之(zhi)后返回的句(ju)柄給它,這個在后面看(kan)hw_get_module函數源(yuan)碼的時(shi)候(hou)你(ni)就會明(ming)白。
b. 下面我(wo)們再來看看hw_device_t結構體,這個結構體主要是用來描(miao)述(shu)模塊(kuai)中硬件(jian)(jian)設(she)備的屬性(xing)信息什么的。一個硬件(jian)(jian)模塊(kuai)可(ke)能(neng)有多個硬件(jian)(jian)設(she)備。
比如說,傳感器模塊,sensor_module,是一個硬件模塊,但是手機中的傳感器就對應的有好多種,比如加速度acc_sensor,磁傳感器M_sensor等,那么他們都屬于sensor_module,但是他們有都有自己的hw_device_t結(jie)構體來描述。hw_device_t定(ding)義:
1 /**
2 * Every device data structure must begin with hw_device_t
3 * followed by module specific public methods and attributes.
4 */
5 typedef struct hw_device_t {
6 /** tag must be initialized to HARDWARE_DEVICE_TAG */
7 uint32_t tag; //設(she)備tag
8 /** version number for hw_device_t */
9 uint32_t version;//版本
10 /** reference to the module this device belongs to */
11 struct hw_module_t* module;//本設備歸屬的硬件模塊
12 /** padding reserved for future use */
13 uint32_t reserved[12];//保(bao)留
14 /** Close this device */
15 int (*close)(struct hw_device_t* device);//關閉設備的函數指(zhi)針
16 } hw_device_t;
其中(zhong),第(di)三個(ge)(ge)成(cheng)員module指向的(de)是這(zhe)個(ge)(ge)設備歸屬(shu)的(de)硬(ying)件模塊結(jie)構(gou)體。
后(hou)一個函(han)數(shu)指針close指向(xiang)的(de)肯(ken)定是(shi)關閉設(she)備的(de)函(han)數(shu)。
恩,到(dao)此(ci),hal的(de)主要的(de)兩個結(jie)構體(ti)講完了,下次(ci)我們(men)繼續,將結(jie)合(he)源(yuan)碼(ma),看(kan)看(kan)hal層(ceng)到(dao)底是(shi)怎(zen)(zen)么工作(zuo)的(de),看(kan)看(kan)上層(ceng)怎(zen)(zen)么獲取到(dao)硬件模塊,硬件設備(bei)的(de),到(dao)底是(shi)怎(zen)(zen)么加載解析動態共享庫的(de)。

