patch
时间:2010-10-12 来源:harryxiyou
在研究内核源代码之前,让我们先下载Linux源代码,学会打补丁,并查看内核源码树的布局。
首先,请到www.kernel.org下载最新的稳定的源代码[源代码以gzip(.zip)和bzip2 (.bz2)两种压缩格式提供],之后请进行解压缩。在下列命令中,请用最新的内核版本号(譬如2.6.23)代替X.Y.Z:
- bash> cd /usr/src
- bash> wget www.kernel.org/pub/linux/kernel/vX.Y/linux-X.Y.Z.tar.bz2
- ...
- bash> tar xvfj linux-X.Y.Z.tar.bz2
现在,你已经拥有位于/usr/src/linux-X.Y.Z/目录的源代码树,下面通过打-mm补丁(Andrew Morton)启动一些实验性测试特性。运行如下命令:
- bash> cd /usr/src
-
bash> wget www.kernel.org/pub/linux/
kernel/people/akpm/patches/X.Y/X.Y.Z/X.Y.Z- - mm2/X.Y.Z-mm2.bz2
打上这个补丁:
- bash> cd /usr/src/linux-X.Y.Z/
- bash> bzip2 -dc ../X.Y.Z-mm2.bz2 | patch -p1
命令中的-dc选项意味着让bzip2将指定的文件解压缩到标准输出。它被以管道方式输送到补丁实用程序,补丁程序会将补丁中的代码修改应用到源码树中的每个需要修改的文件。
如果你需要打多个补丁,请注意要采取正确的顺序。为了生成一个包含X.Y.Z-aa-bb补丁的内核,应首先下载X.Y.Z内核的完整源代码,再打上X.Y.Z-aa补丁,最后打上X.Y.Z-aa-bb补丁。
补丁提交
使用diff命令可以为你更改的内核产生补丁:
-
bash> diff -Nur /path/to/original/kernel /
path/to/your/kernel > changes.patch
要注意的是,在diff命令中,原始内核的路径应该放在修改后内核路径的前面。基于2.6内核补丁提交的公约,你需要在补丁的最后加上这样的一行:
- Signed-off-by: Name <Email>
这一行阐明了这些代码是由你编写的,你拥有贡献它的权利。
你现在就可以在相关的邮件列表(如LKML)中张贴你的补丁了。
文档Documentation/SubmittingPatches包含了一个创建和提交补丁的向导,而Documen- tation/applying-patches.txt是一个教你如何打补丁的教程。
现在,你打好补丁后的/usr/src/linux-X.Y.Z/已经准备好投入使用了。接下来,我们花一些时间来查看内核源代码树的结构。进入内核源代码树的根目录并列出它的子目录。
(1) arch。该目录包含了与体系结构相关的文件。可以在arch/目录下看到针对ARM、Motorola 68K、s390、MIPS、Alpha、SPARC和IA64等处理器的子目录。
(2) block。该目录主要包含块存储设备I/O调度算法的实现。
(3) crypto。该目录实现了密码操作以及与加密相关的API,它们可被应用于WiFi设备驱动的加密算法等场合。
(4) Documentation。该目录包含了内核中各个子系统的简要描述,它是你探究内核方面问题的第一站。
(5) drivers。这个目录包含了大量设备类和外设控制器的驱动,包括字符、串口、内置集成电路(I2C)、个人计算机存储卡国际联盟(PCMCIA)、外 围组件互连(PCI)、通用串行总线(USB)、视频、音频、块、集成驱动电子设备(IDE)、小型计算机系统接口(SCSI)、CD-ROM、网络适配 器、异步传输模式(ATM)、蓝牙和内存技术设备(MTD)等。每一类设备对应drivers/下面的一个子目录,譬如PCMCIA驱动程序的源代码位于 drivers/pcmcia/目录,MTD驱动程序位于drivers/mtd/目录。drivers/下的这些子目录是本书的主要议题。
(6) fs。这个目录包含了EXT3、EXT4、reiserfs、FAT、VFAT、sysfs、procfs、isofs、JFFS2、XFS、NTFS和NFS等文件系统的实现。
(7) include。内核头文件位于此目录。该目录下以asm开头的子目录包含了与体系结构相关的头文件,比如include/asm-x86/子目录包含了x86体系架构的头文件,include/asm-arm/包含了ARM体系架构的头文件。
(8) init。这个目录包含了高级别初始化和启动代码。
(9) ipc。这个目录包含了对消息队列、信号、共享内存等进程间通信(IPC)机制的支持。
(10) kernel。基本内核中与体系架构无关的部分。
(11) lib。通用内核对象(kobject)处理程序、循环冗余码校验(CRC)计算函数等库函数例程位于此目录。
(12) mm。这个目录包含了内存管理的实现。
(13) net。该目录实现了网络协议,包括Internet协议第4版(IPv4)、IPv6、网际互联交换协议(IPX)、蓝牙、ATM、红外、链路访问过程平衡(LAPB)以及逻辑链路控制(LLC)。
(14) scripts。内核编译过程中要使用的脚本位于此目录。
(15) security。这个目录包含了针对安全的框架。
(16) sound。Linux音频子系统位于此目录。
(17) usr。此目录包含了initramfs 的实现。
统一的x86架构源码树
从2.6.24内核版本开始,i386和x86_64(与32位的i386系统对应的64位系统)架构源码树已被统一纳入公共的arch/x86 /目录。如果你使用的是比2.6.24老的内核,请用arch/i386 /代替本书中所说的arch/x86 /目录。同样地,也请将include/asm-x86/替换为include/asm-i386/。此外,这些目录中的一些文件名也会有所不同。
在这么庞大的目录树中查找符号和代码是一项艰巨的任务,表1-1中的一些工具可以帮助你更方便地浏览内核源码树。
表1-1 源码树浏览工具
工具 |
描述 |
lxr |
Linux cross-referencer(Linux交叉引用程序), 可从http://lxr.sourceforge.net/下载。它可以让你 通过网页浏览器遍历内核源码树,因为它为内核 符号的定义和使用提供了超链接 |
cscope |
cscope(网址为http://cscope.sourceforge.net/)为内 核源码树内的所有文件建立一个符号数据库,通 过它可以快速地搜索声明、定义以及正则表达式 等。cscope可能不如lxr那般多才多艺,但是它很 灵活,允许你使用最喜欢的文本编辑器而不是浏 览器的搜索功能。在内核源码树的根目录,运行 cscope-qkRv命令就可建立交叉引用数据库。 -q选项将产生更多的索引信息以加快搜索速度, 但是初始启动会消耗更多的时间。-k要求cscope 调整它的行为以使用内核源代码,-R选项意味着 递归遍历子目录。在手册页面可以找到详细的调用规则 |
ctags/etags |
ctags(网址为http://ctags.sourceforge.net/)可用于 为许多语言产生交叉引用的标签。通过它,你可以 在vi等编辑器中找到源码树中的符号和函数定义。 从内核源码树的根目录运行make tags可以为所有文 件建立标签。etags为emacs编辑器产生相似的索引信 息。运行make TAGS可以采用etags为内核源文件创建标签 |
(续)
工具 |
描述 |
实用程序 |
grep、find、sdiff、strace、od、dd、 make、tar、file和objdump等工具 |
GCC选项 |
使用-E选项可以让GCC产生预处理源代码。预处理代 码包含头文件的扩展,并减少了为扩展多层宏定义在 多个嵌套的头文件间进行跳跃的需要。下面的例子预 处理drivers/char/mydrv.c并产生扩展后的输出文件mydrv.i: bash> gcc -E drivers/char/mydrv. c -D__KERNEL__ -Iinclude -Iinclude/asm-x86/mach-default > mydrv.i 使用-I选项可以指定你的代码所依赖的include的路径 使用-S选项可以让GCC产生汇编列表。下面的命令可 以为drivers/char/mydrv.c产生汇编文件mydrv.s: bash> gcc -S drivers/char/mydrv. c -D__KERNEL__ -Iinclude -Ianother/include/path |