参考老罗的Android之旅
Android硬件抽象层(HAL)概要介绍和学习计划
基于android5.1.1系统源码,清华镜像站https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/下载系统源码和kernel3.4源码
1.在Android内核源代码中,编写Linux驱动程序(driver)
(1).进入到kernel/goldfish/drivers目录,新建hello目录;
(2). 在hello目录中增加hello.h文件;定义了一个字符设备结构体hello_android_dev;
(3).在hello目录中增加hello.c文件,这是驱动程序的实现部分;定义三种访问设备寄存器的方法;
定义传统的设备文件访问方法
定义通过devfs文件系统访问方法
定义通过proc文件系统访问方法
定义模块加载和卸载方法
(4)..在hello目录中新增Kconfig和Makefile两个文件;
Kconfig文件的内容
config HELLO
tristate "First Android Driver"
default n
help
This is the first android driver.
Makefile文件的内容
obj-$(CONFIG_HELLO) += hello.o
(5).修改arch/arm/Kconfig和drivers/kconfig两个文件;
在menu "Device Drivers"和endmenu之间添加一行:
source "drivers/hello/Kconfig"
在arch/arm/Kconfig中没有找到enu "Device Drivers"则添加
menu "Device Drivers"
source "drivers/hello/Kconfig"
endmenu
(6).修改drivers/Makefile文件,添加一行: obj-$(CONFIG_HELLO) += hello/;
(7).配置编译选项:make menuconfig;
找到"Device Drivers" => "First Android Drivers"选项,设置为y。
(8).编译:make;
编译成功后,就可以在hello目录下看到hello.o文件了,这时候编译出来的zImage已经包含了hello驱动。
编译遇到的问题:
a.在make menuconfig之前,没有设置环境变量
export ARCH=arm
export SUBARCH=arm
export CROSS_COMPILE=arm-eabi-
b.在make后报错
error: 'struct proc_dir_entry' has no member named 'owner'
即proc_dir_entry结构体没有成员变量owner,proc_dir_entry定义在include/linux/proc_fs.h文件中,在此文件中添加成员变量owner,
struct module *owner;
重新编译即可。
c.在make后报错
error: implicit declaration of function 'init_MUTEX' [-Werror=implicit-function-declaration] init_MUTEX(&(dev->sem));
在新版本的Linux内核中,init_mutex已经被废除了,新版本使用sema_init函数。
将
init_MUTEX(&(dev->sem));
改为
sema_init(&(dev->sem),1);
重新编译即可。
哈哈哈!!!编译成功!!!
(9).验证,启动模拟器
emulator -kernel arch/arm/boot/zImage &
adb shell
进入到dev目录,可以看到hello设备文件:
root@android:/ # cd dev
root@android:/dev # ls
进入到proc目录,可以看到hello文件:
root@android:/ # cd proc
root@android:/proc # ls
访问hello文件的值:
root@android:/proc # cat hello
0
root@android:/proc # echo '55' > hello
root@android:/proc # cat hello
55
进入到sys/class目录,可以看到hello目录:
root@android:/ # cd sys/class
root@android:/sys/class # ls
进入到hello目录,可以看到hello目录:
root&