Linux 驱动哪些部分是必须的
- 模块入口函数
模块的入口函数也称模块加载函数,当你执行 insmod 或 modprobe 命令加
载驱动模块到内核时,驱动模块的入口函数就会自动被内核执行。 至于模块入口
函数需要完成什么工作,这就你决定了。 - 模块出口函数
模块的出口函数也称为模块卸载函数,当你执行 rmmod 命令卸载驱动模块
时,驱动模块的出口函数就会自动被内核执行。 至于模块出口函数需要完成什么
工作,这个也是你决定的。 - 模块许可证声明
许可证(LICENSE)声明该模块的许可权限,如果不声明,就会收到内核的警
告。
Hello驱动源码
#include <linux/module.h>
#include <linux/kernel.h>
/* 驱动程序的入口函数 */
static int __init hello_init(void)
{
printk(KERN_WARNING "hello_init!\n");
printk(KERN_WARNING "Hello,world!\n");
return 0;
}
/* 驱动程序的出口函数 */
static void __exit hello_exit(void)
{
printk(KERN_WARNING "hello_exit!\n");
printk(KERN_WARNING "Goodbye,world!\n");
}
/* 用于修饰入口/出口函数,换句话说,相当于
* 告诉内核驱动程序的入口/出口函数在哪里
*/
module_init(hello_init);
module_exit(hello_exit);
/* 该驱动支持的协议 */
MODULE_LICENSE("GPL");
hello驱动分析
- hello_init 函数就是我们上面所说的模块入口函数,当执行
insmod 命令时,该函数就会被调用,显然就会打印二条语句。 - hello_exit 函数就是我们上面所说的模块出口函数,当执行
rmmod 命令时,该函数就会被调用,显然也会打印二条语句。 - 模块入口/出口函数
module_init(hello_init);
module_exit(hello_exit);
- 每个函数前面都有static关键字,在Linux驱动中,大部分函数都会冠以static关键字,它表示该函数只能在本文件内使用,其他文件的函数不能调用它。如果非要用它不可的话,需要将函数导出。
EXPORT_SYMBOL(name)
或者
EXPORT_SYMBOL_GPL(name)
- __init 和__exit
__init 表示用__init 修饰过的函数仅仅在初始化期间内有效,在模块被加载之
后,即 insmod 之后,模块装器就会将初始化函数丢弃,之后任何函数也没有办
法调用初始化函数,因为该函数已经从内存中释放出来。 __exit 同理。 - printk 打印等级
printk 函数共有 7 个打印等级, 默认打印等级为 4, 级别越小,表示情况越
紧急,越是要将信息输出到你的串口终端。 大于 4 的等级将不会出现在串口中断,
需要你使用其他方法查看, 比如 dmesg 命令查看。
通用的Makefile
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KDIR := /home/work/linux-3.8_webee210
all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order
endif
Makefile简要分析
- obj-m := hello.o 这句的意思是, hello.ko 模块需要从目标文件 hello.o 中构造, -m 的意思是编译成模块,而不编译进内核。
- KDIR := /home/work/linux-3.8_webee210 它表示驱动模块的编译需要到这个路径去编译。
- ARCH=arm 代表架构为 arm 而不是 X86, CROSS_COMPILE=arm-linux-代表交叉编译工具为 arm-linux-XXX,如: arm-linux-gcc、 arm-linux-ld 等等。
- 清除工作,下面两行表示表示执行 make clean 的时候,删除所有符合上面格式的文件。
Hello 驱动测试
- 以模块方式加载驱动到内核:insmod hello.ko
- 查看当前已经加载的驱动模块:lsmod
- 从内核中卸载模块:rmmod hello
内核配置驱动
make meuconfig
Ubuntu会出现以下错误
*** Unable to find the ncurses libraries or the
*** required header files.
*** 'make menuconfig' requires the ncurses libraries.
***
*** Install ncurses (ncurses-devel) and try again.
***
make[1]: *** [scripts/kconfig/dochecklxdialog] Error 1
make: *** [menuconfig] Error 2
解决方法:
sudo apt-get install ncurses-dev
将驱动配置到内核步骤:
- 拷贝 hello.c 到 Linux 源码的 drivers/char 目录下。
- 修改 drivers/char 目录下的 Konfig。
config Hello
tristate "Frist Driver --Hello"
depends on ARCH_S5PV210
help
This is frist driver for hello.
- 修改 drivers/char 目录下的 Makefile
- 使用 make menuconfig 命令进行配置。
进入 Device Driver–>Character devices–>后
保存配置后,如上图所示保存为,即以模块方式加载进内核,如果保存
为<*>,表示编译进内核。输入 make modules 命令就可以编译模块了。 如果以
模块的方式编译,那么可以在相应目录下找到相应的.ko 文件。比如:
在 drivers/char/目录下面,可以找到 hello.ko 文件。