Menu Close

Linux内核源代码,Linux内核源代码结构,如何阅读Linux Kernel 源代码, Linux 内核源代码分析工具

为了深入地了解 Linux 的实现机制,还必须阅读 Linux 的内核源代码,下面是对有关源代码的介绍。

1 多版本的内核源代码

对不同的内核版本,系统调用一般是相同的。新版本也许可以增加一个新的系统调用,但旧的系统调用将依然不变,这对于保持向后兼容是非常必要的—一个新的内核版本不能打破常规的过程。在大多数情况下,设备文件将仍然相同,而另一方面,版本之间的内部接口有所变化。

Linux 内核源代码有一个简单的数字系统,任何偶数内核(如 2.0.30)是一个稳定的版本,而奇数内核(如 2.1.42)是正在发展中的内核。本书是基于稳定的 2.4.16 源代码的。发展中的内核总是有最新的特点,支持最新的设备,尽管它们还不稳定,也许不是你所想要的,但它们是发展最新而又稳定的内核的基础。

对内核源代码的修改是以补丁文件的形式发布的。patch 实用程序用来对内核源文件进行一系列的修订,例如,如果你有 2.4.9 内核源代码,而想移到 2.4.16,你可以获得 2.4.16的补丁文件,应用 patch 来修订 2.4.9 源文件。例如:


$ cd /usr/src/linux
$ patch -p1 < patch-2.4.16

2 Linux 内核源代码的结构

Linux 内核源代码位于/usr/src/linux 目录下,其结构分布如下图 所示,每一个目录或子目录可以看作一个模块,其目录之间的连线表示“子目录或子模块”的关系。

下面是对每一个目录的简单描述:

  • include/ 目录包含了建立内核代码时所需的大部分包含文件,这个模块利用其他模块重建内核。
  • init/ 子目录包含了内核的初始化代码,这是内核开始工作的起点。
  • arch/子目录包含了所有硬件结构特定的内核代码,如上图所示,arch/子目录下有 i386和 alpha 模块等。
  • drivers/ 目录包含了内核中所有的设备驱动程序,如块设备,scsi 设备驱动程序等。
  • fs/ 目录包含了所有文件系统的代码,如:ext2,vfat 模块的代码等。
  • net/ 目录包含了内核的连网代码。
  • mm/ 目录包含了所有的内存管理代码。
  • ipc/ 目录包含了进程间通信的代码。
  • kernel/ 目录包含了主内核代码。

上图显示了 8 个目录,即 init、kernel、mm、ipc、drivers、fs、arch 及 net 的包含文件都在“include/”目录下。

在 Linux 内核中包含了 drivers、fs、arch 及 net 模块,这就使得 Linux 内核既不是一个层次式结构,也不是一个微内核结构,而是一个“整体式”结构。

因为系统调用可以直接调用内核层,因此,该结构使得整个系统具有较高的性能,其缺点是内核修改起来比较困难,除非遵循严格的规则和编码标准。

上图所示的模块结构,代表了一种工作分配单元。利用这种结构,我们期望 Linus Torvalds能维护和增强内核的核心服务,即 init/、kernel/、mm/及 ipc/,其他的模块 drivers、fs、arch 及 net 也可以作为工作单元,例如,可以分配一组人对块文件系统进行维护和进一步地开发,而另一组人对 scsi 文件系统进行完善。

上图所示类似于 Linux 的自愿者开发队伍一起工作来增强和扩展整个系统的框架。

如何阅读Linux Kernel 源代码

像 Linux 内核这样庞大而复杂的程序看起来确实让人望而生畏,它像一个很大的球,没有起点和终点。在读源代码的过程中,你会遇到这样的情况,当读到内核的某一部分时又会涉及到其他更多的文件,当返回到原来的地方想继续往下读时,又忘了原来读的内容。在Internet 上,很多人为此付出了很大的努力,制作出了源代码导航器,这为源代码阅读提供了很好的条件,下载站点为http://lxr.linux.no/source。

