内核模块

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内核编程的一些基本知识:

内存

在Linux内核模式下,我们不能使用用户态的malloc()和free()函数申请和释放内存。进行内核编程时,最常用的内存申请和释放函数为在include/linux/kernel.h文档中声明的kmalloc()和kfree(),其原型为:

void *kmalloc(unsigned int len, int priority);

void kfree(void *__ptr);

kmalloc的priority参数通常配置为GFP_KERNEL,假如在中断服务程式里申请内存则要用GFP_ATOMIC参数,因为使用GFP_KERNEL参数可能会引起睡眠,不能用于非进程上下文中(在中断中是不允许睡眠的)。

由于内核态和用户态使用不同的内存定义,所以二者之间不能直接访问对方的内存。而应该使用Linux中的用户和内核态内存交互函数(这些函数在include/asm/uaccess.h中被声明):

unsigned long copy_from_user(void *to,const void *from, unsigned long n);

unsigned long copy_to_user (void * to, void * from, unsigned long len);

copy_from_user、copy_to_user函数返回不能被复制的字节数,因此,假如完全复制成功,返回值为0。

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!