android中hw_get_module函數分析

這個函數的主要功能是根據模塊ID尋找硬件模塊動態鏈接庫德地址,然後調用load去打開動態鏈接庫並從中獲取硬件模塊結構體地址。具體的源碼如下:

代碼@/hardware/libhardware/hardware.c

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

120 {

121     int status;

122     int i;

123     const struct hw_module_t *hmi = NULL;

124     char prop[PATH_MAX];

125     char path[PATH_MAX];

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

135     for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {

/*

*這個地方我們來看一下下面將要用到的一個數組variant_keys,因爲HAL_VARIANT_KEYS_COUNT這個就是

*數組variant_keys的大小。

*

*44 static const char *variant_keys[] = {

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

* 46                        file on the emulator. */

* 47     "ro.product.board",

* 48     "ro.board.platform",

*  49     "ro.arch"

* 50 };

*這裏我們記住這個數組,下面我就將用到它。 

*/

136         if (i < HAL_VARIANT_KEYS_COUNT) {

137             if (property_get(variant_keys[i], prop, NULL) == 0) {

138                 continue;

139             }

/*

*這個地方prop得到的就似乎相應的權限,variant_keys[i]對應的如下:

*

*trout\msm7k\ARMV6就是這三個值,那個ro.hardware沒有找到。這個地方我也是看註冊的,沒有弄懂

*知道的同學指教一些,謝謝。

*/

140             snprintf(path, sizeof(path), "%s/%s.%s.so",//把相應的路徑及文件名保存到path中

141                     HAL_LIBRARY_PATH, id, prop);

/*

*看到沒有,這個地方其實就是把HAL_LIBRARY_PATH/id.***.so保存到path中,其中***就是上面我們所分析的variant_keys各個元素所對應的值。

*/

142         } else {

/*

*這個地方就體現了爲什麼我們上面for循環用的是HAL_VARIANT_KEYS_COUNT+1而不是*HAL_VARIANT_KEYS_COUNT。因爲我們在最後還有加載一個default的屬性。

*/

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

144                     HAL_LIBRARY_PATH, id);

145         }

146         if (access(path, R_OK)) {

147             continue;

148         }

149         /* we found a library matching this id/variant */

150         break;

151     }

152

153     status = -ENOENT;

154     if (i < HAL_VARIANT_KEYS_COUNT+1) {

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

156          * to load a different variant. */

157         status = load(id, path, module);//load相應庫。並把它們的HMI保存到module中。//具體見西分析

158     }

159

  return status;

161 }

 

代碼@/hardware/libhardware/hardware.c

這個代碼其實很簡單。load相應庫。並把它們的HMI保存到module中

0 static int load(const char *id,

 61         const char *path,

 62         const struct hw_module_t **pHmi)

 63 {

 64     int status;

 65     void *handle;

 66     struct hw_module_t *hmi;

   handle = dlopen(path, RTLD_NOW);//打開相應的庫

 74     if (handle == NULL) {

 75         char const *err_str = dlerror();

 76         LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");

 77         status = -EINVAL;

 78         goto done;

 79     }

 

 82     const char *sym = HAL_MODULE_INFO_SYM_AS_STR;

 83     hmi = (struct hw_module_t *)dlsym(handle, sym);//找到庫中的HMI函數的地址(據snownight0102說,HMI不是一個函數,我還不是很清楚,等待解釋)

 84     if (hmi == NULL) {

 85         LOGE("load: couldn't find symbol %s", sym);

 86         status = -EINVAL;

 87         goto done;

 88     }

 89

 90     /* Check that the id matches */

 91     if (strcmp(id, hmi->id) != 0) {//只是一個check

 92         LOGE("load: id=%s != hmi->id=%s", id, hmi->id);

 93         status = -EINVAL;

 94         goto done;

 95     }

 96

 97     hmi->dso = handle;

 98

 99     /* success */

100     status = 0;

    done:

103     if (status != 0) {

104         hmi = NULL;

105         if (handle != NULL) {

106             dlclose(handle);

107             handle = NULL;

108         }

109     } else {

110         LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",

111                 id, path, *pHmi, handle);

112     }

113

114     *pHmi = hmi;//把這個返回過去

115

116     return status;

117 }

發佈了13 篇原創文章 · 獲贊 13 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章