为了能够覆盖到刚才说到那些知识点
我们设计了一共8个实验
可以看到从OS启动开始 OS怎么启动的
为此能够跟外设打交道
从一开始200行代码形成小code
到最后Lab8文件系统 大约一共加起来
整个过程大概形成了大约一万行代码
那么整个这些实验内容基本上覆盖了
我们上操作系统原理重要一些基本概念
整个过程我给大家做个介绍 大家知道这个砖头
怎么一步一步搭成最后一个建筑的
一开始我们看到我们这里有一个硬件层
这个硬件层其实是模拟了整个X86大致的架构
包含各种各样的外设
以及我们最主要的CPU内存
这是我们硬件环境
为了能够让我们超系统能够管理这些硬件
我们首先设计一个Bootloader
能够说它的目标干什么 它的目标就是加载OS
我们用Bootloader加载OS
让OS在我们类型中运行 这是第一步
然后OS要运行之后它首先知道
它所处的环境是什么 它需要去管理CPU
第二管理内存 第三管理外设
比如说时钟 键盘 串口 并口等等
只有把这些都能够有效管理起来之后
才能够控制这个硬件
这是我们说前面几个实验
首先从Lab1我们说Bootloader中断处理
Lab2物理内存管理 Lab3虚拟内存管理
都是跟内存打交道 那么Lab4和Lab5
都是说内核线程和用户进程
那跟谁打交道跟CPU打交道
然后Lab6实际上我们说是一个调度
它也是为了能更有效的利用CPU
Lab7是完成同步互斥 这里面Lab7在这块
有了Lab7同步互斥机制之后 我们就可以实现什么
实现解决一些问题 可以实现进程之间的通讯
就是我们运行程序之间可以有效进行通讯
很多可以用来协调的一些工作都可以用这个
有了同步互斥之后就可以完成了
那么在进程和内存管理之上
我们就可以给我们应用程序提供相应的支持
那我们应用程序可以跑起来
来可以完成它们特定的功能
有了进程管理 内存管理
我们就可以有用户态的各种各样的应用
如果说你这些应用的数据
或者你这个代码需要放在永久存储设备上面
比如说硬盘或者磁盘那需要什么呢
需要我们文件系统来完成相应的
把内存中的数据存到我们这个硬盘上的功能
它可以用很简单方式提供很简单的接口来使用
那么最后也许还有同学说可以做扩展
比如你可以完成网络协议栈等等
这都是形成了我们这个完整OS
可以看出来其实包含了三部分
前面说一部分是硬件
第二部分是运行在内核态的kernel
我们说OS kernel软件
然后有了这个OS kernel之后
我们可以设计各种各样的应用
来使用我们内核提供各种各样的服务
那我们重点实现的部分
在内核态这些各个大的模块
涉及到我们提到的八个实验
就是基本上覆盖了这么多内容
简单我们会把这个八个实验做一个逐一的介绍
从Lab1开始 Lab1讲的是Bootloader
中断还有设备驱动 这三部分内容
那这三部分内容实际上就是说
首先你要理解操作系统怎么启起来的
其实它通过Bootloader启起来的
同时当操作系统启起来之后 它怎么管理硬件
它需要通过中断机制
还有通过设备驱动程序来完成对硬件的管理
比如各种各样的外设的管理
这是说我们在Lab1的时候会去碰到
需要大家掌握和理解的知识
也需要大家通过对这些知识的了解
来进一步去完成对一些操作系统
运行时候机制的掌握 比如说堆栈处理
比如说它怎么去控制一些外设的
当然具体的外设的控制
我们这里面可以不用看那么细
可以看的简单一点
只要知道它大致的过程就行了
不用去了解它那些细节
这个我们可以不用去掌握
主要知道它大致处理过程
特别是它怎么去建立好这个中断机制
这点很重要 有了中断之后
我们就可以完成后续很多很重要功能
这个代码其实可以看到 最开始那个代码
比如我们加载一个OS最简单代码
其实只有很小一些代码量 可能不到一千
几百行代码就可以完成打印一个字符串OS
当然它没什么功能 但是它确实就可以看到
我们 bootloader怎么把OS加载起来了
当OS被bootloader加载到内存中运行之后
那OS很重要一个目标
肯定不是仅仅是打印一个字符串
它需要更好去管理整个计算机系统
那第一步管理是什么呢
管理我们内存 物理内存管理
我们知道一个计算机系统
它有大片的物理内存
这个物理内存哪些可以用 哪些不能用
实际上是由我们操作系统管理起来的
首先我们需要去了解 既然我们说
我们这个针对硬件是X86 32位的CPU
那我们就需要理解X86架构下面
它内存管理的模式 它有分段分页机制
我们知道通过理解内存地址的表示来
完成基于分段和分页的方式
能够实现页表 实现对连续物理空间的管理
这实际上是我们Lab2重点考虑内容
我们可以看到在X86架构下
整个内存一个分布图
很重要的一点就是操作系代码段 数据段
ucore代码段 数据段放在什么地方
以及它管理空闲空间在什么地方
这些地方都会被我们ucore操作系统管理起来
来实现一个对内存动态分配和释放这么一个机制
这是我们Lab2里要掌握的几点
对Lab3而言我们还需要知道
在有限物理空间里面 怎么实现一种更大
超过有限物理空间的一个虚拟内存空间
映射和管理机制 就是虚存管理
这是Lab3的功能 那么在Lab3里面
它需要借助我们前面之前讲到中断机制
就是缺页故障处理
还有借助于我们原理课讲到页面置换算法
这两个结合在一起来实现给我们应用程序
提供一个大的虚拟空间 即使我们物理空间很小
比如说只有1M 但是我们虚拟空间
给它虚拟出来一个4M 8M等等
从而可以使得 我们应用程序
可以更好在我们操作系统管理之下去运行
这是我们Lab3需要去掌握的知识
这里面需要了解什么呢
需要知道换页这个机制
就是我们把这个页换出去
比如说这里边一个程序
它怎么能够从内存换到我们硬盘
以及从硬盘再换回到内存里面去
这个机制怎么实现的
这实际上需要我们软硬件协同在一起来完成
并不是说只是靠操作系统来完成
需要我们的CPU和我们外设
有一定支持才能完成
第二我们需要了解页面调换算法
以及对应页出错的之后异常处理机制
这个实际上是我们操作系统来完成的
当产生这个缺页之后我们应该怎么做
第二个就是选择哪页换出去和换入
这个也是一样 就是我们操作系统来管理
有相应的算法 这一套实际上实现了
我们整个Lab3大致的一个内容
就是关于虚拟内存管理这块
Lab2和Lab3实现了什么
实现了我们对内存的一个管理
无论是虚拟还是物理的
操作系统一个很重要部分
就算基本上告一段落
接下来是对什么管理呢 是对CPU的管理
CPU的管理实际上什么呢
我们需要让不同的程序来分时占用CPU去执行
这实际上是我们线程管理
和进程管理很重要一个思路
为了实现线程管理
我们首先是在内核里面实现一个线程管理
这个实验相对来说比我们后面讲到
在Lab5中的用户态进程管理要简单一些
但是它他基本的一些机制是类似的
我们通过在内核实现线程管理
可以使得我们利用CPU来高效完成各种工作
你要创建它 你必须要干什么呢
需要建立关于线程的内部一些关键数据的描述
你可以看到在这里面它有堆有栈
有它的代码有它的数据
那怎么去表示它
这需要我们在内核线程中有相应一些关键信息
第二个如果CPU只有一个
这个时候每某一个时刻有一个线程运行
下一时刻可能是另一个线程运行了
你怎么完成切换 这也是需要去理解的
你需要有效地管理它 完成切换
这点是我们在内核线程管理上
重点去考虑的问题
当你能够完成这个切换之后
那其实应该说关于大家不同的进程
或者线程来分时占用CPU基本机制
就已经建立好了 那接下来问题是什么呢
我们说我们需要应用程序
也能够完成各自特定功能
而这些应用程序呢
由于它的可靠性不够高 也可能出错
我们希望把应用程序放在用户态
它出错了没关系 不影响内核
不影响我们处于内核态的这个操作系统
为了能够让应用程序运行在用户态
我们需要设计一个所谓用户进程
我们怎么能够让应用程序运用在用户态
为此我们需要创建所谓的用户进程
这里面设计到进程的创建 执行切换
等等一系列动态管理过程
这个过程我们Lab4是很相近
但是又有不同 为什么呢
这里面其实可以体现出来你需要了解
建立一个用户级的进程
它需要的一些关键信息
这些信息运行在这个空间
而不是在内核空间
那么运行在所谓用户空间的话
很明显它不能够破坏我们用户空间
怎么能保证这种机制
我们实际上去分析进程和内存这种关系
才能知道它们有一定区别 这是一个
第二个你还要知道运行在用户空间应用程序
无法直接访问我们操作系统内核里面的函数
它不得不通过另外一种机制
我们称之为系统调用
才能够得到操作系统提供的服务
这点大家也需要通过Lab5中
来实现系统调用才能知道这回事
这也是我们操作系统
在Lab5中需要去完成一些工作
你可以看到系统调用和我们中断相关
我们进程创建和我们内存管理相关
它的调度和我们Lab4的线程切换相关
就是你要切换到另一个线程上去执行
其实你看到Lab5其实建立在
我们前面的Lab1到Lab4基础之上才有Lab5
那么有Lab5之后
我们最终基本就可以完成一个很简单的OS
它有能够支持用户空间进程来运行
它建立一个基本的功能
它有了内存管理 CPU管理
接下来我们看Lab6
那既然说我可以让不同的进程
或者线程来分时占用CPU执行
到底那个时刻需要那个进程占用CPU执行
这点其实是有一个策略在里面的
这实际就涉及到什么呢 进程调度
我们需要去了解操作系统调度过程
基于哪些原则来选择哪一个进程去运行
这点你会涉及到怎么去设计一个调度器的框架
怎么实现不同调度算法 这里面的调度算法
和我们在原理课讲的调度算法也是一一对应的
但是你会发现 原理上讲的一些知识
如果真的在实际机器里面去实现
比如我们在一个ucore里实现
跑在X86这个机器里面的话
你会发现可能还有点偏差
为什么 这也是希望大家通过做实验
能够知道实践和理论之间其实还是有偏差的
并不是完全对应的
这也希望大家做实验的时候
能够深刻的体会到这点
那Lab7是同步互斥 既然我们现在
已经可以在计算机系统里面
在操作系统管理之下可以同时跑多个进程
但是其实这些进程之间它们也是需要去沟通的
并不是完全隔离 相互之间没有任何打交道
它们还是需要去说交换一个信息
相互之间有一个谁先谁后执行
这么一个相互关系 这里面就涉及到
所谓同步互斥一些技术 我们需要知道
我们操作系统要建立哪些机制
来支持进程间的同步互斥
为此我们需要了解比如说
我们后面说到spinlock 就是锁机制
semphpore信号量机制 还有condition variable
就是调节变量机制 它是怎么实现的
那么这些实现应该说
和我们操作系统原理课也是一一对应的
但是比原理课要更加贴近实际
它和我们硬件是紧密相关的
第二个假设有了这些实验之后
我们怎么能够用这些同步机制
来解决所谓同步问题 比如说我们原理课里面
经常讲哲学家问题 哲学家吃饭
在有限的资源情况下
怎么确保更多哲学家能够吃上饭
而不被饿死 这些基本问题
其实当你在我们ucore里面实现这些机制
就可以用完全原理和算法来实现
这也是我们说在Lab7里面
需要大家去体会的一些问题
如果说你实现不对 有可能出现死锁
有可能出现其它异常情况
这就避免了一些问题
通过实验相信对同步有更深入的理解
最后一个实验文件系统
为什么要有文件系统 很明显
有了文件系统之后 我们写的代码
可以永久存在一个地方
我不用每次要敲代码进去
我只要重新放在一个永久存储介质
比如我们硬盘上面的一个代码
加载到内存中去执行就可以了
我们不需要说每次要重新敲代码
所以这个永久存储这个介质有效管理和方便管理
实际上我们说是操作系统
很重要一个功能文件系统来完成的
它可以把我们内存中的数据
按照某种简单的方式
我们从文件系统转换到磁盘上去
本身对磁盘的处理实际上挺复杂的
有了这个文件系统之后
应用程序只需要通过一些简单的原语
比如说打开文件 读文件 写文件 关闭文件
这些基本的简单的原语
就可以完成对数据的存储
甚至包括我们执行代码存储也是一样的
最后你就发现 连我们操作系统本身
也是一个文件形式存在我们硬盘上面的
整个文件系统完成之后
你就可以理解它和我们内存有什么关系
和我们进程有有什么关系
和我们外设有什么关系
在文件系统里面都会有涉及
那我们最后还可以考虑一下
这个文件系统不同组织方式以及抽样方式
怎么样来支持不同的存储介质
不同的设计机制
所以说还有一些什么呢
文件系统抽象层设计等等
这些都是一个相对来说比较实际的
文件系统需要考虑的问题
有了硬件系统之后 我们最后就可以
完成一个用户可以操作的小型的OS了
相对来说功能比较完备了 有内存管理
有进程管理 有同步互斥 有文件系统
有了这些应该说我们可以在这个基础之上
开发一些简单的小的应用程序是没有问题的
就类似于大家写算法 上算法课上数据结构课一样
你开发简单小应用程序
就可以在ucore里面跑起来了
当然也许有些同学说
这个实验还是比较简单 不具有挑战
我们的同学也去做了很多具有挑战性的实验
下面列出了一些例子 大家可以看到
比如说能够把ucore跑在64位CPU上面
我们同学已经完成了 把ucore跑在X86 64位上面
能不能说设计一些不同的页替换算法
并不仅仅简单我们在实验课中提到
页替换算法
还更复杂一些 比如说像Linux一些页替换算法能不能实现
也有同学去做尝试 还有支持其它CPU
不光是X86 CPU 我们可以支持
现在在手机平板用的很广泛armCPU
这个有同学做过尝试
还有支持新的文件系统
我们前面讲到是这种最简单一种实验文件系统
相对来说比较实际一些文件系统
比如说FAT文件系统等等
那么这些文件系统也有同学做过尝试
能够去实现让ucore支持FAT格式的系统
最后甚至还有同学去尝试
让操作系统支持不同的语言
我们都知道像ucore基于C语言来开发的
那么我们能不能在ucore之上跑一些
基于其它语言的一些应用程序
有同学尝试了GO语言
这是谷歌开发的一种新的编程语言
也取得了一定成功
我觉得这是很好的扩展
那也有更多一些扩展 这里面没有一一列出
其实操作系统这个领域
有很多事情值得大家去探索和摸索的
从中可以掌握更多一些功能和知识
最后大家想了解一点是说
你做了这么多实验 你到底有什么样的收获
这个收获其实有好有坏
我们这边把同学一些反馈给大家列出来
可以看到 第一个理论和实践能够很好结合
这样不会在感到OS课本
只是需要一个死记硬背的课
以前如果说不做实验的话
基本上把概念死记下来就行了
至于这个概念到底是怎么实现的 不用去关心
上这门课你们需要了解这个实验
和理论怎么去对应 这是一个很重要点
第二点你在一个全局观 我们说上OS课里面
原理课里面很多讲的是一些
概念相对分散独立的概念
那么你通过做实验
你需要把这些概念揉合在一起形成
一个完整可以工作的OS
这也是通过实验能得到
第三个很多概念和原理做了大量的抽象
对于很多细节
没有再进一步展开讲解
那么通过做实验能够把这些细节知道更清楚
特别是跟硬件结合 这实际上说
在某种程度上可以说是计算机原理课
和操作系统课一个综合
能够知道在OS里面怎么控制一个硬件
同时也有同学提出来
这确实是大学期间碰到最复杂软件设计
那么学到了分析和设计大型系统软件的方法
也许大家将来不会开发OS
但是你这种方法的掌握
便于你后续去做跟计算机软件系统
相关的一些事情打下很好的基础
大家可以看到
其实完成操作系统实验可以有很大的收获
所以说这些实验之确实值得你去做深入的尝试