前言
linux驱动开发的基础是开发一个module。module可以编译到内核中,也可以动态的使用insmod进行加载。将会使用动态加载的方式进行驱动开发。
正文
以一个简单的module最为开始,进行驱动的开发。
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
static int __init first_drv_init(void)
{
printk(" %s\n",__func__);
return 0;
}
static void __exit first_drv_exit(void)
{
printk("%s\n",__func__);
}
module_init(first_drv_init);
module_exit(first_drv_exit);
MODULE_LICENSE("GPL");
在上述的代码中,提供了用 __init 修饰的 first_drv_init 函数和用 __exit 修饰的 first_drv_exit 函数,这样的函数是每个 module 都必不可以少的。
提供了入口函数和出口函数,但是他们都是普通的函数,是如何告诉内核,他们是一个模块呢,这就需要使用 module_init 和 module_exit 进行修饰。
模块加载进行内核,需要进行授权,这里使用的是 GPL 协议。
入口函数,是一个带有返回值的函数,加载成功会返回 -1;加载失败将会返回负数,绝对值是错误码。这个错误码保存在应用进程 errno 中。在这里,仅仅使用 func 打印函数的名称,还没有进行其他的操作。
Makefile脚本文件
KERN_DIR = /work/linux-3.0.86
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf *.o *.symvers *.order *.ko *.mod.c *.markers .tmp_versions .*.cmd
obj-m +=first_drv.o
KERN_DIR 指定的是内核的目录。这里使用的 linux3.0.86 内核,不是系统自带的内核。这个内核需要在编译module 之前实现编译好。
在代码的目录下执行 make ,将会生成 first_drv.ko 文件。
操作
编译出 module first_drv.ko,使用 insmod加载到内核中。在加载后,可以使用 lsmod 查看加载已经加载的内核;在卸载的时候,使用 rmmod 卸载掉 module。
总结
module的开发基本框架就是这样,有了骨架,就可以进行填充内容,越来越丰满,功能也会越来越强大。