怎样实现Android系统的HAL(硬件适配层)

你实现自己硬件平台的硬件适配层,那么 Android系统将会调用你的硬件适配层来为系统加速。如果你未定义自己平台硬件适配层(HAL),那么Android系统将调用软实现,这样的话不会 发挥出你的硬件平台的最大效能。本文简略介绍一下Android系统的HAL层,进而介绍怎样实现HAL层,以起到抛砖引玉的作用。

  •      Android系统HAL层位于hardware目录下面。HAL层是以桩的形式实现的,请看如下取自hardware/hardware.c的代码:

    int hw_get_module(const char *id, const struct hw_module_t **module)
    {
        int status;
        int i;
        const struct hw_module_t *hmi = NULL;
    布于: 2010 八月 28
  • 作者:
    Simon_fu
  • 目录: 嵌入式技术
  • 评论: 0 条评论

      Android系统作为一个开放的平台,为了适配千变万化的硬件平台,定义了一个硬件适配层(HAL)框架。如果

    char prop[PATH_MAX];
    char path[PATH_MAX];

    /*
     * Here we rely on the fact that calling dlopen multiple times on
     * the same .so will simply increment a refcount (and not load
     * a new copy of the library).
     * We also assume that dlopen() is thread-safe.
     */

    /* Loop through the configuration variants looking for a module */
    for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
        if (i < HAL_VARIANT_KEYS_COUNT) {
            if (property_get(variant_keys[i], prop, NULL) == 0) {
                continue;
            }
            snprintf(path, sizeof(path), "%s/%s.%s.so",
                    HAL_LIBRARY_PATH, id, prop);
        } else {
            snprintf(path, sizeof(path), "%s/%s.default.so",
                    HAL_LIBRARY_PATH, id);
        }
        if (access(path, R_OK)) {
            continue;
        }
        /* we found a library matching this id/variant */
        break;
    }

    status = -ENOENT;
    if (i < HAL_VARIANT_KEYS_COUNT+1) {
        /* load the module, if this fails, we're doomed, and we should not try
         * to load a different variant. */
        status = load(id, path, module);
    }

    return status;
}

从代码中我们可以看出Android系统首先去系统属性查找硬件定义,然后再去加载相应硬件HAL层的特定模块(模块名字在函数参数id传入)so库文件,如果系统属性中未定义硬件属性则价值默认硬件HAL层对应模块的so库文件进行硬件加速。

     你可能会问Android加载了HAL层的so库文件,那么他怎么知道调用哪个函数呢?其实所有的硬件模块需要实现的接口Android系统都已经定义好 了,位于hardware/libhardware/include/hardware下面,你打开会发现下面有很多Android定义好的HAL层模 块,比如gralloc,copybit等等。自定义的HAL层的任何模块都必须按上述目录中定义好的接口来实现,否则就会HAL层出错(后果很严重)。这样Android系统正确的加载了HAL层特定模块的so库文件之后,它就知道这个模块的so库中包含哪些函数,需要的时候直接调用就可以了。

     Android系统其实是HAL层框架,大家实现HAL层必须要按照预先定义好的接口来实现。这样做的优势是扩展非常方便,当你有一个新的硬件平台需要跑 Android,你只需要在hardware目录下面实现一个自己的HAL层就可以了,不需要修改Android框架的代码。因为现实世界中的平台千变万 化,Simon也不可能对他们全部了解,所以这里就不具体介绍怎样实现具体的HAL层了,可供参考的实例很多,拿来模仿一下即可。

     为了让系统正确加载你的代码,你需要在系统属性中定义好你的硬件属性,这样Android系统才会正确的加载你的HAL层so库文件。那么需要定义那些系统属性呢?我们继续看hardware/hardware.c文件,发现如下定义:

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函数的代码,会发现只要定义了上述系统属性中的一个就可以了。定义上述属性的方法有很多。我这里推荐一种 方法就是在系统启动的时候,init进程会读取/proc/cpuinfo文件中的数据得到硬件信息,并且设置ro.hardware属性(具体请查看 system/core/init/init.c文件),所以在kernal中定义好硬件信息是个很不错的想法。这样Android移植到一个新的硬件平 台只需要移植Kernal(这步肯定是少不了的),另外定义好相应平台的HAL层就可以了,Android框架不需要做任何修改即可。

     http://my.unix-center.net/~Simon_fu/?p=630。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值