一.如何让驱动程序运行起来
1.1 linux中驱动程序和应用程序的区别
linux系统中驱动程序运行在内核空间而应用程序运行在用户空间,他们之间有着很多的不同之处,应用程序是无后缀的,而驱动程序是带后缀".ko",比如hello.ko是驱动成员,而hello是应用程序。驱动程序通过命令 insmod 加载,通过命令 rmmod 卸载
1.2 如何在linux内核中运行我们的驱动程序
1.方法一
将驱动程序和linux内核"融为一体",即将驱动源码拷贝到内核源码中,并重新编译内核。
这个方法比较麻烦,因为每次修改驱动程序都需要重新编译整个内核源码树,并且驱动模块无法被卸载,驱动调试会带来很大的麻烦。
2.方法二
将驱动程序编译为可加载模块,然后使用 insmod 命令将驱动程序加载到内核中。
可加载模块的好处是可以手动加载和卸载,并且编译简单。不用重新内核镜像。加载驱动和运行应用程序一样的简单。
1.3 运行环境
1.开发板
任何开发板都可以,笔者采用是友善的nanopiM2,原因主要是便宜咸鱼价80块钱左右,还是多核的CPU,然后可以通过他的维基网站下载内核源码,uboot源码
2.编译器
这个编译器是交叉编译工具链,和应用程序一样的编译器即可。
3.内核源码
驱动程序即使不编译进内核,但编译驱动程序依然是需要内核源码,这是因为驱动编译的时候会去内核读取一些信息作为驱动程序的头部,当驱动加载的时候,内核会根据驱动程序的这些信息进行判断是否让驱动程序加载到内核之中。
最简单的驱动程序 hello.c :
#include <linux/init.h>
#include <linux/module.h>
static int hello_world_init(void)
{
printk(KERN_EMERG "hello_world hi!\n");/*加KERN_EMERG 用于紧急权限打印*/
return 0;
}
static void hello_world_exit(void)
{
printk(KERN_EMERG "hello_world goobye!\n");
}
module_init(hello_world_init);/*insmod 调用的函数*/
module_exit(hello_world_exit);/*rmmod 调用的函数*/
MODULE_AUTHOR("Jaya Kumar");
MODULE_LICENSE("GPL");
Makefile:
#目标
obj-m:=hello.o
#内核源码目录,读者根据自己情况修改这个参数!
KDIR:=/root/linux-3.4.y/
#获取当前目录
PWD:=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o *.ko
这个Makefile 语法比较简洁,通过 -C 参数
(
K
D
I
R
)
指
定
内
核
源
码
的
位
置
,
再
通
过
M
=
(KDIR) 指定 内核源码的位置,再通过 M=
(KDIR)指定内核源码的位置,再通过M=(PWD) 指定源文件hello.c的位置,通过 modules 指定编译目标为可加载模块。
将驱动程序hello.ko文件通过串口或者U盘再或者NFS方式传送到开发板中,然后用
insmod hello.ko 加载 观察打印信息,通过lsmod 可以查看当前所有加载中的可加载模块,最后通过rmmod hello.ko 卸载驱动程序。