本章描述了你应该在Linux核心源程序的什么地方开始查看特定的核心功能。
本书不依赖‘C’语言的知识或要求你有Linux核心源程序才能理解Linux核心如何工作。而是说,练习查看核心源程序能够对于Linux操作系统有一个深入地理解。本章给出核心源程序的概览:它们如何组织,你应该从哪里开始查找特定的代码。
Where to Get The Linux Kernel Sources(从哪里得到Linux核心源程序)
所有的主要的Linux分发(Craftworks,Debian,Slackware,RedHat 等等)中间都有核心源程序。通常L安装在你的Linux系统上的Linux核心都是用这些源程序建立的。实际上这些源程序显得有些过时,所以你可能希望得到附录C提到的web站点得到最新的源程序。它们放在ftp://ftp.cs.helsinki.fi和其它所有的镜像的web站点。Helsinki的web站点最新,但是其它站点例如MIT和Sunsite也不会太落后。
如果你无法访问web,还有许多CDROM厂家用非常合理的费用提供世界主要web站点的块找。一些甚至提供预订服务,按季或月进行更新。你的本地的Linux用户组也是一个源程序的好的来源。
Linux核心源程序有一个非常简单的编号系统。任何偶数的核心(例如2.0.30)都是一个稳定的发行的核心,而任何奇数的核心(例如2.1.42)都是一个开发中的核心。本书基于稳定的2.0.30源代码。开发版的核心具有所有的最新特点和所有最新的设备的支持,但是它们可能不稳定,可能不是你所要的,但是让Linux社团测试最新核心是很重要的。这样可以让整个社团都进行测试。记住,即使你测试非生产用核心,最好也要备份你的系统。
对于核心源程序的改动作为patch文件分发。工具patch可以对于一系列源文件应用一系列修改。例如,如果你有2.0.29的源程序树,而你希望转移到2.0.30,你可以取到2.0.30的patch文件,并把这些patch(编辑)应用到源程序树上:
$ cd /usr/src/linux
$ patch -p1 < patch-2.0.30
这样可以不用拷贝整个源程序树,特别对于慢速的串行连接。一个核心补丁(正式和非正式的)的好来源是http://www.linuxhq.com
How The Kernel Sources Are Arranged(核心源程序如何组织)
在源程序树的最上层你会看到一些目录:
arch arch子目录包括所有和体系结构相关的核心代码。它还有更深的子目录,每一个代表一种支持的体系结构,例如i386和alpha。
Include include子目录包括编译核心所需要的大部分include文件。它也有更深的子目录,每一个支持的体系结构一个。Include/asm是这个体系结构所需要的真实的include目录的软链接,例如include/asm-i386。为了改变体系结构,你需要编辑核心的makefile,重新运行Linux的核心配置程序
Init 这个目录包含核心的初始化代码,这时研究核心如何工作的一个非常好的起点。
Mm 这个目录包括所有的内存管理代码。和体系结构相关的内存管理代码位于arch/*/mm/,例如arch/i386/mm/fault.c
Drivers 系统所有的设备驱动程序在这个目录。它们被划分成设备驱动程序类,例如block。
Ipc 这个目录包含核心的进程间通讯的代码
Modules 这只是一个用来存放建立好的模块的目录
Fs 所有的文件系统代码。被划分成子目录,每一个支持的文件系统一个,例如vfat和ext2
Kernel 主要的核心代码。同样,和体系相关的核心代码放在arch/*/kernel
Net 核心的网络代码
Lib 这个目录放置核心的库代码。和体系结构相关的库代码在arch/*/lib/
Scripts 这个目录包含脚本(例如awk和tk脚本),用于配置核心
Where to Start Looking(从哪里开始看)
看像Linux核心这么巨大复杂的程序相当困难。它就像一个巨大的线球,显示不出终点。看核心的一部分代码通常会引到查看其它几个相关的文件,不就你就会忘记你看了什么。下一节给你一个提示,对于一个给定的主题,最好看源程序树的那个地方。
System Startup and Initialization(系统启动和初始化)
在一个Intel系统上,当loadlin.exe或LILO把核心加载到内存并把控制权交给它的时候,核心开始启动。这一部分看arch/i386/kernel/head.S。head.S执行一些和体系结构相关的设置工作并跳到init/main.c中的main()例程。
Memory Management(内存管理)
代码大多在mm但是和体系结构相关的代码在arch/*/mm。Page fault处理代码在mm/memory.c中,内存映射和页缓存代码在mm/filemap.c 中。Buffer cache 在mm/buffer.c中实现,交换缓存在mm/swap_state.c和mm/swapfile.c中。
Kernel
大部分相对通用的代码在kernel,和体系结构相关的代码在arch/*/kernel。调度程序在kernel/sched.c,fork代码在kernel/fork.c。bottom half 处理代码在include/linux/interrupt.h。task_struct数据结构可以在include/linux/sched.h中找到
PCI
PCI伪驱动程序在drivers/pci/pci.c,系统范围的定义在include/linux/pci.h。每一种体系结构都有一些特殊的PCI BIOS代码,Alpha AXP的位于arch/alpha/kernel/bios32.c
Interprocess Communication
全部在ipc目录。所有系统V IPC对象都包括ipc_perm数据结构,可以在include/linux/ipc.h中找到。系统V消息在ipc/msg.c中实现,共享内存在ipc/shm.c中,信号灯在ipc/sem.c。管道在ipc/pipe.c中实现。
Interrupt Handling
核心的中断处理代码几乎都是和微处理器(通常也和平台)相关。Intel中断处理代码在arch/i386/kernel/irq.c它的定义在incude/asm-i386/irq.h。
Device Drivers(设备驱动程序)
Linux核心源代码的大部分代码行在它的设备驱动程序中。Linux所有的设备驱动程序源代码都在drivers中,但是它们被进一步分类:
/block 块设备驱动程序比如ide(ide.c)。如果你希望查看所有可能包含文件系统的设备是如何初始化的,你可以看drivers/block/genhd.c中的device_setup()。它不仅初始化硬盘,也初始化网络,因为你安装nfs文件系统的时候需要网络。块设备包括基于IDE和SCSI设备。
/char 这里可以查看基于字符的设备比如tty,串行口等。
/cdrom Linux所有的CDROM代码。在这里可以找到特殊的CDROM设备(比如Soundblaster CDROM)。注意ide CD驱动程序是drivers/block中的ide-cd.c,而SCSI CD驱动程序在drivers/scsi/scsi.c中
/pci PCI伪驱动程序。这是一个观察PCI子系统如何被映射和初始化的好地方。Alpha AXP PCI整理代码也值得在arch/alpha/kernel/bios32.c中查看
/scsi 在这里不但可以找到所有的Linux支持的scsi设备的驱动程序,也可以找到所有的SCSI代码
/net 在这里可以找到网络设备驱动程序比如DEC Chip 21040 PCI以太网驱动程序在tulip.c中
/sound 所有的声卡驱动程序的位置
File Systems(文件系统)
EXT2文件系统的源程序都在fs/ext2/子目录,数据结构的定义在include/linux/ext2_fs.h,ext2_fs_i.h和ext2_fs_sb.h中。虚拟文件系统的数据结构在include/linux/fs.h中描述,代码是fs/*。Buffer cache和update 核心守护进程都是用fs/buffer.c实现的
Network(网络)
网络代码放在net子目录,大部分的include文件在include/net。BSD socket代码在net/socket.c,Ipv4 INET socket 代码在net/ipv4/af_inet.c中。通用协议的支持代码(包括sk_buff处理例程)在net/core中,TCP/IP网络代码在net/ipv4。网络设备驱动程序在drivers/net
Modules(模块)
核心模块代码部分在核心,部分在modules包中。核心代码全部在kernel/modules.c,数据结果和核心守护进程kerneld的消息则分别在include/linux/module.h和include/linux/kerneld.h中。你可能也希望在include/linux/elf.h中查看一个ELF目标文件的结构。  
|