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

by sundy 10/14/2010 9:20:51 AM

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;
    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框架不需要做任何修改即可。

Currently rated 2.0 by 13 people

  • Currently 2/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Mobile & Wireless | C/C++/Embedded

Related posts

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2007 - 2008 Design by Sundy Linghua-Zhang 蜀ICP备08108648号

About the author

Name of author Author name
Something about me and what I do.

E-mail me Send mail

Calendar

<<  May 2012  >>
MoTuWeThFrSaSu
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

View posts in large calendar

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2012

Sign in