在开始愉快的PA之旅之前

PA的目的是要实现NEMU, 一款经过简化的x86全系统模拟器. 但什么是模拟器呢?

你小时候应该玩过红白机, 超级玛丽, 坦克大战, 魂斗罗... 它们的画面是否让你记忆犹新? (希望我们之间没有代沟...) 随着时代的发展, 你已经很难在市场上看到红白机的身影了. 当你正在为此感到苦恼的时候, 模拟器的横空出世唤醒了你心中尘封已久的童年回忆. 红白机模拟器可以为你模拟出红白机的所有功能, 有了它, 你就好像有了一个真正的红白机, 可以玩你最喜欢的红白机游戏(这里是jyy移植的一个小型项目LiteNES, 但由于debian虚拟机中缺少GUI, 因此要运行LiteNES是一件比较困难的事情). 你可以在如今这个红白机难以寻觅的时代, 再次回味你儿时的快乐时光, 这实在是太神奇了!

你被计算机强大的能力征服了, 你不禁思考, 这到底是怎么做到的? 你学习完程序设计基础课程, 但仍然找不到你想要的答案. 但你可以肯定的是, 红白机模拟器只是一个普通的程序, 因为你还是需要像运行Hello World程序那样运行它. 但同时你又觉得, 红白机模拟器又不像一个普通的程序, 它究竟是怎么模拟出一个红白机的世界, 让红白机游戏在这个世界中运行的呢?

事实上, NEMU就是在做类似的事情! 它模拟了一个x86的世界(准确地说, 是x86的一个子集), 你可以在这个x86世界中执行程序. 换句话说, 你将要编写一个用来执行其它程序的程序! 为了更好地理解NEMU的功能, 下面将

  • 在GNU/Linux中运行Hello World程序
  • 在GNU/Linux中通过红白机模拟器玩超级玛丽
  • 在GNU/Linux中通过NEMU运行Hello World程序

这三种情况进行比较.

+--------------------------------+
|      "Hello World" program     |
+--------------------------------+
|            GNU/Linux           |
+--------------------------------+
|       Computer hardware        |
+--------------------------------+

上图展示了"在GNU/Linux中运行Hello World程序"的情况. GNU/Linux操作系统直接运行在计算机硬件上, 对计算机底层硬件进行了抽象, 同时向上层的用户程序提供接口和服务. Hello World程序输出信息的时候, 需要用到操作系统提供的接口, 因此Hello World程序并不是直接运行在计算机硬件上, 而是运行在操作系统(在这里是GNU/Linux)上.

+--------------------------------+
|          Super Mario           |
+--------------------------------+
|     Simulated NES hardware     |
+--------------------------------+
|          NES Emulator          |
+--------------------------------+
|            GNU/Linux           |
+--------------------------------+
|       Computer hardware        |
+--------------------------------+

上图展示了"在GNU/Linux中通过红白机模拟器玩超级玛丽"的情况. 在GNU/Linux看来, 运行在其上的红白机模拟器NES Emulator和上面提到的Hello World程序一样, 都只不过是一个用户程序而已. 神奇的是, 红白机模拟器的功能是负责模拟出一套完整的红白机硬件, 让超级玛丽可以在其上运行. 事实上, 对于超级玛丽来说, 它并不能区分自己是运行在真实的红白机硬件之上, 还是运行在模拟出来的红白机硬件之上, 这正是"虚拟化"的魔术.

+--------------------------------+
|      "Hello World" program     |
+--------------------------------+
|     Micro operating system     |
+--------------------------------+
|     Simulated x86 hardware     |
+--------------------------------+
|             NEMU               |
+--------------------------------+
|           GNU/Linux            |
+--------------------------------+
|       Computer hardware        |
+--------------------------------+

上图展示了"在GNU/Linux中通过NEMU执行Hello World程序"的情况. 在GNU/Linux看来, 运行在其上的NEMU和上面提到的Hello World程序一样, 都只不过是一个用户程序而已. 但NEMU的功能是负责模拟出一套x86硬件, 让程序可以在其上运行. 不过, 我们还需要先在模拟出的x86硬件之上运行一个微型操作系统, 之后才让Hello World程序在这个微型操作系统上面运行. 为了方便叙述, 我们将在NEMU中运行的程序称为"用户程序".

初识虚拟化

假设你在Windows中使用Virtualbox安装了一个GNU/Linux虚拟机, 然后在虚拟机中完成PA, 通过NEMU运行Hello World程序. 在这样的情况下, 尝试画出相应的层次图.

要虚拟出一个计算机系统并没有你想象中的那么困难. 我们可以把计算机看成由若干个硬件部件组成, 这些部件之间相互协助, 完成"运行程序"这件事情. 在NEMU中, 每一个硬件部件都由一个C语言的数据对象来模拟, 例如变量, 数组, 结构体等; 而对这些部件的操作则通过对相应数据对象的操作来模拟. 例如NEMU中使用结构体来模拟通用寄存器, 那么对这个结构体进行读写则相当于对通用寄存器进行读写.

这些数据对象之间相互协助的威力会让你感到吃惊! NEMU不仅仅能运行Hello World这样的小程序, 在PA的最后, 你将会在NEMU中运行仙剑奇侠传(很酷! %>_<%). 完成PA之后, 你在程序设计课上对程序的认识会被彻底颠覆, 你会觉得红白机模拟器不再是一件神奇的玩意儿, 甚至你会发现编写一个属于自己的红白机模拟器不再是遥不可及!

让我们来开始这段激动人心的旅程吧! 但请不要忘记:

  • 机器永远是对的
  • 未测试代码永远是错的
  • RTFM

results matching ""

    No results matching ""