Android硬件抽象層(HAL)深入剖析(二)

上一篇我們分析了android HAL層的主要的兩個(gè)結(jié)構(gòu)體hw_module_t(硬件模塊)和hw_device_t(硬件設(shè)備)的成員,下面我們來(lái)具體看看上層app到底是怎么實(shí)現(xiàn)操作硬件的?

我們知道网沾,一些硬件廠(chǎng)商不愿意將自己的一些核心代碼開(kāi)放出去盼玄,所以將這些代碼放到HAL層蚂子,但是怎么保證它不開(kāi)放呢?HAL層代碼不是也讓大家知道下載嗎?其實(shí)硬件廠(chǎng)商的HAL核心代碼是以共享庫(kù)的形式出現(xiàn)的萌庆,每次在需要的時(shí)候燥透,hal會(huì)自動(dòng)加載調(diào)用相關(guān)共享庫(kù)沙咏。那么是怎么加載找到某一硬件設(shè)備對(duì)應(yīng)的共享庫(kù)的呢?這也是我們這篇都要說(shuō)的辨图。

上層app通過(guò)jni調(diào)用hal層的hw_get_module函數(shù)獲取硬件模塊,這個(gè)函數(shù)是上層與hal打交道的入口肢藐。所以如果我們以程序調(diào)用執(zhí)行的流程去看源碼的話(huà)故河,這個(gè)函數(shù)就是hal層第一個(gè)被調(diào)用的函數(shù),下面我們就

從這個(gè)函數(shù)開(kāi)始吆豹,沿著程序執(zhí)行的流程走下去鱼的。

hw_get_module函數(shù)定義在/hardware/libhardware/hardware.c中,打開(kāi)這個(gè)文件可以看到定義如下:

1 int hw_get_module(const char *id, const struct hw_module_t **module)

2 {

3 int status;

4 int i;

5 const struct hw_module_t *hmi = NULL;

6 char prop[PATH_MAX];

7 char path[PATH_MAX];

8

9 /*

10 * Here we rely on the fact that calling dlopen multiple times on

11 * the same .so will simply increment a refcount (and not load

12 * a new copy of the library).

13 * We also assume that dlopen() is thread-safe.

14 */

15

16 /* Loop through the configuration variants looking for a module */

17 for (i=0 ; i

18 if (i < HAL_VARIANT_KEYS_COUNT) {

19 if (property_get(variant_keys[i], prop, NULL) == 0) {//獲取屬性

20 continue;

21 }

22 snprintf(path, sizeof(path), "%s/%s.%s.so",

23 HAL_LIBRARY_PATH1, id, prop);

24 if (access(path, R_OK) == 0) break;//檢查system路徑是否有庫(kù)文件

25

26 snprintf(path, sizeof(path), "%s/%s.%s.so",

27 HAL_LIBRARY_PATH2, id, prop);

28 if (access(path, R_OK) == 0) break;//檢查vender路徑是否有庫(kù)文件

29 } else {

30 snprintf(path, sizeof(path), "%s/%s.default.so",//如果都沒(méi)有痘煤,則使用缺省的

31 HAL_LIBRARY_PATH1, id);

32 if (access(path, R_OK) == 0) break;

33 }

34 }

35

36 status = -ENOENT;

37 if (i < HAL_VARIANT_KEYS_COUNT+1) {

38 /* load the module, if this fails, we're doomed, and we should not try

39 * to load a different variant. */

40 status = load(id, path, module);//裝載庫(kù)凑阶,得到module

41 }

42

43 return status;

44 }

看第一行我們知道有兩個(gè)參數(shù),第一參數(shù)id就是要獲取的硬件模塊的id速勇,第二個(gè)參數(shù)module就是我們想得到的硬件模塊結(jié)構(gòu)體的指針晌砾。

所以可以看出,上層首先給hal需要獲取的硬件模塊的id烦磁,hw_get_module函數(shù)根據(jù)這個(gè)id去查找匹配和這個(gè)id對(duì)應(yīng)的硬件模塊結(jié)構(gòu)體的养匈。

下面看看怎么找的。

17行有個(gè)for循環(huán)都伪,上限是HAL_VARIANT_KEYS_COUNT+1呕乎,那么這個(gè)HAL_VARIANT_KEYS_COUNT是什么呢?查看同文件下找到有:

static const int HAL_VARIANT_KEYS_COUNT =

(sizeof(variant_keys)/sizeof(variant_keys[0]));

原來(lái)它是ariant_keys這個(gè)數(shù)組的元素個(gè)數(shù)。那么這個(gè)數(shù)組又是什么呢?在本文件找陨晶,有:

/**

* There are a set of variant filename for modules. The form of the filename

* is ".variant.so" so for the led module the Dream variants

* of base "ro.product.board", "ro.board.platform" and "ro.arch" would be:

*

* led.trout.so

* led.msm7k.so

* led.ARMV6.so

* led.default.so

*/

static const char *variant_keys[] = {

"ro.hardware", /* This goes first so that it can pick up a different

file on the emulator. */

"ro.product.board",

"ro.board.platform",

"ro.arch"

};

可以看到它其實(shí)是個(gè)字符串?dāng)?shù)組猬仁。站且不知道干什么的。繼續(xù)看hw_get_module函數(shù)先誉,進(jìn)入for循環(huán)里面湿刽,看22行,其實(shí)它是將HAL_LIBRARY_PATH1, id, prop這三個(gè)串拼湊一個(gè)路徑出來(lái)褐耳,

HAL_LIBRARY_PATH1定義如下:

/** Base path of the hal modules */

#define HAL_LIBRARY_PATH1 "/system/lib/hw"

#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"

