Linux-0.11 源码解析与思考题

拟题 杨力祥老师
初稿 李效宇同学
整理&终稿 李辰剑 2022-12-31

写在前面

写作背景

这篇笔记来源于这学期的操作系统课程。课程上,杨老师带同学们一起手撕早期版本的 Linux 源代码,非常刺激。

杨老师在期末前出了很多思考题,供同学们参考、复习。李效宇同学则花了不少功夫,结合上课内容和网上资料,整理了所有思考题的答案,分享给同学。

李效宇同学的原文链接:https://lixiexie.notion.site/dbfc366cee8f4931bfa33d414b1132f9

我看到了这篇长文之后觉得内容很棒,便决定转载到自己的博客上。于是我对内容进行了全面的修订,最终得到了这篇文章。

修订内容

本以为只是修改一些错别字和优化排版,没有想到最后却成为了大工程,花费了我小半个学期。对文本的修订和优化包括:

  • 修订了一些错别字、并对文字进行了润色,让文字更书面化。
  • 对代码使用了程序环境进行排版,优化了总体排版。
  • 修改了一些错误答案,例如“25. 为什么 static inline _syscall0(type,name) 中需要加上关键字 inline?”——实际原因不是优化性能,而是与写时复制 (CoW, Copy on Write) 机制有关。
  • 重写/扩充了一些问题的答案。
  • 对思考题顺序进行了调整,让问题之间的逻辑更紧密连贯。想按寻找某道特定思考题答案的同学,可以参考文末附录:「思考题调整前后编号对照表」。
  • 将许多图片替换为了高清版本,增加了一些示意图。
  • 添加了参考文献。

阅读指南

文中有许多内容是对 Linux-0.11 源代码的解析,还有一部分是对 Intel IA-32 体系结构的分析。对于没有阅读过 Linux 源代码的读者来说可能有些难懂。我建议读者的阅读方法有如下几种:

  1. 对计算机感兴趣但不熟悉 Linux 源码也不愿意花费太多时间的读者,可以不求甚解地阅读。文中有一些 IA-32 体系结构相关的内容,也许能拓宽你的知识面,帮助你理解计算机体系结构。文中有一些关于 Linux 操作系统设计思路的内容,也许能向你展现操作系统的具体实现,帮你把抽象的操作系统概念落到具体的实现上。
  2. 了解 Linux 源码,或者准备认真研读的读者,可以配合文末给出的参考资料(即参考文献)阅读。赵炯博士的《Linux内核完全注释》是一本功力极为深厚的 Linux 源码解析专著,我强力推荐。杨力祥老师的《Linux内核设计的艺术》则与文中的思考题思路最为契合。最后,解析 Linux 源码最少不了的便是 Linux 源码本身和 Intel IA-32 芯片手册——后者是当时乃至当今绝大多数操作系统的体系结构基础。源码和《完全注释》可以在 www.oldlinux.org 获得,其余资料也大都可以从网上获得。如果你想偷懒,也可以向我发邮件要资料。我的邮箱是 icy_chlorine@pku.edu.cn。
  3. 对于正在上/上过杨老师操作系统课的同学,你阅读整篇文章应该没有太大的障碍。根据杨老师上课的思路或者《Linux内核设计的艺术》书中的思路走即可。

记号约定:

  • 寄存器用带百分号的代码环境表示,如 %eip, %eax

  • 函数、变量、标识符、内存地址用程序环境排版,如 main(), dir, 0x7c00

  • 体系结构中的专有概念(如全局描述符表 GDT、基本输入输出系统 BIOS)用一般环境排版。
  • Linus 时代多使用 8 空格长的 tab 缩进,而如今的编辑器大都默认使用 4 个空格缩进,并将 tab 页渲染为四个空格长的空白。为了让代码和注释能正常对齐,将代码中的缩进全部替换为了与当时等长的空格。
  • 引用代码中,用 C++ style 注释(//...)表示我们添加的注解,以和 Linux 源代码中的 C style 注释(/*...*/)区分。

Part I 启动与 Intel IA-32 体系结构

1. 为什么开始启动计算机的时候,执行的是 BIOS 代码而不是操作系统自身的代码?

计算机只能从内存中运行程序,而无法直接从软盘或者硬盘中运行程序。不幸的是,计算机刚启动的时候,内存中空空如也、没有任何程序,需要将程序本身先加载进内存当中。这部分操作就由 BIOS(Basic Input/Output System) 完成。加电后, BIOS 完成一些硬件检测工作,设置实模式下的中断向量表和服务程序,并将操作系统的引导扇区加载至内存地址 0x7C00 处,然后将跳转至 0x7C00 运行操作系统的代码。

“实模式”是对 Intel x86 体系结构而言的

BIOS 程序存放在只读存储器 ROM(Read Only Memory) 中。ROM 断电后也能保持信息,但不能改变数据(或修改数据很困难),适合存放 BIOS 这种不需要修改的例行工作。通过内存映射,可以让处理器在上电后最先执行 ROM 中的程序,所以计算机启动最开始运行的是 BIOS 代码。BIOS 在计算机上电启动和操作系统代码之间增加了一层 indirection,使得同样的硬件上可以运行不同的操作系统。

阅读更多