Android14-HAL分析


参考资料:

1、阿豪讲Framework:https://juejin.cn/user/342703355728382/posts

2、术语

1、VINTF : Vendor interface

一、HAL综述

1、HAL:Hardware Abstraction Layer

2、HAL存在的意义

1)HAL是对驱动操作的包装库,操作硬件的具体逻辑可以放到 HAL中(属于算法,如果这部分暴露的话 会让友商反推出硬件IP Core的设计),驱动程序本身只提供基本寄存器操作功能。

3、不同版本的HAL(传统HAL、HIDL HAL、AIDL HAL)开发流程是不同的,HAL(so库)与HIDL/AIDL(进程间通信)要区分开,从推出时间来分类,如下
1)Android 8以前 -> HAL层 以so库和.h文件存在 - 传统HAL
2)Android 8-10 -> HAL层 以进程方式存在 - HIDL HAL
3)Android 10 -> HAL层 以进程方式存在 - AIDL HAL

注意以上Android版本是推出时间,实际上高版本的Android混杂着各个HAL版本(比如Android13 Audio用的是hidl),实在让人混乱!

4、HAL库所在的代码目录

hardware/* 部分厂商开源的硬件适配层HAL代码

hardware/libhardware_legacy //旧的HAL层库

hardware/libhardware //HAL层实库

5、厂家闭源,厂家需要实现什么?

通过OS里面开源例子来了解学习

二、Android各版本HAL的演进

1、参考资料

1)Android8 HAL变迁: https://juejin.cn/post/7359954143916425251

2) Android HIDL HAL 接口定义语言详解:https://blog.youkuaiyun.com/qq_19923217/article/details/88398660

3)AN14 添加HAL层:https://blog.youkuaiyun.com/baidu_41666295/article/details/145503951

每一篇博文 都有参考的意义(不同开发者的知识域都不同,角度不同 即表述的内容也不同,应该各取精华)

2、Android版本对HAL有过几次改革,因此需要了解演进的背景和变化对理解几种HAL层的设计有很大的帮助;

1)尤其是网络上的各类资料,充斥着不同的Android版本,注意区分和分辨;

2)在不同版本上又应该如何选择实现HAL的方式?首先确定硬件厂商,而厂商不同,各自的选择也不同~

3、先理解Android系统各厂家合作模式:
在这里插入图片描述

1)Google : 负责Android系统开发、维护、迭代;

2)芯片厂商:负责适配硬件(vendor),定制Framework,有实力的话会帮忙解bug,加特性;

3)终端厂商:负责进一步定制Framework,有实力的话也会解BUG和加特性;

4、Treble架构(Android 8 / O)

由于系统发布比较频繁,而芯片厂和厂商更新版本代价较高(移植适配,测试耗时耗力),导致下游厂家不愿升级,间接损害Google的利益,Google为了解决升级问题,将芯片厂商从Framework抽离开来,实现互相升级不受影响,这就是Android8引入的Treble架构(代价是大大增加了复杂度),看图:
在这里插入图片描述

1、划分之后,System(放Framework部分)/ Vendor(放厂商部分)分区中的native程序/库(NDK)只能链接各自的库,而这由系统权限设置管理,Framework要访问Vendor的HAL接口,只能通过进程间通信实现;

扩展,Android 9推出product分区(存放终端厂商的针对特定设备的系统配置、应用程序、资源文件)

2、但难免有vendor和Framework互相依赖库,这些“特别的库”被分类出来如下(了解下即可)
1)LL-NDK(low level vendor native development kit),可以framework和vender进程链接,由google来维护,例子:
libEGL.so
libGLESv1_CM.so
libvndksupport.so
2)VNDK : Vendor Native Development Kit(Android 8.0引入,将系统分区和供应商分区分离,保持Android核心系统的纯净性,供应商可以使用VNDK开发自己的HAL,包含在system.img中 - 即VNDK升级与否让供应商决定,可以不升级在新的Android版本上使用)

目录示例:
android\prebuilts\vndk\v30\arm\arch-arm-armv7-a-neon\shared\vndk-core

VNDK深入剖析:https://blog.youkuaiyun.com/learnframework/article/details/134889443
bp中使用proprietary/vendor-only指定

3)SP-HAL:same-Process HAL(framework负责加载的hal库,由google来维护),链接的so库 称为VNDK-SP,需为VNDK或LL-NDK, 例子:
android.hardware.graphics.mapper@2.0-impl.so
android.hardware.renderscrip@1.0-impl.so
4)VNDK-SP:链接LL-NDK/VNDK的SP-HAL

这些特性怎么体现?

1、由SEpolicy强制执行,在te文件或Andorid.bp指定属性;

目录示例:
android\prebuilts\vndk\v30\arm\arch-arm-armv7-a-neon\shared\vndk-sp

3、随着库和进程被隔离开,Framework访问HAL层只能通过进程通信的方式,因此基于binder设计出HIDL HAL;

4、进一步地,Android9之后推出apex,同样也是为了方便第三方对系统组件的更新;

三、传统HAL(<= Android7)

1、HAL应知应会

1、传统的HAL,即厂家提供.so和.h,在需要访问硬件的时候dlopen,调用对应接口
>>既然是厂家实现,Google需要提供demo以保证规范,在哪里?
以audio为例
1)
android\hardware\libhardware\modules\audio //旧架构
android\hardware\libhardware_legacy\audio //新架构
厂家参照这个demo实现自家的audio hal(使用哪个架构,视乎厂家,无论哪个架构,接口都是一样的),并生成so库提供第三方集成
2)qcom开源出来源码实现:
android\hardware\qcom\audio\hal  //对应新架构
android\hardware\qcom\audio\legacy //对应旧架构


2、传统hal必须按照一定规范来写,用库函数 来加载

3、传统的HAL在高版本被弃用?还有必要去了解?
1)没有完全弃用,Android推出新的架构,不会一下子丢弃旧的方式,厂商会逐渐过渡 甚至一直保留都有可能;

2、代码分析

1、在系统服务代码中使用以下方法加载 HAL 模块
const hw_module_t *module;
hw_get_module(AUDIO_HARDWARE_MODULE_ID, &module); //会根据名字去对应目录查找并加载

具体实现如下:
1)
android\hardware\libhardware\hardware.c
typedef struct hw_module_t {
    struct hw_module_methods_t* methods;
}
2)
hw_get_module(const char *id, struct hw_module_t **module)
--hw_get_module_by_class(id, module)
----load(class_id, path, module)
------dlopen(path)
------dlsym(handle, sym) //找到结构体(hw_module_t),存在module指针中

3)例:audio_hw_module实现
struct audio_hw_module{
    struct hw_module_t common;
};
struct audio_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = AUDIO_HARDWARE_MODULE_ID,
        .name = "QCOM Audio HAL",
        .author = "Code Aurora Forum",
        .methods = &hal_module_methods,
    },
};

2、HAL什么时候被加载?最好是对应服务拉起的时候去加载,而事实也是如此
比如AudioFlinger 在启动时通过 hw_get_module方法加载传统hal库,并调用 create() 方法实例化接口

3、例:Vibrator(Vibrator实现相对简单易懂,是学习的好例子)
1)负责加载传统Vibrator HAL库对应的Service进程
frameworks/base/services/core/java/com/android/server/VibratorService.java //注意此传统hal service实现与AIDL hal实现的VibratorService 是有区别的!

2)C语言中的继承
typedef struct vibrator_device {
    struct hw_device_t common;
    int (*vibrator_on)(struct vibrator_device* vibradev, unsigned int timeout_ms);
    int (*vibrator_off)(struct vibrator_device* vibradev);
} vibrator_device_t;
通过指针巧妙实现C语言中的“继承”,vibrator_device(子类) 和 hw_device_t(父类)指针可以相互转换

四、HIDL HAL(Android8-10)

1、参考资料

1)HIDL Hal 开发指南3-HIDL HAL实例程序: https://juejin.cn/post/7360612648043708456

2)Android HAL 与 HIDL 开发笔记:https://evilpan.com/2020/11/01/hidl-basics/

3)HIDL实战(千里马):https://juejin.cn/post/7336743827826065459

2、概述

1、HIDL HAL是什么?

1)HIDL全称HAL interface definition language,而HIDL HAL则为,使用HIDL语言描述HAL层的对外接口,

2)注意HIDL语言只是一个Google提供的辅助工具,必须使用?不是,自己也可以自行实现所有代码

2、与传统HAL的区别?

1)传统HAL:用户<->HAL<->驱动

2)HIDL HAL:用户(client) <-> HIDL(hidl-gen) <-> HAL(service) <-> 驱动

3、Android8后推出的,为了能独立升级Framework和Vendor,按照规定格式和步骤编写代码即可;

2、架构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值