了解 OS 实验

写一个操作系统难吗?别被现在上百万行的 Linux 和 Windows 操作系统吓倒。当年 Thompson 乘他老婆带着小孩度假留他一人在家时,写了 UNIX;当年 Linus 还是一个 21 岁大学生时完成了 Linux 雏形。站在这些巨人的肩膀上,我们能否也尝试一下做“巨人”的滋味呢?

MIT 的 Frans Kaashoek 等在 2006 年参考 PDP-11 上的 UNIX Version 6 写了一个可在 X86 上跑的操作系统 xv6(基于 MIT License),用于学生学习操作系统。我们可以站在他们的肩膀上,基于 xv6 的设计,尝试着一步一步完成一个从“空空如也”到“五脏俱全”的“麻雀”操作系统—ucore,此“麻雀”包含虚存管理、进程管理、处理器调度、同步互斥、进程间通信、文件系统等主要内核功能,总的内核代码量(C+asm)不会超过 5K 行。充分体现了“小而全”的指导思想。

ucore 的运行环境可以是真实的 X86 计算机,不过考虑到调试和开发的方便,我们可采用 X86 硬件模拟器,比如 QEMU、BOCHS、VirtualBox、VMware Player 等。ucore 的开发环境主要是 GCC 中的 gcc、gas、ld 和 MAKE 等工具,也可采用集成了这些工具的 IDE 开发环境 Eclipse-CDT 等。在分析源代码上,可以采用 Scitools 提供的 understand 软件(跨平台),windows 环境上的 source insight 软件,或者基于 emacs+ctags,vim+ctags 等,都可以比较方便在在一堆文件中查找变量、函数定义、调用/访问关系等。软件开发的版本管理可以采用 GIT、SVN 等。比较文件和目录的不同可发现不同实验中的差异性和进行文件合并操作,可使用 meld、kdiff3、UltraCompare 等软件。调试(deubg)实验有助于发现设计中的错误,可采用 gdb(配合 qemu)等调试工具软件。并可整个实验的运行环境和开发环境既可以在 Linux 或 Windows 中使用。推荐使用 Linux 环境。

那我们准备如何一步一步来实现 ucore 呢?根据一个操作系统的设计实现过程,我们可以有如下的实验步骤:

  1. 启动操作系统的 bootloader,用于了解操作系统启动前的状态和要做的准备工作,了解运行操作系统的硬件支持,操作系统如何加载到内存中,理解两类中断--“外设中断”,“陷阱中断”等;
  2. 物理内存管理子系统,用于理解 x86 分段/分页模式,了解操作系统如何管理物理内存;
  3. 虚拟内存管理子系统,通过页表机制和换入换出(swap)机制,以及中断-“故障中断”、缺页故障处理等,实现基于页的内存替换算法;
  4. 内核线程子系统,用于了解如何创建相对与用户进程更加简单的内核态线程,如果对内核线程进行动态管理等;
  5. 用户进程管理子系统,用于了解用户态进程创建、执行、切换和结束的动态管理过程,了解在用户态通过系统调用得到内核态的内核服务的过程;
  6. 处理器调度子系统,用于理解操作系统的调度过程和调度算法;
  7. 同步互斥与进程间通信子系统,了解进程间如何进行信息交换和共享,并了解同步互斥的具体实现以及对系统性能的影响,研究死锁产生的原因,以及如何避免死锁;
  8. 文件系统,了解文件系统的具体实现,与进程管理等的关系,了解缓存对操作系统 IO 访问的性能改进,了解虚拟文件系统(VFS)、buffer cache 和 disk driver 之间的关系。

其中每个开发步骤都是建立在上一个步骤之上的,就像搭积木,从一个一个小木块,最终搭出来一个小房子。在搭房子的过程中,完成从理解操作系统原理到实践操作系统设计与实现的探索过程。这个房子最终的建筑架构和建设进度如下图所示:

ucore系统结构图

图 1 ucore 系统结构图

如果完成上诉实验后还想做更大的挑战,那么可以参加 ucore 的研发项目,我们可以完成 ucore 的网络协议栈,增加图形系统,在 ARM 嵌入式系统上运行,支持虚拟化功能等。这些项目已经有同学参与,欢迎有兴趣的同学加入!

results matching ""

    No results matching ""