内核驱动程序模块
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中。