struct hw_module_t HAL_MODULE_INFO_SYM
Hal层的库文件是怎么被上层调用的?上层调用时的入口(相当于main)又是什么呢?它就是HAL_MODULE_INFO_SYM。
下gps.default.so库为例子,上层gpstest.apk打开后,会在/system/lib/hw/下面寻找gps.default.so(也可能是gps.$(platform).so)的这个库,gps.defualt.so的入口就是HAL_MODULE_INFO_SYM, 从此再去调用hal层里的open,init,write,read等接口,hal再通过这个接口去设备结点读写。
通过linux提供的系统调用接口
dlopen去打开对应的动态链接库之后
handle = dlopen(path, RTLD_NOW);
通过dlsym去寻找HAL_MODULE_INFO_SYM_AS_STR名字的结构体
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);
而 HAL_MODULE_INFO_SYM_AS_STR 在\hardware\libhardware\include\hardware\hardware.h中定义的一个字符串, dlsym通过字符串去寻找与该字符串相同名字的结构体。
/**
* Name of the hal_module_info
*/
#define HAL_MODULE_INFO_SYM HMI
/**
* Name of the hal_module_info as a string
*/
#define HAL_MODULE_INFO_SYM_AS_STR "HMI"
所以每一个HAL module 都使用HAL_MODULE_INFO_SYM作为xxx_module_t的结构体名称,就是通过dlsym去寻找这个统一的名称,因为一个HAL module,只有一个xxx_module_t。
hw_module_t 必须在第一个的原因也是因为在dlsym 找到 xxx_module_t 以后,返回的地址是xxx_module_t 地址,也是第一个变量的地址,也就是hw_module_t 模块,这样就能调用 module 的 open 函数,去找到xxx _device_t,hw_device_t必须要在第一个的原因也是如此。