您的位置:首页 > 运维架构 > Linux

Linux内核源代码简单分析(如何深入研究源代码)(转)

2011-10-19 08:23 253 查看
第11章Linux内核源代码

本章讲述在Linux内核源码中,应该从何处开始查找特定的内核函数。

本书并不要求读者具有C语言编程能力,也不要求读者有一份可参阅的Linux内核源码,

事实上,通过查看内核源码可以在一定深度上理解Linux操作系统,同时这也是一个很好的实

践机会。本章给出了对内核源码的概览:它们是如何编排的以及从何处开始查找特定代码。

11.1怎样得到Linux内核源码

所有主要的Linux系统(Craftworks、Debian、Slackware、RedHat等等)都包含有内核源码,

通常所安装的Linux系统都是通过这些源码创建的。由于Linux总是不断更新,因此用户所安

装的Linux可能已过时,不过从附录A所列的站点上可得到最新的源码,所有这些站点地址都

可在ftp://ftp.cs.helsinki.fi上查到。

Linux内核源码的版本号表示方法非常简单:所有偶数版(如2.0.30)都是已发行的稳定版;

所有奇数版(如2.1.42)都是测试版,本书是基于2.0.30版撰写的。测试版包含所有的新特征,

并支持所有的新设备,虽然测试版并不稳定,并且可能提供了一些用户不想要的东西,但对

于Linux与用户沟通而言,测试新的内核是很重要的。不过请注意,在尝试非产品型的测试版

之前,最好先完全备份系统。

对内核源码的修改是作为patch文件出现的,patch工具提供了一组对源码文件的编辑。例

如,若想把2.0.29源码升级为2.0.30版,则要使用patch文件来完成对源码的编辑,操作如下:

这样做可以避免对所有源码文件的拷贝。在http://www.linuxhq.com站点上可找到很好的

内核源码的patch。

11.2内核源码的编排

在源码目录树的最顶端(/usr/src/linux)可看到如下一些目录:

*archarch子目录包含所有的特定体系结构的内核源码,它的子目录分别对应着一种

Linux所支持的体系结构,例如i386和alpha。

*includeinclude子目录包含大部分的编译内核源码所需文件。

*init此目录下包含了内核的初始化代码,由此可以很好地开始了解内核是如何工作的。

*mm此目录下包含了所有内存管理代码,特定体系结构的内存管理代码在arch/*/mm目

录下。

*drivers此目录下包含了系统所有的设备驱动程序,其下子目录各针对不同的设备驱动

程序类。

*ipc此目录下包含了内核的内部进程通信代码。

*modules此目录只是用来保存创建的模块。

*fs所有文件系统代码,其下子目录各针对不同的系统所支持的文件系统。

*kernel内核主代码,特定体系结构内核代码保存在arch/*/kernel中。

*net内核的网络代码。

*lib此目录包含内核库代码,特定体系结构的库代码保存在arch/*/lib目录下。

*scripts此目录包含了内核设置时用到的脚本。

11.3从何处看起

像Linux这样复杂的大程序,探究起来使人迷茫,这就像一个找不出头绪的大线团。要查

看内核的某一部分通常会被引向许多其他的相关文件,最后甚至忘记了最初的动机。下面给

出了一些提示,根据这些提示,对于给定的内容即可找到最好的开始阅读代码部分。

1.系统启动和初始化

在基于Intel的系统中,通常先运行loadlin.exe或LILO,由这两个程序将内核载入内存并启

动内核,之后便由内核控制系统。在arch/i386/kernel/head.s中可找到这一部分,head.s先进行

一些特定体系结构的安装,然后跳转到init/main.c中的main()例程。

2.内存管理

有关内存管理的代码大部分都在mm中,但与特定体系结构相关的部分则保存在

arch/*/mm中,内存缺页处理代码在mm/memory.c中,内存映射和页缓冲代码在mm/filemap.c

中,实现缓冲区缓存部分代码在mm/buffer.c中,页交换代码在mm/swap_state.c和

mm/swapfile.c中。

3.内核

大部分通用内核代码在kernel中,与特定体系结构相关的代码在arch/*/kernel中,调度进

程代码在kernel/sched.c中,创建子进程代码在kernel/fork.c中,BottomHalf控制程序代码在

include/linux/interrupt.h中,task_struct数据结构的定义在include/linux/sched.h中。

4.PCI

PCI伪驱动程序在drivers/pci/pci.c中,系统全局定义在include/linux/pci.h中。每种体系结

构都有其特定的PCIBIOS代码,如AlphaAxp的代码在arch/alpha/kernel/bios32.c中。

5.内部进程间通信

所有相关代码都在ipc中,所有的SystemVIPC对象都有一个ipc_perm数据结构,在

include/linux/ipc.h中有该数据结构的定义。SystemV的消息机制代码在ipc/msg.c中,共享内

存代码在ipc/shm.c中,信号量代码在ipc/sem.c中,管道代码在ipc/pipe.c中。

6.中断处理

内核的中断处理代码几乎都与特定微处理器相关。Intel的中断处理代码在

arch/i386/kernel/irq.c中,并且定义在include/asm-i386/irq.h中。

7.设备驱动程序

大部分的Linux内核源码行在设备驱动程序中,所有设备驱动程序代码在drivers中,并分

为如下几类:

*/block块设备驱动程序(如ide.c)。若要了解其初始化过程,参看drivers/block/genhd.c中

的device_setup()函数,该函数不仅能初始化硬盘,也可以初始化网络。块设备包括IDE

和SCSI设备。

*/char字符设备驱动程序,例如ttys、串口和鼠标。

*/cdromLinux的所有CDROM代码。在此可找到特定的CDROM设备(如SoundblasterCD

ROM),请注意,ideCD驱动程序在drivers/block下的ide-cd.c中,而SCSICD驱动程序在

drivers/scsi中的scsi.c中。

*/pciPCI伪驱动程序代码,由此可了解PCI子系统是如何映射和初始化的,arch/alpha

/kernel/bios32.c中的AlphaPCI固化代码也值得一看。

*/scsi所有的SCSI代码,以及Linux所支持的所有scsi设备驱动程序代码。

*/net所有网络设备驱动程序代码。

*/sound所有声卡驱动程序代码。

8.文件系统

EXT2文件系统的代码都在fs/ext2/目录下,其数据结构定义在include/linux/ex2_fs.h、

ext2_fs_i.h和ext2_fs_sb.h中,虚文件系统(VirtualFileSystem)数据结构在include/linux/fs.h中,

代码在fs/*中,缓冲区缓存代码在fs/buffer.c中。

9.网络

网络部分代码在net中,其大部分的include文件在include/net中,BSD套接字代码在

net/socket.c中,IP版本4INET套接字代码在net/ipv4/af_inet.c中,常用的协议支持代码(包括

sk_buff控制例程)在net/core中,TCP/IP网络代码在net/ipv4中,而网络设备驱动程序在

drivers/net中。

10.模块

内核模块代码一部分在kernel中,另一部分在模块包中,内核代码都在kernel/mcdules.c中,

其数据结构和内核守护程序kerneld消息分别在include/linux/module.h和include/linux/kerneld.h

中,ELF对象文件的结构定义在include/linux/elf.h中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: