千家信息网

Android中HAL层库的加载原理是什么

发表于:2025-01-30 作者:千家信息网编辑
千家信息网最后更新 2025年01月30日,本篇文章给大家分享的是有关Android中HAL层库的加载原理是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Android HAL
千家信息网最后更新 2025年01月30日Android中HAL层库的加载原理是什么

本篇文章给大家分享的是有关Android中HAL层库的加载原理是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

Android HAL层的由来:由于市面做移动芯片的厂商很多,大部分厂商考虑到自己硬件的设计架构、安全、专利等方面原因,不愿意公开自己的这方面代码,也出于不同厂商硬件架构不太一样,适配开发难度周期长,GOOGLE在kernel之上加了一个HAL层,只要各个厂商实现Android 所需要的功能接口,可以以库的方式提供不用开源。

问题来了,android如何实现针对不同的Hardware Module进行通用性调用的呢?

以加载camera HAL层库为例:

#define CAMERA_HARDWARE_NODULE_ID "camera"

首先在 void CameraService::onFirstRef()

{

............略..............

camera_module_t *rawModule;

int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t **)&rawModule);

............略..............

}


通过hw_get_module()函数以CAMERA_HARDWARE_MODULE_ID 参数获得 camera_module_t 指针来初始化和调用CMAERA 我们再看hw_get_module()的实现:

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

{

return hw_get_module_by_class(id, NULL, module);

}

而hw_get_module()又是通过 hw_get_module_by_class():

int hw_get_module_by_class(const char *class_id, const char *inst,

const struct hw_module_t **module)

{

.................核心看......................

return load(class_id, path, module);

}

static int load(const char *id,const char *path,const struct hw_module_t **pHmi)

{

..........................................................................................

handle = dlopen(path, RTLD_NOW);

if (handle == NULL) {

char const *err_str = dlerror();

ALOGE("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);

if (hmi == NULL) {

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

status = -EINVAL;

goto done;

}

/* Check that the id matches */

if (strcmp(id, hmi->id) != 0) {

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

status = -EINVAL;

goto done;

}

有load函数可发现,它是通过dlopen()加载camera.so库,通过dlsym()查询HAL_MODULE_INFO_SYM_AS_STR全局变量的地址,通过强制指针转换可以获得HAL_MODULE_INFO_SYM_AS_STR变量,并检查传进来的id和获得id是否一致。HAL_MODULE_INFO_SYM_AS_STR是个宏定义如下:

#define HAL_MODULE_INFO_SYM_AS_STR "HMI"
也就是说camera.so库中肯定有一个名字为HMI 数据类型为struct hw_module_t的全局变量。

我们通过linux自带的readelf工具查看camera.so的符号表:

JEFF$ readelf -s camera.msm8937.so

Symbol table '.dynsym' contains 336 entries:

Num: Value Size Type Bind Vis Ndx Name

0: 00000000 0 NOTYPE LOCAL DEFAULT UND

1: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_finalize@LIBC (2)

2: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@LIBC (2)

3: 00000000 0 FUNC GLOBAL DEFAULT UND __register_atfork@LIBC (2)

4: 00000000 0 FUNC GLOBAL DEFAULT UND __aeabi_memcpy8@LIBC_N (3)

5: 00000000 0 FUNC GLOBAL DEFAULT UND __android_log_print

6: 00000000 0 FUNC GLOBAL DEFAULT UND __gnu_Unwind_Find_exidx@LIBC_N (3)

7: 00000000 0 FUNC GLOBAL DEFAULT UND dladdr@LIBC (4)

..................................................................................................................................

187: 000112c7 16 OBJECT GLOBAL DEFAULT 15 _ZN7android21SunmiCameraP

188: 00010eaa 17 OBJECT GLOBAL DEFAULT 15 _ZN7android21SunmiCameraP

189: 00006a25 28 FUNC GLOBAL DEFAULT 13 start_recording

190: 00012af8 44 OBJECT WEAK DEFAULT 18 _ZTVN7android12SortedVect

191: 0001134b 13 OBJECT GLOBAL DEFAULT 15 _ZN7android21SunmiCameraP

192: 00006ab1 28 FUNC GLOBAL DEFAULT 13 cancel_auto_focus

193: 0001120d 10 OBJECT GLOBAL DEFAULT 15 _ZN7android21SunmiCameraP

194: 00013158 176 OBJECT GLOBAL DEFAULT 23 HMI

195: 00006901 40 FUNC GLOBAL DEFAULT 13 get_camera_info

196: 00010e9a 16 OBJECT GLOBAL DEFAULT 15 _ZN7android21SunmiCameraP

197: 0001114c 7 OBJECT GLOBAL DEFAULT 15 _ZN7android21SunmiCameraP

198: 0000af79 20 FUNC GLOBAL DEFAULT 13 _Z11mjpegDecodeiiPciS_i

199: 00006b05 28 FUNC GLOBAL DEFAULT 13 set_parameters

200: 0000791d 40 FUNC WEAK DEFAULT 13 _ZNK7android12SortedVecto

201: 0001109b 9 OBJEC


可以看出来确实存在一个全局类型为OBJECT 名字为HMI的变量

那这个变量谁定义的呢?

我们看到hardware/qcom/camera/qcamera2/QCamera2Hal.cpp有这样的定义:

static hw_module_t camera_common = {

.tag = HARDWARE_MODULE_TAG,

.module_api_version = CAMERA_MODULE_API_VERSION_2_4,

.hal_api_version = HARDWARE_HAL_API_VERSION,

.id = CAMERA_HARDWARE_MODULE_ID,

.name = "QCamera Module",

.author = "Qualcomm Innovation Center Inc",

.methods = &qcamera::QCamera2Factory::mModuleMethods,

.dso = NULL,

.reserved = {0}

};

camera_module_t HAL_MODULE_INFO_SYM = {

.common = camera_common,

.get_number_of_cameras = qcamera::QCamera2Factory::get_number_of_cameras,

.get_camera_info = qcamera::QCamera2Factory::get_camera_info,

.set_callbacks = qcamera::QCamera2Factory::set_callbacks,

.get_vendor_tag_ops = qcamera::QCamera3VendorTags::get_vendor_tag_ops,

.open_legacy = qcamera::QCamera2Factory::open_legacy,

.set_torch_mode = qcamera::QCamera2Factory::set_torch_mode,

.init = NULL,

.reserved = {0}

};

可以看到有一个static hw_module_t camera_common变量的定义,就是我们通过dlsym()要获取的变量类型,但是这个变量也不叫 HMI 啊,我们再看这变量是被camera_module_t HAL_MODULE_INFO_SYM使用的,我们来看这个结构体定义:

typedef struct camera_module {

hw_module_t common;

int (*get_number_of_cameras)(void);

int (*get_camera_info)(int camera_id, struct camera_info *info);

int (*set_callbacks)(const camera_module_callbacks_t *callbacks);

void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops);

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

uint32_t halVersion, struct hw_device_t** device);

int (*set_torch_mode)(const char* camera_id, bool enabled);

int (*init)();

void* reserved[5];

} camera_module_t;

可以看出来 hw_module_t 是这个结构体的第一个变量,这样定义有个好处,可以实现类似C++的继承效果,camera_module继承于hw_module_t,可以通过hw_module_t控制camera_module,所以外面理论上应该通过HAL_MODULE_INFO_SYM 获得hw_module_t的,全局搜索HAL_MODULE_INFO_SYM 发现所有的HAL层模块都会有一个HAL_MODULE_INFO_SYM的定义,还发现HAL_MODULE_INFO_SYM其实是个宏定义:

#define HAL_MODULE_INFO_SYM HMI
1
也就是说

camera_module_t HAL_MODULE_INFO_SYM = {
1
编译解释为:

camera_module_t HMI = {
1
这样整个HAL层调用通用性就解释的通了。

以上就是Android中HAL层库的加载原理是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

变量 全局 厂商 类型 原理 不同 也就是 也就是说 函数 名字 就是 指针 更多 架构 知识 硬件 篇文章 结构 通用性 解释 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器主机解析不了目标站 陕西服务器提供商哪家好 高中数据库会考操作题 服务器4块显卡如何交火 魔兽世界永远60级服务器 金蝶服务器未启动 做软件开发买苹果电脑浪费吗 东北软件开发公司有哪些 国旗下讲话网络安全教育内容 通用网络安全技术分类 办公软件开发有什么好处 学软件开发一般需要科目 软件开发那种入门低 三级数据库考试用哪个软件 网络安全项目包含什么 服务器输出端口和输入端口 携程旅游数据库 sql对不同数据库查询 服务器电源用在台式机 数据库技术及应用作用 天津服务器机柜系列云服务器 邢台星瀚网络技术有限公司 济南三树软件开发有限公司电话 东北软件开发公司有哪些 服务器恢复出厂设置还能开机吗 网络安全等级最高的是几级 最大软件开发公司 厦门软件开发中小型企业 网络安全问卷设计的八个步骤 数据库join in 用法
0