当前位置: 移动技术网 > IT编程>移动开发>Android > Android HAL层模块的加载过程

Android HAL层模块的加载过程

2018年03月17日  | 移动技术网IT编程  | 我要评论

曹秉局,羞辱尤娜,岭城兄弟电影

一、概述

HAL层是Android系统架构里介于Linux内核和系统运行库层之间的一个层,个人认为这个层存在的目的主要是为了避免GPL协议所带来的开源问题。Android系统会统一加载硬件抽象层模块,负责加载硬件抽象层模块的函数是hw_get_module函数。

二、hw_get_module

1、hw_get_module原型

在Android硬件抽象层中,负责加载硬件抽象层模块的函数是hw_get_module,当调用者需要加载这些模块时,只要指定它们的ID值就可以了。它的原型如下:

1 /**
2  * Get the module info associated with a module by id.
3  * @return: 0 == success, <0 == error and *pHmi == NULL
4  */
5 int hw_get_module(const char *id, const struct hw_module_t **module)
{
    return hw_get_module_by_class(id,NULL,module);
}

它有id和module两个参数。

id:输入参数,表示要加载的硬件抽象层模块ID; module:输出参数,如果加载成功,则它指向一个自定义的硬件抽象层模块结构体。 返回值:是一个整数,如果等于0,则表示加载成功;如果小于0,则表示加载失败。

2、hw_get_module函数的实现

该函数在Android源码位置如下:

hardware/libhardware/hardware.c

具体实现如下(可跳过不看):

01 /** Base path of the hal modules */
02 #define HAL_LIBRARY_PATH1 "/system/lib/hw"
03 #define HAL_LIBR ARY_PATH2 "/vendor/lib/hw"
04
05 static const char *variant_keys[] = {
06     "ro.hardware",  /* This goes first so that it can pick up a different
07                        file on the emulator. */
08     "ro.product.board",
09     "ro.board.platform",
10     "ro.arch"
11 };
12
13 static const int HAL_VARIANT_KEYS_COUNT =
14     (sizeof(variant_keys)/sizeof(variant_keys[0]));
15
16 int hw_get_module(const ch ar *id, const struct hw_module_t **module)
17 {
18     int status;
19     int i;
20     const struct hw_module_t *hmi = NULL;
21     char prop[PATH_MAX];
22     char path[PATH_MAX];
23
24     /*
25      * Here we rely on the fact that calling dlopen multiple times on
26      * the same .so will simply increment a refcount (and not load
27      * a new copy of the library).
28      * We also assume that dlopen() is thread-safe.
29      */
30
31     /* Loop through the configuration variants looking for a module */
32     for (i=0 ; i

前面提到,硬件抽象层模块文件实际上是一个动态链接库文件,即so文件。因此,第14行调用dlopen函数将它加载到内存中。加载完成这个动态链接库文件之后,第24行就调用dlsym函数来获得里面名称为HAL_MODULE_INFO_SYM_AS_STR的符号。这个HAL_MODULE_INFO_SYM_AS_STR符号指向的是一个自定义的硬件抽象层模块结构体,也就是获取了对应的硬件抽象层模块的所有信息。AL_MODULE_INFO_SYM_AS_STR是一个宏,它的值定义为“HMI”。根据硬件抽象层模块的编写规范,每一个硬件抽象层模块都必须包含一个名称为“HMI”的符号,而且这个符号的第一个成员变量的类型必须定义为hw_module_t,因此,第24行可以安全地将模块中的HMI符号转换为一个hw_module_t结构体指针。 获得了这个hw_module_t结构体指针之后,第32行调用strcmp函数来验证加载得到的硬件抽象层模块ID是否与所要求加载的硬件抽象层模块ID一致。如果不一致,就说明出错了,函数返回一个错误值-EINVAL。最后,第38行将成功加载后得到的模块句柄值handle保存在hw_module_t结构体指针hmi的成员变量dso中,然后将它返回给调用者。

至此,HAL层的一个模块加载完毕。

四、小结

硬件抽象层加载一个模块无非就是:

调用者传目标模块的ID参数到加载函数 。 获取目标模块的存储路径。 检查该路径下是否有该模块的.so文件。 加载模块至内存。 将句柄返回给调用者。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网