linux内核模块编程1


http://bbs.chinaunix.net/thread-852547-1-1.html

Foreword

Table of Contents
作者声明
版本和注意
感谢
译者注
作者声明
《Linux内核驱动模块编程指南》最初是由Ori Pomerantz为2.2版本的内核编写的 ,后来,Ori将文档维护的任务交给了Peter Jay Salzman,Peter完成了2.4内核版本文档 的编写,毕竟Linux内核驱动模块是一个更新很快的内容。现在,Peter也无法腾出足够的 时间来完成2.6内核版本文档的编写,目前该2.6内核版本的文档由合作者Michael Burian 完成。

版本和注意
Linux内核模块是一块不断更新进步的内容,在LKMPG上总有关于是否保留还是历史 版本的争论。Michael和我最终是决定为每个新的稳定版本内核建立一个新的文档分支。也 就是说LKMPG 2.4.x专注于2.4的内核,而LKMPG 2.6.x将专注于2.6的内核。我们不会在一 篇文档中提供对旧版本内核的支持,对此感兴趣的读者应该寻找相关版本的文档分支。

在文档中的绝大部分源代码和讨论都应该适用于其它平台,但我无法提供任何保证。其中的一个例外就是 Chapter 12, 中断处理该章的源代码和讨论就只适用于x86平台。

感谢
感谢下列人士为此文档提供了他们宝贵的意见。他们是:Ignacio Martin, David Porter, Daniele Paolo,Scarpazza 和 Dimo Velev。
译者注
我,译者,名叫田竞,目前是一名在北京邮电大学就读的通信专业的大学生。 自高中起我就是Linux的爱好者并追随至今。我喜欢Linux给我带来的自由,我想大家也一样。没有人不向往自由。 

我学习内核模块编写时最初阅读的是Orelly出版社的使用2.0版本的内核的书籍,但如同我预料的一样, 书中的许多事例由于内核代码的变化而无法使用。这让想亲自体验内核模块的神秘的我非常苦恼。 我在Linux文档计划在上海的镜像站ldp.linuxforum.net上找到了这篇文档。 

受原作者Ori的鼓励,基于上次完成的LKMPG 2.4的,内容有稍许的改变和扩充。应该是目前最新的了。 翻译的方式有所改变,在基于LDP认可的docbook格式上翻译,通过docbook2html转换为附件中的html文档。 由于对docbook不是很熟悉,其中的一些标题尚未翻译,而且可能破坏了原有的tag,导致html出现一些错误显示, 但总体来说很少。修改了很多2.4中的错别字。 
学习并分享学习的过程是我翻译的最终目的。


Chapter 1. Introduction
Table of Contents
什么是内核模块?
内核模块是如何被调入内核工作的?
什么是内核模块?
现在,你是不是想编写内核模块。你应该懂得C语言,写过一些用户程序, 那么现在你将要见识一些真实的东西。在这里,你会看到一个野蛮的指针是如何 毁掉你的文件系统的,一次内核崩溃意味着重启动。

什么是内核模块?内核模块是一些可以让操作系统内核在需要时载入和执 行的代码,这同样意味着它可以在不需要时有操作系统卸载。它们扩展了操作系 统内核的功能却不需要重新启动系统。举例子来说,其中一种内核模块时设备驱 动程序模块,它们用来让操作系统正确识别,使用安装在系统上的硬件设备。如 果没有内核模块,我们不得不一次又一次重新编译生成单内核操作系统的内核镜 像来加入新的功能。这还意味着一个臃肿的内核。
内核模块是如何被调入内核工作的?
你可以通过执行lsmod命令来查看内核已经加载了哪 些内核模块, 该命令通过读取/proc/modules文件的内容 来获得所需信息。

这些内核模块是如何被调入内核的?当操作系统内核需要的扩展功能不存 在时,内核模块管理守护进程kmod[1]执行modprobe去加载内核模 块。两种类型的参数被传递给modprobe:


一个内核模块的名字像softdog或是ppp。

通用识别符像char-major-10-30。

当传递给modprobe是通用识别符时,modprobe首先在文件 /etc/modules.conf查找该字符串。如果它发现的一行别名像:

alias char-major-10-30 softdog
        
它就明白通用识别符是指向内核模块softdog.o。

