Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6658634
  • 博文数量: 915
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8846
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(915)

文章存档

2022年(9)

2021年(13)

2020年(10)

2019年(40)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: 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.cMakefile文件应该位于同一个目录下,,本文的两个文件都位于//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$

阅读(1764) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~