Linux设备驱动编程内核模块的学习

Linux设备驱动属于内核的一部分,Linux内核的一个模块可以以两种方式被编译和加载:

(1)直接编译进Linux内核,随同Linux启动时加载;

(2)编译成一个可加载和删除的模块,使用insmod加载(modprobe和insmod命令类似,但依赖于相关的配置文件),rmmod删除。这种方式控制了内核的大小,而模块一旦被插入内核,它就和内核其他部分一样。

下面我们给出一个内核模块的例子:

#include <linux/module.h> //所有模块都需要的头文件 #include <linux/init.h> // init&exit相关宏 MODULE_LICENSE("GPL"); static int __init hello_init (void) {  printk("Hello module init\n");  return 0; } static void __exit hello_exit (void) {  printk("Hello module exit\n"); } module_init(hello_init); module_exit(hello_exit);  

分析上述程序,发现一个Linux内核模块需包含模块初始化和模块卸载函数,前者在 insmod的时候运行,后者在rmmod的时候运行。初始化与卸载函数必须在宏module_init和module_exit使用前定义,否则会出现编译错误。程序中的MODULE_LICENSE("GPL")用于声明模块的许可证。

如果要把上述程序编译为一个运行时加载和删除的模块,可以编写makefile文件如下:

CC =/usr/local/arm/2.95.3/bin/arm-linux-gcc KERNELDIR=/home/work/linux-2.4 CFLAGS =-D__KERNEL__ -DMODULE -I$(KERNELDIR)/include -O -Wall test.o:test.c $(CC)$(CFLAGS) -c $< clean: rm -rf *.o  

由此可见,Linux内核模块的编译需要给arm-linux-gcc指示-D__KERNEL__ -DMODULE 参数。-I选项跟着Linux内核源代码中Include目录的路径。

下列命令将可加载hello模块:

insmod ./hello.o

下列命令完成相反过程:

rmmod hello

如果要将其直接编译入Linux内核,则需要将源代码文件拷贝入Linux内核源代码的相应路径里,并修改Makefile。

我们有必要补充一下Linux内核编程的一些基本知识:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzwxyw.html