The previous analysis shows how the android HAL layer searches for the dynamic shared library of hardware modules. In fact, it is to find the shared library modueid under the two paths of "system/lib/hw /" or "/ vendor/lib/hw /" variant. After so, load the library by calling the load function.
Now let's enter the load function to see how to load the shared library.
The following is the definition of the load function, also in / hardware / libhardware / hardware Implemented in C,
/** * Load the file defined by the variant and if successful * return the dlopen handle and the hmi. * @return 0 = success, !0 = failure. */ static int load(const char *id, const char *path, const struct hw_module_t **pHmi) {//Pass in the hardware module id and the path where the library is located to obtain the hardware module structure int status; void *handle; struct hw_module_t *hmi; /* * load the symbols resolving undefined symbols before * dlopen returns. Since RTLD_GLOBAL is not or'd in with * RTLD_NOW the external symbols will not be global */ handle = dlopen(path, RTLD_NOW);//Open shared library if (handle == NULL) { char const *err_str = dlerror(); LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown"); status = -EINVAL; goto done; } /* Get the address of the struct hal_module_info. */ const char *sym = HAL_MODULE_INFO_SYM_AS_STR; hmi = (struct hw_module_t *)dlsym(handle, sym);//Resolve shared library if (hmi == NULL) { LOGE("load: couldn't find symbol %s", sym); status = -EINVAL; goto done; } /* Check that the id matches */ if (strcmp(id, hmi->id) != 0) {//Match and analyze whether the id of the hardware module is consistent with the module id we actually want to get LOGE("load: id=%s != hmi->id=%s", id, hmi->id); status = -EINVAL; goto done; } hmi->dso = handle; //Pass the handle obtained by opening the library to the dso of the hardware module /* success */ status = 0; done: if (status != 0) { hmi = NULL; if (handle != NULL) { dlclose(handle); handle = NULL; } } else { LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p", id, path, *pHmi, handle); } *pHmi = hmi;//Pass the result of the obtained module to HW through the third parameter_ module_ t return status; }
You can see several parameters passed in by the load function. The first parameter is the id of the hardware module of the dynamic library corresponding to the hardware module to be loaded,
The second parameter is the path of dynamic inventory, which is in HW_ get_ The path obtained by searching the library in the first part of the module function,
The third parameter is the hardware module structure we need to get, which is passed to hw_get_module,hw_ get_ The module function is passed to jni through parameters.
In line 19, first call dlopen to open the shared library. This function finds the library through the path of the incoming library, opens it, and returns an operation handle. Then call dlsym function to parse the open library. In line 29 below, get the hardware module structure contained in the library and return it. Therefore, hardware manufacturers or hardware transplanters must fill the hardware module structure related to their own hardware according to the architecture of hal hw_module_t. For use.
After dlsym parsing, HW is obtained_ module_ t. Then, in line 37, compare the id in the structure parsed from the library with the id passed in to see whether it is consistent.
If it is consistent, it is proved that the correct hardware module is obtained.
Finally, on line 60, add hw_module_t structure pointer is passed to the third parameter and hw_get_module function.
Here, hw_get_module function to get the hardware module structure hw_module_t.
With hw_module_t. Then the device corresponding to the hardware module can be opened through its internal method open, and the hardware device can be operated through some methods in the structure.