下面给出阅读源代码的一些线索。

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.内核
内核中,特定结构的代码在 arch/*/kernel,调度程序在 kernel/sched.c,fork 的代码在 kernel/fork.c,task_struct 数据结构在 include/linux/sched.h 中。

4.PCI
PCI 伪驱动程序在 drivers/pci/pci.c ,其定义在 include/linux/pci.h。每一种结构都有一些特定的 PCI BIOS 代码,Intel 的在 arch/alpha/kernel/bios32.c。

5.进程间通信
所 有 System V IPC 对 象 权 限 都 包 含 在 ipc_perm 数 据 结 构 中 , 这 可 以 在include/linux/ipc.h 中找到 System V 消息是在 ipc/msg.c 中实现, 共享内存在 ipc/shm.c中,信号量在 ipc/sem.c 中,管道在 ipc/pipe.c 中实现。

6.中断处理
内核的中断处理代码是几乎所有的微处理器所特有的。中断处理代码在arch/i386/kernel/irq.c 中,其定义在 include/asm-i386/irq.h 中。

7.设备驱动程序
Linux 内核源代码的很多行是设备驱动程序。Linux 设备驱动程序的所有源代码都保存在/driver,根据类型可进一步划分为:

/block
块设备驱动程序如 ide(在 ide.c)。如果想看包含文件系统的所有设备是如何被初始化的,应当看 drivers/block/genhd.c 中的 device_setup(),device_setup()不仅初始化了硬盘,当一个网络安装 nfs 文件系统时,它也初始化网络。块设备包含了基于 IDE 和 SCSI的设备。

/char
这是看字符设备(如 tty,串口及鼠标等)驱动程序的地方。

/cdrom
Linux 的所有 CDROM 代码都在这里,如在这儿可以找到 Soundblaster CDROM 的驱动程序。注意 ide CD 的驱动程序是 ide-cd.c,放在 drivers/block;SCSI CD 的驱动程序是 scsi.c,
放在 drivers/scsi。

/pci
这是 PCI 伪驱动程序的源代码,在这里可以看到 PCI 子系统是如何被映射和初始化的。

/scsi
在这里可以找到所有的 SCSI 代码及 Linux 所支持的 scsi 设备的所有设备驱动程序。

/net
在这里可以找到网络设备驱动程序,如 DECChip 21040 PCI 以太网驱动程序在 tulip.c中。

/sound
这是所有声卡驱动程序的所在地。

8.文件系统
EXT2 文 件 系 统 的 源 代 码 全 部 在 fs/ext2/ 目 录 下 , 而 其 数 据 结 构 的 定 义 在include/linux/ ext2_fs.h,ext2_fs_i.h 及 ext2_fs_sb.h 中。虚拟文件系统的数据结构在include/linux/fs.h 中描述,而代码是在 fs/*中。缓冲区高速缓存与更新内核的守护进程的实现是在 fs/buffer.c 中。

9.网络
网络代码保存在/net 中,大部分的 include 文件在 include/net 下,BSD 套节口代码在net/socket.c 中,IP 第 4 版本的套节口代码在 net/ipv4/af_inet.c。一般的协议支持代码(包括 sk_buff 处理例程)在 net/core 下,TCP/IP 联网代码在 net/ipv4 下,网络设备驱动程序在/drivers/net 下。

10.模块
内核模块的代码部分在内核中,部分在模块包中,前者全部在 kernel/modules.c 中,而 数 据 结 构 和 内 核 守 护 进 程 kerneld 的 信 息 分 别 在 include/linux/module.h 和include/linux/kerneld.h 中。如果想看 ELF 目标文件的结构,它位于 include/linux/elf.h中。

Linux 内核源代码分析工具

凡是尝试做过内核分析的人都知道,Linux 的内核组织结构虽然非常有条理,但是,它毕竟是众人合作的结果,在阅读代码的时候要将各个部分结合起来,确实是件非常困难的事情。因为在内核中的代码层次结构肯定分多个层次,那么对一个函数的分析,肯定会涉及到多个函数,而对每一个函数都可能有多层的调用,一层层下来,直接在代码文件中查找肯定会让你失去耐心和兴趣的。最后,很多人只能望洋兴叹,或者只是找一本书来看看基本原理,却不敢去说自己真正看过内核源代码。任何一本原理书只能是你阅读源代码的导航器,绝不能代替源代码的阅读。

俗话说:“工欲善其事,必先利其器”。面对 Linux 这样庞大的源代码,必须有相应工具的支持才能使分析有效地进行下去。在此介绍两种源代码的分析工具,希望能对感兴趣的读者有所帮助。

1 Linux 超文本交叉代码检索工具

Linux 超文本交叉代码检索工具 LXR(Linux Cross Reference),是由挪威奥斯陆大学数学系 Arne Georg Gleditsch 和 Per Kristian Gjermshus 编写的。这个工具实际上运行在Linux 或者 UNIX 平台下,通过对源代码中的所有符号建立索引,从而可以方便地检索任何一个符号,包括函数、外部变量、文件名、宏定义等。不仅仅是针对 Linux 源代码,对于 C 语言的其他大型的项目,都可以建立其 LXR 站点,以便开发者查询代码,以及后继开发者学习代码。

目前的 LXR 是专门为 Linux 下面的 Apache 服务器设计的,通过运行 perl 脚本,检索在安装时根据需要建立的源代码索引文件,将数据发送到网络客户端的 Web 浏览器上。任何一种平台上的 Web 浏览器都可以访问,这就方便了习惯在 Windows 平台下工作的用户。

LXR 的 英 文 网 站 为 http://lxr.linux.no/ , 在 中 国 Linux 论 坛http://www.linuxforum.net上有其镜像。

读者如果想建立自己的 LXR网站,则可直接通过 http://lxr.linux.no/lxr-0.3.tar.gz,下载 LXR 的 tarball 形式的安装包。另外,因为 LXR 使用 glimpse 作为整个项目中文本的搜
索工具,因此还需要下载 glimpse,位置在 http://glimpse.cs.arizona.edu ,下载glimpse-4.12.6.bin.Linux- 2.2.5-22-i686.tar.gz,也可以使用更新的版本下载以后按照
说明进行安装和配置,就可以建立自己的 LXR 网站。

如果你上网很方便,就可以直接从http://lxr.linux.no/网站查询所需要的各种源代码信息。

2 Windows 平台下的源代码阅读工具(Source Insight)

为了方便地学习 Linux 源程序,我们不妨回到我们熟悉的 Windows 环境下。但是在Windows 平台上,使用一些常见的集成开发环境,效果也不是很理想,比如难以将所有的文件加进去,查找速度缓慢,对于非 Windows 平台的函数不能彩色显示。在 Windows 平台下有一个强大的源代码编辑器,它的卓越性能使得学习 Linux 内核源代码的难度大大降低,这便是 Source Insight 3.0 , 它 是 一 个 Windows 平 台 下 的 共 享 软 件 , 可 以 从http://www.sourceinsight.com/上下载 30天试用版本。

由于 Source Insight是一个 Windows平台的应用软件,所以首先要通过相应手段把 Linux 系统上的程序源代码移到 Windows 平台下,这一点可以通过在 linux 平台上将/usr/src 目录下的文件拷贝到 Windows 平台的分区上,或者从网上或光盘中直接拷贝文件到 Windows 平台的分区上。

这个软件的安装非常简单,双击安装文件名,然后按提示进行即可。安装完成后,就可启动该程序。这个软件使用起来也非常简单:先选择 Project 菜单下的 new,新建一个工程,输入工程名,接着要求你把欲读的源代码加入(可以加入整个目录)后,该软件就分析你所加的源代码。分析完后,就可以进行阅读了。对于打开的阅读文件,如果想看某一变量的定义,先把光标定位于该变量,然后单击工具条上的相应选项,该变量的定义就显示出来。对于函数的定义与实现也可以同样操作。

 

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Leave the field below empty!

Posted in Linux内核, 家庭生活

Related Posts