Android硬件抽象层(HAL)深入剖析(二)
上一篇我们分析了android HAL层的主要的两个结构体hw_module_t(硬件模块)和hw_device_t(硬件设备)的成员,下面我们来具体看看上层app到底是怎么实现操作硬件的?
我们知道,一些硬件厂商不愿意将自己的一些核心代码开放出去,所以将这些代码放到HAL层,但是怎么保证它不开放呢?HAL层代码不是也让大家知道下载吗?其实硬件厂商的HAL核心代码是以共享库的形式出现的,每次在需要的时候,hal会自动加载调用相关共享库。那么是怎么加载找到某一硬件设备对应的共享库的呢?这也是我们这篇都要说的。
上层app通过jni调用hal层的hw_get_module函数获取硬件模块,这个函数是上层与hal打交道的入口。所以如果我们以程序调用执行的流程去看源码的话,这个函数就是hal层第一个被调用的函数,下面我们就
从这个函数开始,沿着程序执行的流程走下去。
hw_get_module函数定义在/hardware/libhardware/hardware.c中,打开这个文件可以看到定义如下:
1 int hw_get_module(const char *id, const struct hw_module_t **module)
2 {
3 int status;
4 int i;
5 const struct hw_module_t *hmi = NULL;
6 char prop[PATH_MAX];
7 char path[PATH_MAX];
8
9 /*
10 * Here we rely on the fact that calling dlopen multiple times on
11 * the same .so will simply increment a refcount (and not load
12 * a new copy of the library).
13 * We also assume that dlopen() is thread-safe.
14 */
15
16 /* Loop through the configuration variants looking for a module */
17 for (i=0 ; i<hal_variant_keys_count+1 p="">
18 if (i < HAL_VARIANT_KEYS_COUNT) {
19 if (property_get(variant_keys[i], prop, NULL) == 0) {//获取属性
20 continue;
21 }
22 snprintf(path, sizeof(path), "%s/%s.%s.so",
23 HAL_LIBRARY_PATH1, id, prop);
24 if (access(path, R_OK) == 0) break;//检查system路径是否有库文件
25
26 snprintf(path, sizeof(path), "%s/%s.%s.so",
27 HAL_LIBRARY_PATH2, id, prop);
28 if (access(path, R_OK) == 0) break;//检查vender路径是否有库文件
29 } else {
30 snprintf(path, sizeof(path), "%s/%s.default.so",//如果都没有,则使用缺省的
31 HAL_LIBRARY_PATH1, id);
32 if (access(path, R_OK) == 0) break;
33 }
34 }
35
36 status = -ENOENT;
37 if (i < HAL_VARIANT_KEYS_COUNT+1) {
38 /* load the module, if this fails, we're doomed, and we should not try
39 * to load a different variant. */
40 status = load(id, path, module);//装载库,得到module
41 }
42
43 return status;
44 }
看第一行我们知道有两个参数,第一参数id就是要获取的硬件模块的id,第二个参数module就是我们想得到的硬件模块结构体的指针。
所以可以看出,上层首先给hal需要获取的硬件模块的id,hw_get_module函数根据这个id去查找匹配和这个id对应的硬件模块结构体的。
下面看看怎么找的。
17行有个for循环,上限是HAL_VARIANT_KEYS_COUNT+1,那么这个HAL_VARIANT_KEYS_COUNT是什么呢?查看同文件下找到有:
static const int HAL_VARIANT_KEYS_COUNT =
(sizeof(variant_keys)/sizeof(variant_keys[0]));
原来它是ariant_keys这个数组的元素个数。那么这个数组又是什么呢?在本文件找,有:
/**
* There are a set of variant filename for modules. The form of the filename
* is "<module_id>.variant.so" so for the led module the Dream variants
* of base "ro.product.board", "ro.board.platform" and "ro.arch" would be:
*
* led.trout.so
* led.msm7k.so
* led.ARMV6.so
* led.default.so
*/
static const char *variant_keys[] = {
"ro.hardware", /* This goes first so that it can pick up a different
file on the emulator. */
"ro.product.board",
"ro.board.platform",
"ro.arch"
};
可以看到它其实是个字符串数组。站且不知道干什么的。继续看hw_get_module函数,进入for循环里面,看22行,其实它是将HAL_LIBRARY_PATH1, id, prop这三个串拼凑一个路径出来,
HAL_LIBRARY_PATH1定义如下:
/** Base path of the hal modules */
#define HAL_LIBRARY_PATH1 "/system/lib/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"
id是上层提供的,prop这个变量的值是前面19行property_get(variant_keys[i], prop, NULL)函数获取到的,其实这个函数是通过ariant_keys数组的的属性查找到系统中对应的变种名称。不同的平台获取到prop值是不一样的。
假如在获取到的prop值是tout,需要获取的硬件模块的id是leds,那么最后path组成的串是/system/lib/hw/leds.tout.so。
后面24行access是检查这个路径下是否存在,如果有就break,跳出循环。如果没有,继续走下面,
可以看到下面几行和刚才形式差不多,
snprintf(path, sizeof(path), "%s/%s.%s.so", HAL_LIBRARY_PATH2, id, prop);
if (access(path, R_OK) == 0) break;//检查vender路径是否有库文件
结合 HAL_LIBRARY_PATH2 为"/vendor/lib/hw",假设同样获取到的prop值是tout,需要获取的硬件模块的id是leds,这种情况下path拼出来的值是/vender/lib/hw/leds.tout.so,然后在判断文件是否存在。如果存在跳出循环。
从以上分析,其实这就是hal层搜索动态共享库的方式,从中我们可以得到两点:
1.动态共享库一般放在 "/system/lib/hw"和"/vendor/lib/hw"这两个路径下。
2.动态库的名称是以"id.variant.so"的形式命名的,其中id为上层提供,中间variant为变种名称,是随系统平台变化的。
接着,从29到32行我们可以看到,当所有变种名称形式的包都不存在时,就以"id.default.so"形式包名查找是否存在。
37行, if (i < HAL_VARIANT_KEYS_COUNT+1),如果i小于变种名称数组的话,表示找到了对应的库,那么38行load(id, path, module);//装载库,得到module。
以上就对hal层搜索库的规则搞清楚了。
下一篇我们将进入load函数,看看共享库是如何被加载的。
Android硬件抽象层(HAL)深入剖析(二)的更多相关文章
- Android硬件抽象层(HAL)深入剖析(二)【转】
上一篇我们分析了android HAL层的主要的两个结构体hw_module_t(硬件模块)和hw_device_t(硬件设备)的成员,下面我们来具体看看上层app到底是怎么实现操作硬件的? 我们知道 ...
- Android硬件抽象层(HAL)深入剖析(一)【转】
作为一个搞android驱动或者说搞底层的人,我觉得对于hal那是必须要掌握的,而且必须达到一定深度,于是我总结了一下,将整个自己的分析思路写下来. 主要是看android源代码,根据源代码得到的思路 ...
- Android硬件抽象层(HAL)深入剖析(三)【转】
前面分析了android HAL层是如何搜索硬件模块的动态共享库的,其实就是在"system/lib/hw/"或者"/vendor/lib/hw/"这两个路径下 ...
- [Android] Toast问题深度剖析(二)
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者: QQ音乐技术团队 题记 Toast 作为 Android 系统中最常用的类之一,由于其方便的api设计和简洁的交互体验,被我们所广泛采用 ...
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口(老罗学习笔记4)
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接口.实现这两者的目的是为了向更上一层提供硬件访问接口,即为 ...
- Android架构分析之使用自定义硬件抽象层(HAL)模块
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本:2.3.7_r1 Linux内核版本:android-goldfish-2.6.29 在上一篇博 ...
- 为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接 口.实现这两者的目的是为了向更上一层提供硬件访问接口,即 ...
- Android - 硬件抽象层(HAL)
以下资料摘录整理自老罗的Android之旅博客,是对老罗的博客关于Android底层原理的一个抽象的知识概括总结(如有错误欢迎指出)(侵删):http://blog.csdn.net/luosheng ...
- Android硬件抽象层(HAL)概要介绍和学习计划
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6567257 Android的硬件抽象层,简单来 ...
随机推荐
- Python虚拟机中的一般表达式(一)
在Python虚拟机框架这一章中,我们通过PyEval_EvalFrameEx看到了Python虚拟机的整体框架.而这章开始,我们将了解Python虚拟机是如何完成对Python的一般表达式的执行,这 ...
- Netcore 基础之TagHelper知识
饮水思源,来自:http://www.cnblogs.com/liontone 的BLOG中关于taghelper中的内容 概要 TagHelper是ASP.NET 5的一个新特性.也许在你还没有听说 ...
- [POJ 1001] Exponentiation C++解题报告 JAVA解题报告
Exponentiation Time Limit: 500MS Memory Limit: 10000K Total Submissions: 126980 Accepted: 30 ...
- Leetcode4--->求两个排序数组的中位数
题目:给定两个排序数组,求两个排序数组的中位数,要求时间复杂度为O(log(m+n)) 举例: Example 1: nums1 = [1, 3] nums2 = [2] The median is ...
- 让boostrap的图片轮播支持滑动效果
因为最近开发的项目涉及到移动设备上的 HTML5 开发,其中需要实现轮播效果. 然后最快捷的方式,你知道的(Bootstrap),然后原生的 Bootstrap 的 carousel.js 插件并没有 ...
- Python3异常-AttributeError: module 'sys' has no attribute 'setdefaultencoding'
基于python3.6.1版本,在一个.py文件中,加入这3行: import requests, re, sys reload(sys) sys.setdefaultencoding("u ...
- 以前刷过的FFT
Gym - 101667H 2017-2018 ACM-ICPC, Asia Daejeon Regional Contest #include<bits/stdc++.h> using ...
- C++ ---->中include <iostream>和include <iostream.h>的区别
简单来说: .h的是标准C的头文件,没有.h的是标准C++的头文件,两种都是头文件. 造成这两种形式不同的原因,是C++的发展历史决定的,刚才正好有别的人也问这个问题,这里我再回答一下(注意vs200 ...
- iOS学习笔记35-社交分享
一.社交分享 现在很多应用都内置“社交分享”功能,可以将看到的新闻.博客.广告等内容分享到微博.微信.QQ.人人网等,其实从iOS6.0开始苹果官方就内置了Social.framework专门来实现社 ...
- 【CTSC2010】产品销售(bzoj1920)
数据结构优化网络流…… 重新定义一下题目的各种条件: 第 $i$ 天能生产 $a_i$ 个物品: 第 $i$ 天有 $b_i$ 个物品的需求: 每存储一天物品(把订单提前一天)需要 $c_i$ 的花费 ...