然后,modprobe遍历文件/lib/modules/version/modules.dep 来判断是否有其它内核模块需要在该模块加载前被加载。该文件是由命令depmod -a 建立,保存着内核模块的依赖关系。举例来说,msdos.o依赖于模块fat.o 内核模块已经被内核载入。当要加载的内核模块需要使用别的模块提供的符号链接时(多半是变量或函数), 那么那些提供这些所需符号链接的内核模块就被该模块所依赖。

最终,modprobe调用insmod先加载被依赖的模块,然后加载该被内核要求的模块。modprobe将insmod指向 /lib/modules/version/[2]目录,该目录为默认标准存放内核模块的目录。insmod对内核模块存放位置 的处理相当呆板,所以modprobe应该很清楚的知道默认标准的内核模块存放的位置。所以,当你想要载入一个内 核模块时,你可以执行:

insmod /lib/modules/2.5.1/kernel/fs/fat/fat.o
insmod /lib/modules/2.5.1/kernel/fs/msdos/msdos.o
        
或只是执行"modprobe -a msdos"。

Linux提供modprobe, insmod and depmod在一个名为modutils 或 mod-utils的工具包内。

在结束本章前,让我们来看一个 /etc/modules.conf文件:

#This file is automatically generated by update-modules
path[misc]=/lib/modules/2.4.?/local
keep
path[net]=~p/mymodules
options mydriver irq=10
alias eth0 eepro
        
用'#'起始的行为注释。空白行被忽略。

以 path[misc]起始的行告诉modprobe用 /lib/modules/2.4.?/local替代搜寻 misc内核模块的路径。正如你看到的,命令解释器shell的元字符也可以使用。

以path[net]起始的行告诉modprobe 在目录 ~p/mymodules搜索网络方面的内核模块。但是,在path[net] 指令之前使用的"keep" 指令告诉modprobe只是将该路径添加到标准搜索路径中,而不是像对待 misc前面那样进行替换。

以alias 起始的的行使modprobe加载eepro.o当kmod 以通用识别符'eth0' 要求加载相应内核模块时。

你不会发现像"alias block-major-2 floppy"这样的别名行在文件/etc/modules.conf 因为modprobe已经知道在绝大多数系统上安装的标准的设备的驱动模块。

现在你已经知道内核模块是如何被调入的了。当你想写你自己的依赖于其它模块的内核模块时, 还有一些内容没有提供。这个相对高级的问题将在以后的章节中介绍,当我们已经完成前面的学习后。 

在开始前
在我们介绍源代码前,有一些事需要注意。系统彼此之间的不同会导致许多困难。 顺利的编译并且加载你的第一个"hello world"模块有时就会比较困难。但是当你跨过 这道坎时,后面会顺利的多。

内核模块和内核的版本问题
为某个版本编译的模块将不能被另一个版本的内核加载如果内核中打开了 CONFIG_MODVERSIONS选项。我们暂时不会讨论与此相关的 内容。在我们进入相关内容前,本文档中的范例可能在该选项打开的情况下无法 工作。但是,目前绝大多数的发行版是将该选项打开的。所以如果你遇到和版本 相关的错误时,最好,重新编译一个关闭该选项的内核。

使用 X带来的问题
强烈建议你在控制台下输入文档中的范例代码,编译然后加载模块,而不是在X下。

模块不能像printf()那样输出到屏幕,但它们可以 记录信息和警告,当且仅当你在使用控制台时这些信息才能最终显示在屏幕上。 如果你从xterm中insmod一个模块,这些日志信息只会记录在你的日志文件中。 除了查看日志文件你将无法 得到输出信息。想要及时的获得这些日志信息,建议 所有的工作都在控制台下进行。

编译相关和内核版本相关的问题
Linux的发行版经常给内核打一些非标准的补丁,这种情况回导致一些问题的发生。

一个更普遍的问题是一些Linux发行版提供的头文件不完整。编译模块时你将需要非常多 的内核头文件。墨菲法则之一就是那些缺少的头文件恰恰是你最需要的。

我强烈建议从Linux镜像站点下载源代码包,编译新内核并用新内核启动系统来避免以上 的问题。参阅"Linux Kernel HOWTO"获得详细内容。

具有讽刺意味的是,这也会导致一些问题。gcc倾向于在缺省的内核源文件路径(通常是/usr/src/)下寻找源代码文件。这可以通过gcc的-I 选项来切换。

Notes
[1] 在早期的linux版本中,是 一个名为kerneld的守护进程。

[2] 如果你在修改内核,为避免 覆盖你现在工作的模块,你应该试试使用内核Makefile中的变量EXTRAVERSION去建立一个独 立的模块目录。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值