一个好老好老的老程序员了。
全部博文(915)
分类: LINUX
2011-06-06 12:25:29
以下是内核模块的编译:
linux内核是一个整体是结构。因此向内核添加任何东西.或者删除某些功能,都十分困难。为了解决这个问题。引入了内核机制.从而可以动态的想内核中添加或者删除模块。模块不被编译在内核中,因而可以控制了内核的大小。然而模块一旦被插入内核,它就和内核其它部分一样。
Linux® 可加载内核模块(从内核的 1.2 版本开始引入)是 Linux 内核的最重要创新之一。它们提供了可伸缩的、动态的内核。探索隐藏在可加载模块后面的原理,并学习这些独立的对象如何动态地转换成 Linux 内核的一部分。
单内核(monolithic kernel),即操作系统的大部分功能都被称为内核,并在特权模式下运行。它与微型内核不同,后者只把基本的功能(进程间通信 [IPC]、调度、基本的输入/输出 [I/O] 和内存管理)当作内核运行,而把其他功能(驱动程序、网络堆栈和文件系统)排除在特权空间之外。因此,您可能认为 Linux 是一个完全静态的内核,但事实恰恰相反。通过 Linux 内核模块(LKM)可以在运行时动态地更改 Linux。
LKM 与直接编译到内核或典型程序的元素有根本区别。典型的程序有一个 main 函数,其中 LKM 包含一个入口函数和退出函数(在 2.6 版本,您可以任意命名这些函数)。当向内核插入模块时,调用入口函数,从内核删除模块时则调用退出函数。因为入口函数和出口函数是用户定义的,所以存在 module_init 和 module_exit 宏,用于定义这些函数属于哪种函数。LKM 还包含一组必要的宏和一组可选的宏,用于定义模块的许可证、模块的作者、模块的描述等等。
LKM 只不过是一个特殊的可执行可链接格式(Executable and Linkable Format,ELF)对象文件。通常,必须链接对象文件才能在可执行文件中解析它们的符号和结果。由于必须将 LKM 加载到内核后 LKM 才能解析符号,所以 LKM 仍然是一个 ELF 对象。您可以在 LKM 上使用标准对象工具(在 2.6 版本中,内核对象带有后缀 .ko,)。例如,如果在 LKM 上使用 objdump 实用工具,您将发现一些熟悉的区段(section),比如 .text(说明)、.data(已初始化数据)和 .bss(块开始符号或未初始化数据)
下面 提供了一个非常简单的 LKM 程序。
以一个非常简单的程序hello.c为例:
/*hello.c*/
#include
#include
MODULE_LICENSE(“GPL”); //General Public License
static int hello_init(void)
{
printk(KERN_ALERT “Hello, world!\n”);
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT”Goodbye world!\n”);
}
module_init(hello_init);
module_exit(hello_exit);
程序说明:
(1)第一行的头文件包含了内核模块初始化和退出时处理的宏。第二行应用的头文件包含了内核模块相关的数据结构。
(2)第三行是用于定义模块的许可证。这里还可以定义模块的作者、模块的描述等等。
(3)第四行到第八行是这个模块初始化函数。
(4)第九行到第十二行是退出函数。
(5)第十三行模块入口函数module_init对模块初始化函数的调用。在内核模块执行时是不直接认模块初始化函数的,初始化函数需要模块入口函数module_init的引见。
(6)第十四行是模块出口函数module_exit对模块退出处理函数的调用。实现在退出时释放进入时申请的空间和不用指针。
Makefile文件的内容为:
obj-m := hello.o
KERNELDIR := /usr/src/kernels/linux-2.6.24/
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
其中,hello.c和Makefile文件应该位于同一个目录下,,本文的两个文件都位于//home/helight/linux/linux-test/khello
编译和装载模块:
在文件所处的目录下,执行:
helight@helight-desktop:~/linux/linux-test/khello$ make
make -C /usr/src/linux-2.6.24/ M=/home/helight/linux/linux-test/khello modules
make[1]: Entering directory `/usr/src/linux-2.6.24′
CC [M] /home/helight/linux/linux-test/khello/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/helight/linux/linux-test/khello/hello.mod.o
LD [M] /home/helight/linux/linux-test/khello/hello.ko
make[1]: Leaving directory `/usr/src/linux-2.6.24′
helight@helight-desktop:~/linux/linux-test/khello$ ls
hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile Module.symvers
helight@helight-desktop:~/linux/linux-test/khello$
插入使用模块
helight@helight-desktop:~/linux/linux-test/khello$ sudo insmod hello.ko
helight@helight-desktop:~/linux/linux-test/khello$ lsmod |grep hello
hello 2688 0
helight@helight-desktop:~/linux/linux-test/khello$ sudo rmmod hello
helight@helight-desktop:~/linux/linux-test/khello$ dmesg
….
helight@helight-desktop:~/linux/linux-test/khello$Hello, world!
helight@helight-desktop:~/linux/linux-test/khello$Goodbye world!
helight@helight-desktop:~/linux/linux-test/khello$