這個函數的主要功能是根據模塊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 }