首先要去掉厂家提供的gralloc,hwcopser HAL模块,在这之前先回顾一下:android系统如何加载一个硬件模块,在之前的小节中,详细的讲解了:
int hw_get_module(const char *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL, module);
}
在此我们简单的总结一下,如何获得HAL模块gralloc。hw_get_module函数时在哪里去查找呢?我们进入源代码:
hw_get_module(const char *id, const struct hw_module_t **module)
hw_get_module_by_class(id, NULL, module);
hw_module_exists(path, sizeof(path), name, "default")
snprintf(path, path_len, "%s/%s.%s.so",HAL_LIBRARY_PATH3, name, subname);
snprintf(path, path_len, "%s/%s.%s.so",HAL_LIBRARY_PATH2, name, subname);
snprintf(path, path_len, "%s/%s.%s.so",HAL_LIBRARY_PATH1, name, subname);
可以看到首先会在HAL_LIBRARY_PATH3,HAL_LIBRARY_PATH2,HAL_LIBRARY_PATH1三个目录进行查找,对于我们的RK3399(64位)定义如下:
#define HAL_LIBRARY_PATH1 "/system/lib64/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib64/hw"
#define HAL_LIBRARY_PATH3 "/odm/lib64/hw"
确定了目录以后,我们要知道,他查找的文件名是什么,
/*穿入一个模块的名字const char *id,尝试获得他对应的文件*/
hw_get_module(const char *id, const struct hw_module_t **module)
/*把id与inst组成name,其中inst=null,即该就为id原型*/
snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {//循环查找
/*如果属性存在prop之中,获取其属性值*/
if (property_get(variant_keys[i], prop, NULL) == 0) {
/*判断是否存在文件。*/
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
/*其文件名由name与subname(属性值)构成的字符串*/
snprintf(path, path_len, "%s/%s.%s.so",HAL_LIBRARY_PATH3, name, subname);
从上面可以得出,文件名为gralloc.属性.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"
};
我们在开发板上查看这四个属性值分别是什么,使用getprop 命令,输出如下:
qytech_azalea:/ $ getprop ro.hardware
rk30board
qytech_azalea:/ $ getprop ro.product.board
rk30sdk
qytech_azalea:/ $ getprop ro.board.platform
rk3399
qytech_azalea:/ $ getprop ro.arch
(null)
从上面我们可以看出,他会去看看是否存在:
getprop.属性值.so:getprop.rk30board.so,getprop.rk30sdk.so,getprop.rk3399.so
这四个文件,如果之前的三个路径存在,则hw_module_exists函数会直接返回,如果都没有找到。最后会在这三个路径下查找gralloc.default.so。
根据图示,我们需要去掉两个模块,一个为上面推述的gralloc模块,与hwcomposer。在以下三个路径下查找:
#define HAL_LIBRARY_PATH1 "/system/lib64/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib64/hw"
#define HAL_LIBRARY_PATH3 "/odm/lib64/hw"
我们可以在/system/lib64/hw中看到
他会有限使用厂家提供的gralloc.rk30board.so,后面我们可以把这个删除掉,对于hwcomposer(硬件合成单元)为hwcomposerrk30board.so,这个我们也需要删除掉。
下面我们修改源码:
a.删除单板上的gralloc.rk30board.so与hwcomposerrk30board.so。
使用adb执行:
adb disable-verity (为了能够让开发板可以文件系统以读写方式挂载)
然后重启开发板执行:
mount -o rw,remount -t auto /system (这样我们就能对/system目录进行操作了)
最后执行
rm hwcomposer.rk30board.so
rm gralloc.rk30board.so
然后重启我们的开发板,看看我们的系统是否能够启动,此时发现,开发板虽然能够进入终端,但是我们的屏幕无法点亮。下面我们要修改源代码,看看能不能让我能的屏幕点亮,在分析之前,我们还需要修改源代码,让编译的源码不出现hwcomposer.rk30board.so与 gralloc.rk30board.so文件。
我们可以修改device/rockchip/common/device.mk文件(在这之前先备份device.mk_mybak):
PRODUCT_PACKAGES += \
sensors.$(TARGET_BOARD_HARDWARE) \
- gralloc.$(TARGET_BOARD_HARDWARE) \
- hwcomposer.$(TARGET_BOARD_HARDWARE) \
lights.$(TARGET_BOARD_PLATFORM) \
camera.$(TARGET_BOARD_HARDWARE) \
Camera \
libvpu \
libstagefrighthw \
libgralloc_priv_omx \
akmd
把其中做-号的两句代码删除。