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

来源:互联网 发布:淘宝买家修改差评步骤 编辑:程序博客网 时间:2024/05/22 10:34

你实现自己硬件平台的硬件适配层,那么 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 0
原创粉丝点击