这里使用一个虚拟的硬件设备,这个设备只有一个4字节的寄存器,它可读可写。这里把这个虚拟的设备命名为“mydev”,而这个内核驱动程序也命名为mydev驱动程序。
这里通过cat命令直接访问/proc/mydev和/sys/class/mydev/mydev/val文件验证驱动程序的正确性。
驱动程序目录结构如下:
1
2
3
4
5
6
7~/Android/kernel/goldfish
----drivers
----mydev
----mydev.h
----mydev.c
----Kconfig
----Makefile新建mydev目录
- ~/Android$ cd kernel/goldfish/drivers
- ~/Android/kernel/goldfish/drivers$ mkdir mydev
- 在mydev目录中增加mydev.h文件
1 |
|
在mydev目录中增加mydev.c文件,这是驱动程序的实现部分。
驱动程序的功能主要是向上层提供访问设备的寄存器的值,包括读和写。这里,提供了三种访问设备寄存器的方法,一是通过proc文件系统来访问,二是通过传统的设备文件的方法来访问,三是通过devfs文件系统来访问。下面分段描述该驱动程序的实现。- 首先是包含必要的头文件和定义三种访问设备的方法:
1 |
|
在mydev目录中新增Kconfig和Makefile两个文件,其中Kconfig是在编译前执行配置命令make menuconfig时用到的,而Makefile是执行编译命令make是用到的
在Kconfig文件中,tristate表示编译选项MYDEV支持在编译内核时,mydev模块支持以模块、内建和不编译三种编译方法,默认是不编译,因此,在编译内核前,我们还需要执行make menuconfig命令来配置编译选项,使得mydev可以以模块或者内建的方法进行编译。
在Makefile文件中,根据选项MYDEV的值,执行不同的编译方法。- Kconfig文件的内容(默认的编译方式为n,即不编译到内核中,故在编译驱动程序之前,需要执行make menuconfig命令来修改编译选项)
1
2
3
4
5config MYDEV
tristate "Fake Register Android Driver"
default n
help
This is the mydev driver for android system.
- Makefile
1
obj-$(CONFIG_MYDEV) += mydev.o
- Kconfig文件的内容(默认的编译方式为n,即不编译到内核中,故在编译驱动程序之前,需要执行make menuconfig命令来修改编译选项)
修改内核Kconfig文件
- 打开arch/arm/Kconfig文件,找到以下两行内容
1
2
3menu "Device Drivers"
......
endmenu
- 打开arch/arm/Kconfig文件,找到以下两行内容
在这两行内容之间添加下面一行内容,将驱动程序mydev和Kconfig文件包含尽量。1
2
3
4menu "Device Drivers"
source "drivers/mydev/Kconfig"
......
endmenu
这样,执行make menuconfig时,就可以配置mydev模块的编译选项了。
- 打开drivers/Kconfig,和arch/arm/Kconfig一样,增加一行内容:source "drivers/mydev/Kconfig"
修改drivers/Makefile文件,添加一行:
1
obj-$(CONFIG_MYDEV) += mydev/
配置编译选项:
- ~/Android/kernel/goldfish$ make menuconfig
找到”Device Drivers” => “Fake Register Android Drivers”选项,设置为y。注意,如果内核不支持动态加载模块,这里不能选择m,虽然我们在Kconfig文件中配置了MYDEV选项为tristate。要支持动态加载模块选项,必须要在配置菜单中选择Enable loadable module support选项;在支持动态卸载模块选项,必须要在Enable loadable module support菜单项中,选择Module unloading选项。
- 编译:
- ~/Android/kernel/goldfish$ make
编译成功后,就可以在mydev目录下看到mydev.o文件了,这时候编译出来的zImage已经包含了mydev驱动。
运行新编译的内核文件,验证mydev驱动程序是否已经正常安装
- ~/Android$ emulator -kernel ./kernel/goldfish/arch/arm/boot/zImage &
- ~/Android$ adb shell
进入到dev目录,可以看到mydev设备文件
- root@android:/ # cd dev
- root@android:/dev # ls
进入到proc目录,可以看到mydev文件:
- root@android:/ # cd proc
- root@android:/proc # ls
访问mydev文件的值
- root@android:/proc # cat mydev
0 - root@android:/proc # echo ‘5’ > mydev
- root@android:/proc # cat mydev
5
进入到sys/class目录,可以看到mydev目录:
- root@android:/ # cd sys/class
- root@android:/sys/class # ls
进入到mydev目录,可以看到mydev目录:
- root@android:/sys/class # cd mydev
- root@android:/sys/class/mydev # ls
进入到下一层mydev目录,可以看到val文件
- root@android:/sys/class/mydev # cd mydev
- root@android:/sys/class/mydev/mydev # ls
访问属性文件val的值
- root@android:/sys/class/mydev/mydev # cat val
5 - root@android:/sys/class/mydev/mydev # echo ‘0’ > val
- root@android:/sys/class/mydev/mydev # cat val
0
至此,mydev内核驱动程序就完成了。这里采用的是系统提供的方法和驱动程序进行交互,也就是通过proc文件系统和devfs文件系统的方法。