makefile脚本的编写。
obj-m是将驱动编译成模块的形式,obj-y是将驱动编译进内核。我是讲led驱动做成模块,可以用insomd和rmmod进行模块的安装、删除。我是在ubuntu10.04的虚拟机上编译驱动的,led驱动运行在tiny6410开发板上,因此内核的路径应该选择的tiny6410的内核路径。在虚拟机上编译linux-2.6.38的源码,用的是友善提供的源码,主要是在make menuconfig时注意允许模块装载的选项,其他的默认。直接make。查看arch/arm/boot/目录下是否生成zImage文件,稍后需要将这个文件烧录到tiny6410中。在makefile脚本中进行编译的内核路径就选择刚才编译号的内核路径KERNELDIR = /usr/local/FriendlyARM/tiny6410/linux/linux-2.6.38/。当然可以用内核树的路径就是/lib/module/`uname -r`/build者个链接文件。(其实也可以在tiny6410中直接编译驱动)
obj-m := MiscDev.o
CURRENT_PATH = $(shell pwd)
KERNELDIR = /usr/local/FriendlyARM/tiny6410/linux/linux-2.6.38/
all:MiscDev.o led_test.o
MiscDev.o:MiscDev.c
make -Wall -C $(KERNELDIR) M=$(CURRENT_PATH) modules
led_test.o:led_test.c
arm-linux-gcc -Wall -o led_test led_test.c
clean:
make -Wall -C $(KERNELDIR) M=$(CURRENT_PATH) clean
-rm -fr *.o led_test
全部弄完之后,将MiscDev.ko、led_test文件下载到开发板上,修改文件的属性为可执行chmod a+x 显示结果。
安装驱动,查看驱动
执行测试函数
卸载驱动
小结:
这次写驱动遇到了许多问题,一开始是写一个在虚拟机上运行的hello字符设备驱动模块。但是内核环境不对,老是提示要make oldconfig && make prepare进行修复。执行了之后,又会出现缺少文件的错误。不甚其烦,最后决定重新编译内核下了2.6.32.61的内核版本,编译了一个晚上。在执行时没问题了,在insmod驱动时出现了几次错误驱动的提示(忘了将错误截图了==),出现原因有模块之前已经安装了,驱动的编译内核和目标板的内核不一致。解决办法就是lsmod |grep 驱动名 ,找到驱动rmmod它。要么就是重新加载内核。然后就是给开发板写驱动,主要还是交叉编译环境和目标板的内核,处理好了就没有问题。驱动的内容还很深,一开始真不好弄,不过出现问题,分析问题,解决问题的过程很享受。从地域到天堂,周而复始,不做真会死!