id是上層提供的诈闺,prop這個(gè)變量的值是前面19行property_get(variant_keys[i], prop, NULL)函數(shù)獲取到的,其實(shí)這個(gè)函數(shù)是通過(guò)ariant_keys數(shù)組的的屬性查找到系統(tǒng)中對(duì)應(yīng)的變種名稱(chēng)铃芦。不同的平臺(tái)獲取到prop值是不一樣的雅镊。

假如在獲取到的prop值是tout,需要獲取的硬件模塊的id是leds刃滓,那么最后path組成的串是/system/lib/hw/leds.tout.so仁烹。

后面24行access是檢查這個(gè)路徑下是否存在,如果有就break咧虎,跳出循環(huán)卓缰。如果沒(méi)有,繼續(xù)走下面,

可以看到下面幾行和剛才形式差不多征唬,

snprintf(path, sizeof(path), "%s/%s.%s.so", HAL_LIBRARY_PATH2, id, prop);

if (access(path, R_OK) == 0) break;//檢查vender路徑是否有庫(kù)文件

結(jié)合 HAL_LIBRARY_PATH2 為"/vendor/lib/hw"震叮,假設(shè)同樣獲取到的prop值是tout,需要獲取的硬件模塊的id是leds鳍鸵,這種情況下path拼出來(lái)的值是/vender/lib/hw/leds.tout.so,然后在判斷文件是否存在。如果存在跳出循環(huán)尉间。

從以上分析偿乖,其實(shí)這就是hal層搜索動(dòng)態(tài)共享庫(kù)的方式,從中我們可以得到兩點(diǎn):

1.動(dòng)態(tài)共享庫(kù)一般放在 "/system/lib/hw"和"/vendor/lib/hw"這兩個(gè)路徑下哲嘲。

2.動(dòng)態(tài)庫(kù)的名稱(chēng)是以"id.variant.so"的形式命名的贪薪,其中id為上層提供,中間variant為變種名稱(chēng)眠副,是隨系統(tǒng)平臺(tái)變化的画切。

接著,從29到32行我們可以看到囱怕,當(dāng)所有變種名稱(chēng)形式的包都不存在時(shí)霍弹,就以"id.default.so"形式包名查找是否存在。

37行娃弓, if (i < HAL_VARIANT_KEYS_COUNT+1)典格,如果i小于變種名稱(chēng)數(shù)組的話(huà),表示找到了對(duì)應(yīng)的庫(kù)台丛,那么38行l(wèi)oad(id, path, module);//裝載庫(kù)耍缴,得到module。

以上就對(duì)hal層搜索庫(kù)的規(guī)則搞清楚了挽霉。


更多專(zhuān)業(yè)內(nèi)容可參考:http://www.embedu.org/Column/6997.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末防嗡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子侠坎,更是在濱河造成了極大的恐慌蚁趁,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硅蹦,死亡現(xiàn)場(chǎng)離奇詭異荣德,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)童芹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)涮瞻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人假褪,你說(shuō)我怎么就攤上這事署咽。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵宁否,是天一觀(guān)的道長(zhǎng)窒升。 經(jīng)常有香客問(wèn)我,道長(zhǎng)慕匠,這世上最難降的妖魔是什么饱须? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮台谊,結(jié)果婚禮上蓉媳,老公的妹妹穿的比我還像新娘。我一直安慰自己锅铅,他們只是感情好酪呻,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著盐须,像睡著了一般玩荠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贼邓,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天阶冈,我揣著相機(jī)與錄音,去河邊找鬼立帖。 笑死眼溶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晓勇。 我是一名探鬼主播堂飞,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼绑咱!你這毒婦竟也來(lái)了绰筛?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤描融,失蹤者是張志新(化名)和其女友劉穎铝噩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體窿克,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骏庸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了年叮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片具被。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖只损,靈堂內(nèi)的尸體忽然破棺而出一姿,到底是詐尸還是另有隱情七咧,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布叮叹,位于F島的核電站艾栋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蛉顽。R本人自食惡果不足惜蝗砾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望携冤。 院中可真熱鬧遥诉,春花似錦、人聲如沸噪叙。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)睁蕾。三九已至,卻和暖如春债朵,著一層夾襖步出監(jiān)牢的瞬間子眶,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工序芦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留臭杰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓谚中,卻偏偏與公主長(zhǎng)得像渴杆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宪塔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 上一篇我們分析了androidHAL層的主要的兩個(gè)結(jié)構(gòu)體hw_module_t(硬件模塊)和hw_device_t...
    donnahn閱讀 637評(píng)論 0 1
  • Android HAL概述 Android HAL(Hardware Abstract Layer)硬件抽象層磁奖,從...
    諾遠(yuǎn)閱讀 29,776評(píng)論 2 27
  • 硬件廠(chǎng)商處于保護(hù)核心代碼,會(huì)將核心實(shí)現(xiàn)以so庫(kù)的形式出現(xiàn)在HAL層某筐,當(dāng)需要時(shí)HAL會(huì)自動(dòng)調(diào)用相關(guān)的共享庫(kù)比搭。 共享庫(kù)...
    Galileo_404閱讀 1,909評(píng)論 0 3
  • 眾所周知,現(xiàn)代的計(jì)算機(jī)系統(tǒng)由硬件系統(tǒng)以及軟件系統(tǒng)兩個(gè)部分組成南誊,再好的硬件身诺,如果沒(méi)有軟件的支持,就不能發(fā)揮其應(yīng)有的作...
    哲影閱讀 2,862評(píng)論 0 5
  • 午間要下班了抄囚,站在鏡子前照了照霉赡,喃喃自語(yǔ),“白頭發(fā)好象又多了怠苔,沒(méi)招巴!” C抬頭看我,“你怎么又不堅(jiān)持梳頭了迫肖?” ...
    鉛筆芒種閱讀 191評(píng)論 0 1