Foreword (3)
作者声明 (3)
idea2022激活码绝对有效版本和注意 (3)
感谢 (3)
译者注 (3)
Chapter1.Introduction (4)
什么是内核模块? (4)
内核模块是如何被调入内核工作的? (4)
Chapter2.Hello World (7)
Hello,World(part1):最简单的内核模块 (7)
Hello World(part2) (9)
pledge是什么意思
Hello World(part3):关于__init和__exit宏 (10)
Hello World(part4):内核模块证书和内核模块文档说明 (11)
从命令行传递参数给内核模块 (13)
由多个文件构成的内核模块 (16)
为已编译的内核编译模块 (18)
如何在手机编程Chapter3.Preliminaries (20)
常量元素越多越好吗内核模块和用户程序的比较 (20)
内核模块是如何开始和结束的 (20)
模块可调用的函数 (20)
用户空间和内核空间 (21)
命名空间 (21)
代码空间 (22)
Device Drivers (22)
Chapter4.Character Device Files (24)
字符设备文件 (24)
关于file_operations结构体 (24)
Chapter5.The/proc File System (32)
关于/proc文件系统 (32)
Chapter6.Using/proc For Input (36)
使用/proc作为输入 (36)
Chapter7.Talking To Device Files (43)
与设备文件对话(writes and IOCTLs) (43)
Chapter8.System Calls (56)
系统调用 (56)
Chapter9.Blocking Processes (62)
阻塞进程 (62)
Chapter10.Replacing Printks (70)
替换printk (70)
让你的键盘指示灯闪起来 (72)
Chapter11.Scheduling Tasks (76)
任务调度 (76)
Chapter12.Interrupt Handlers (81)
Interrupt Handlers (81)
Chapter13.Symmetric Multi Processing (86)
对称多线程处理 (86)
LINUX内核模块编程[转] Chapter14.Common Pitfalls (87)
注意 (87)
Appendix B.Where To Go From Here (89)
为什么这样写? (89)
2
LINUX内核模块编程[转]
linux操作系统书籍Foreword
作者声明
《Linux内核驱动模块编程指南》最初是由Ori Pomerantz为2.2版本的内核编写的,后来,Ori将文档维
护的任务交给了Peter Jay Salzman,Peter完成了2.4内核版本文档的编写,毕竟Linux内核驱动模块是一个更新很快的内容。现在,Peter也无法腾出足够的时间来完成2.6内核版本文档的编写,目前该2.6内核版本的文档由合作者Michael Burian完成。
版本和注意
Linux内核模块是一块不断更新进步的内容,在LKMPG上总有关于是否保留还是历史版本的争论。Michael和我最终是决定为每个新的稳定版本内核建立一个新的文档分支。也就是说LKMPG2.4.x专注于2.4的内核,而LKMPG2.6.x将专注于2.6的内核。我们不会在一篇文档中提供对旧版本内核的支持,对此感兴趣的读者应该寻相关版本的文档分支。
在文档中的绝大部分源代码和讨论都应该适用于其它平台,但我无法提供任何保证。其中的一个例外就是Chapter12,中断处理该章的源代码和讨论就只适用于x86平台。
感谢
感谢下列人士为此文档提供了他们宝贵的意见。他们是:Ignacio Martin,David Porter,Daniele Paolo,Scarpazza和Dimo Velev。
译者注
我,译者,名叫田竞,目前是一名在北京邮电大学就读的通信专业的大学生。自高中起我就是Linux的爱好者并追随至今。我喜欢Linux给我带来的自由,我想大家也一样。没有人不向往自由。
我学习内核模块编写时最初阅读的是Orelly出版社的使用2.0版本的内核的书籍,但如同我预料的一样,书中的许多事例由于内核代码的变化而无法使用。这让想亲自体验内核模块的神秘的我非常苦恼。我在Linux文档计划在上海的镜像站ldp.linuxforum上到了这篇文档。
受原作者Ori的鼓励,基于上次完成的LKMPG  2.4的,内容有稍许的改变和扩充。应该是目前最新的了。翻译的方式有所改变,在基于LDP认可的docbook格式上翻译,通过docbook2html转换为附件中的html文档。由于对docbook不是很熟悉,其中的一些标题尚未翻译,而且可能破坏了原有的tag,导致html出现一些错误显示,但总体来说很少。修改了很多2.4中的错别字。
学习并分享学习的过程是我翻译的最终目的。
3
LINUX内核模块编程[转] Chapter1.Introduction
什么是内核模块?
现在,你是不是想编写内核模块。你应该懂得C语言,写过一些用户程序,那么现在你将要见识一些真实的东西。在这里,你会看到一个野蛮的指针是如何毁掉你的文件系统的,一次内核崩溃意味着重启动。
什么是内核模块?内核模块是一些可以让操作系统内核在需要时载入和执行的代码,这同样意味着它可以在不需要时有操作系统卸载。它们扩展了操作系统内核的功能却不需要重新启动系统。举例子来说,其中一种内核模块时设备驱动程序模块,它们用来让操作系统正确识别,使用安装在系统上的硬件设备。如果没有内核模块,我们不得不一次又一次重新编译生成单内核操作系统的内核镜像来加入新的功能。这还意味着一个臃肿的内核。
内核模块是如何被调入内核工作的?
你可以通过执行lsmod命令来查看内核已经加载了哪些内核模块,该命令通过读取/proc/modules文件的内容来获得所需信息。
这些内核模块是如何被调入内核的?当操作系统内核需要的扩展功能不存在时,内核模块管理守护进程kmod[1]执行modprobe去加载内核模块。两种类型的参数被传递给modprobe:
一个内核模块的名字像softdog或是ppp。
create or replace table通用识别符像char-major-10-30。
当传递给modprobe是通用识别符时,modprobe首先在文件/f查该字符串。如果它发现的一行别名像:
alias char-major-10-30softdog
它就明白通用识别符是指向内核模块softdog.o。
然后,modprobe遍历文件/lib/modules/version/modules.dep来判断是否有其它内核模块需要在该模块加载前被加载。该文件是由命令depmod-a建立,保存着内核模块的依赖关系。举例来说,msdos.o依赖于模块fat.o内核模块已经被内核载入。当要加载的内核模块需要使用别的模块提供的符号链接时(多半是变量或函数),那么那些提供这些所需符号链接的内核模块就被该模块所依赖。
最终,modprobe调用insmod先加载被依赖的模块,然后加载该被内核要求的模块。modprobe将insmod指向/lib/modules/version/[2]目录,该目录为默认标准存放内核模块的目录。insmod对内核模块存放位置的处理相当呆板,所以modprobe应该很清楚的知道默认标准的内核模块存放的位置。所以,当你想要载入一个内核模块时,你可以执行:
4
或只是执行"modprobe-a msdos"。
Linux提供modprobe,insmod and depmod在一个名为modutils或mod-utils的工具包内。
在结束本章前,让我们来看一个/f文件:
#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 eth0eepro
用'#'起始的行为注释。空白行被忽略。
以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-2floppy"这样的别名行在文件/f因为modprobe已经知道在绝大多数系统上安装的标准的设备的驱动模块。
现在你已经知道内核模块是如何被调入的了。当你想写你自己的依赖于其它模块的内核模块时,还有一些内容没有提供。这个相对高级的问题将在以后的章节中介绍,当我们已经完成前面的学习后。
在开始前
在我们介绍源代码前,有一些事需要注意。系统彼此之间的不同会导致许多困难。顺利的编译并且加载你的第一个"hello world"模块有时就会比较困难。但是当你跨过这道坎时,后面会顺利的多。
内核模块和内核的版本问题
为某个版本编译的模块将不能被另一个版本的内核加载如果内核中打开了CONFIG_MODVERSIONS 选项。我们暂时不会讨论与此相关的内容。在我们进入相关内容前,本文档中的范例可能在该选项打开的情况下无法工作。但是,目前绝大多数的发行版是将该选项打开的。所以如果你遇到和版本相关的错误时,最好,重新编译一个关闭该选项的内核。
使用X带来的问题
强烈建议你在控制台下输入文档中的范例代码,编译然后加载模块,而不是在X下。
5

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。