Androidy硬件驱动开发

内核驱动程序模块

1、编写好的内核,放到内核的drivers文件夹中,一般有c实现文件(包括.c和.h)、kconfig和Makefile。

2、修改内核中的Kconfig和Makefile文件。

其中Kconfig在arch/$(ARCH)目录下,比如arch/arm/Kconfig,找到两行内容:

menu “Device Drivers”

……

endmenu

添加自己的Kconfig:source “drivers/(自己驱动的文件夹)/Kconfig”

Makefile在drivers目录下,只要添加下面一行:

obj - $(自己驱动的文件中Makefile部分相同)+=(自己驱动的文件夹)/

比如自己的驱动文件夹为temp,temp文件夹中的Makefile中添加的是:obj -$(CONFIG_TEMP)+=temp.o

则在arch/arm/Kconfig添加为:source “drivers/temp/Kconfig”,在drivers/Makefile文件添加为:obj - $(CONFIG_TEMP)+= temp/

3、修改内核驱动程序模块。内核中执行make menuconfig,会弹出一下窗口:

上下箭头可以选择项,先把”Enable loadable module support“项按Y键选上(这样允许模块方式来编译自己的驱动),然后在“Device Drivers”项按住Enter键进入第二个配置界面中选择自己的驱动然后按Y键,让它以模块方式编译。

保存配置之后,用make命令(建议make后面添加参数-jn,其中n一般为cpu核心*2)就可以编译自己修改驱动后的内核了。

启动模拟器,执行adb shell,进入然后可以查看dev目录下有没有你的驱动文件夹,在自己实现的系统中有没有自己的文件夹。

可以自己写c可执行的程序来验证Android硬件驱动程序,一般放在externel文件夹中,然后用mmm ./extenernal/(自己的c可执行程序),最后make snod。

Android硬件抽象层模块

Android系统的硬件抽象层以模块的形式来管理各个硬件访问接口,每个模块都对应有一个动态链接库文件。

其中硬件抽象层模块文件的命名规范定义在hardware/libhardware/hardware.c文件中。它主要变量:

/** Base path of the hal modules */
#define HAL_LIBRARY_PATH1 "/system/lib/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"

/**
 * 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"
};

它的加载顺序是ariant数组的顺序。

编写的硬件抽象层模块接口就放到Android/hardware/libhardware中,其中头文件放到include/hardware中,而模块文件放到Modules中。

每一个硬件抽象模块都要导出一个名称为HAL_MODULE_INFO_SYM的符号,它指向一个自定义的硬件抽象层模块结构体。

注意硬件设备访问的权限在system/core/rootdir目录的ueventd.rc的配置文件中,所以可以在里面添加访问权限,添加之后需要重新编译源码才能生效,或者,直接把它放到ramdisk.img文件中。具体操作:

先把ramdisk解压

cp /home/tempal/Android/out/target/product/generic/ramdisk.img ramdisk.img.gz
gunzip ramdisk.img.gz
mkdir ramdisk
cd ramdisk
cpio -i -F ../ramdisk.img

修改里面的ueventd.rc

最后重新打包回去即可

Android硬件访问服务

硬件访问服务必须通过java本地接口(java native interface,JNI)来调用硬件抽象层模块的接口。Android系统的硬件访问服务通常在系统进程System中,而使用这些硬件访问服务的应用程序运行在另外的进程中,故要实现访问接口。

服务接口一般定义在frameworks/base/core/java/android/os/中

硬件访问实现在frameworks/base/core/java/android/server/目录中。

本地调用服务实现在frameworks/base/services/jni中。

posted @ 2013-08-01 17:05  Tempal  阅读(489)  评论(0编辑  收藏  举报