东京大学版一生一芯:自制CPU,成功运行类Unix系统( 二 )


3. 模拟器呢?
我们已经在 CPU 实验的核心任务部分做了一个模拟器 , 但那个模拟器很简单 , 只能逐一执行指令 , 而且没有中断和虚拟地址转换 。
4.Xv6 的可移植性差
Xv6 很难移植 。 举个例子 , 它假设 char 是 1 个字节 , 而 int 是 4 个字节 , 并会大量操作堆栈 。 好吧 , 我猜 Xv6 这个名字实际上来自 x86 和 Unix v6 , 所以这种设计当然很自然 。
我们有过很多担忧 , 但还是在 12 月份开始了 Group X 的 OS 移植项目 。
接下来 , 我将大致按时间顺序编写我们的工作经历 。 这个过程会有一点长 , 所以如果你想快些看到结果 , 请跳转至「三月」部分 。
十一月下旬:开始开发编译器
我们找到答案的第一个问题是编译器和工具链 。 有点意外的是 , 我们决定从头开始写 C89 编译器 。 说老实话 , 我之前没想到我们会选这条路 。 我记得我和 Yuichi(后来负责 Group X 的 CPU)一开始讨论过移植 gcc 或 llvm 。
但是 , 一位团队成员 Keiichi 突然说他已经写好了一个 C 编译器并向我们展示了一个编译器原型 , 其带有一个简单的解释器和发射器 。 从头开始写工具链似乎更有意思 , 因此我们决定自己写一个编译器 。
来自第 3 组的 Yuichi 和 Wataru 已经结束了那一年 CPU 实验的核心任务 , 于是他们加入了 Keiichi , 组成了 Group X 的编译器团队 。 后来我们将我们的编译器命名为 Ucc 。
十二月中旬:OS 团队上线!
十二月初 , 我完成了自己的 CPU , 第 6 组完成了 CPU 实验的核心部分 。 于是我们开始做有趣的部分:Group X 的 OS 移植任务 。 这时候 , 第 6 组的我和 Shohei 开始了 Group X 的工作并组成了 OS 团队 。 Masayoshi 也在那时候加入了进来 。
实验的核心任务:编写一个 CPU
顺便一提 , 我猜没多少软件工程师亲自写过 CPU , 所以我也谈谈如何写 CPU 。
【东京大学版一生一芯:自制CPU,成功运行类Unix系统】现如今 , 制作 CPU 并不意味着要在面包板上连接各种跳线 , 你可以完全使用硬件描述语言(HDL)编写电路 。 然后你可以使用 Vivado 或 Quartus 将 HDL 合成到真实电路中 。 这个过程叫做逻辑综合(logic synthesis) , 而不是编译 。
HDL 与编程语言既有相似之处 , 也有一些差异 。 你可以将其视为一个将寄存器的信号状态映射成另一个信号状态的函数 , 其可由时钟或输入信号触发 。 如果你想体验真正的反应式编程 , 我建议你试试 HDL 。 同时请务必记住 , 在写 HDL 时要一直注意你写的 HDL 的信号传播会在某个时钟切实地终止 。 否则 , 人类将难以理解你的电路的行为 。
实际开发过程中最艰难的部分就是逻辑综合 , 其所需的时间多得离谱 。 在开始执行综合之后 , 我们往往需要等上多达 30 分钟时间 。 所以开始综合之后 , 我常常与其他也在等着综合结束的 CPU 团队成员玩《任天堂明星大乱斗 DX》 。 随便说一下 , 我的角色是 Sheik 。
十二月下旬到一月中旬:通过将 Xv6 移植到 MIPS 来学习
我们开始找到「操作系统需要 CPU 具备哪些功能?」这个问题的答案 。
OS 团队诞生之后 , 我们开始每周聚会 , 阅读 Xv6 源代码 。
与此同时 , 我开始将 Xv6 移植到 MIPS 。 这样做的部分原因是学习 OS 在实现层的工作方式 , 部分原因是似乎还没人将 Xv6 移植到 MIPS 过 。 我在大约一周内完成了移植工作 , 直到调度器过程开始 。 在这个移植过程中 , 我花了大量精力研究 MIPS , 并且为了了解 Xv6 的工作方式还大量研究了 x86 。 得益于此 , 我理解了中断的相关机制以及实现层的内存管理单元(MMU) 。 这时候 , 对于 Xv6 所需的 CPU 功能 , 我已经有了扎实的理解 。
另外 , 在一月中旬 , 我们也开始努力通过注释掉各个部分来编译 Xv6 的整体代码 。 结果是在我们自制架构的模拟器上 , Xv6 在引导顺序中显示出了第一条消息: