编译用户程序
别让简单问题复杂化.
第二章进行至此, 我们已经可以完整的构建整个 EOS, 并且同时生成可引导的软盘镜像了. 我们还为 Makefile 增加了一些便捷的新规则, 使得我们可以一键构建并启动 EOS.
不过, 我们目前的 OS lab 实验环境离“完全够用”还有一段距离. 在 EOS 的官方 IDE 中, 你不仅可以生成 EOS 内核本身, 还可以为 EOS 编写用户应用程序, 然后一同放入软盘镜像, 在启动 EOS 后执行. 所以我们至少还需要实现“编译用户应用程序”这一功能, 才能让我们的 OS lab 更加完善.
在这里, 教程作者想吐槽一下 EOS 官方的 IDE (虽然他基本没怎么用过这个软件): 如果你想写一个 EOS 用户应用程序, 你必须新建一个专门写用户程序的工程, 然后从内核工程中复制内核的 SDK, 再如此这般才能构建完成. 那假如你想同时修改你的用户应用程序和 EOS 内核, 你就必须在两个工程之间来回折腾, 场面一度异常混乱.
所以说, 不要让简单的问题复杂化, 接下来的教程将带你实现一个更为便利的构建用户程序的方法.
需要的文件
有了第二章的第一节的介绍, 你现在应该已经知道: 操作系统中用户应用程序的编译和执行, 依赖于编程语言为其提供的一系列基础设施, 以及运行时库. 好在我们无需自己手动实现, 直接从官方仓库获取即可.
将下载到的 crt 目录放入 eos/user 中:
eos
├── build
├── src
├── user
│ └── crt # C Runtime
├── util
├── vm
├── Makefile
└── License.txt除此之外, 用户应用程序还应当能调用 EOS 内核提供的 API, 我们在构建应用程序时需要确保 EOS 内核的 inc/eos.h, inc/eosdef.h 和 inc/error.h 能被编译器找到. 在编写 Makefile 时, 我们需要把上述三个文件拷贝到 eos/user/sdk 中去; 如果这个目录不存在, Makefile 应当自动创建.
构建规则示例
将 .asm 构建为 .o
.asm 构建为 .o和构建内核时相同, 例如将 __alloca.asm 构建为 __alloca.o:
此处选择不输出 .lst, 因为没必要.
将 .c 构建为 .o
.c 构建为 .o例如将 crt0.c 构建为 crt0.o:
其中 sdk 存放了三个 EOS 相关的头文件, crt/inc 存放了 C Runtime 的头文件.
将 .o 构建为 .exe
.o 构建为 .exe例如将 test.o 和所有的 Runtime 构建为 test.exe:
其中:
-e __start: C Runtime 中定义了入口函数_start, C 源程序编译到目标文件时函数符号之前会加一个下划线, 于是这里的入口点需要指定为__start;--major-subsystem-version 80: EOS 内核在创建用户进程之前必须加载 PE 文件, 加载 PE 文件时会检查子系统版本, 不是80则会报错, 详情请 RTFSC;-Leos/build: 指定链接器在此目录搜索链接库;-lkernel: 指定静态链接导入库libkernel.a. 一般所有的静态链接库都叫libXXX.a, 所以静态链接时告诉链接器中间的XXX就行, 不用写全.
额外的规则
为了方便大家往软盘镜像中放入其他各种类型的文件 (例如最后一个实验会要求大家向软盘中添加 .txt 用于测试磁盘写入), 我们可以在 eos/user 中新建一个 import 目录. 每当执行 make 时, 自动将目录内的所有文件放入镜像.
编写 Makefile
在 eos/user 中新建 Makefile, 同时新建目录 src 存放所有需要编译的用户应用程序; 新建 import 存放其他需要导入的文件:
Makefile 内容如下:
此时我们需要更新 eos/Makefile:
在 EOS 中运行 Hello World
到目前为止, 我们的 OS lab 基本上就搭建完成了. 现在我们可以来写一个 “Hello, world!” 来测试一下:
将这个文件保存到 eos/user/src/hello.c, 然后重新构建 EOS:
在虚拟机中我们输入 hello 后回车, 就可以看到 “Hello, world!” 已经出现在了控制台当中:

当然, EOS 中还有一些其他命令, 比如 pt 可以显示进程/线程列表:

奇怪的事情
好奇的小铭同学也想用自己刚搭建好的环境试试身手. 他首先输入了 hello, 但是一不小心输错打成了 helo, EOS 提示创建进程失败 (因为软盘镜像里根本没这个文件).
小铭没有理会这个问题, 他随后输入了 pt, 想看看系统里目前有什么进程. 结果敲下回车之后:

完了, 自己是不是把 EOS 给玩坏了? 小铭同学喜欢刨根问底, 他后来又重新启动虚拟机, 多试了几次, 发现: 只要用户尝试启动一个不存在的程序之后, 再次执行 pt 命令, EOS 就一定会蓝屏.
为什么说这是低级错误?
因为只要你尝试在 EOS 的控制台中输入几条指令, 你就有很大几率会触发这个 bug. 但是发生概率这么大的一件事, EOS 的开发者们却没有发现! (或者是发现了但是不去/无法修复?)
如果真的是开发者没有发现这个问题, 那就说明 EOS 在发布之前没有经过严谨的测试, 或者干脆就没测试. 在软件工程领域, 软件测试是一种有效且必要的质量保证手段, 科学合理的软件测试会给软件的质量带来飞跃般的提升.
说这么多是想告诉大家, 千万不要轻视软件测试. 别以为软件测试就是一群不懂开发的测试员, 打开软件随便在界面上点几下就完成了的事情. 现代的软件在开发的过程中往往就要进行大量的测试, 这些测试程序由软件开发者设计, 并且由专门的脚本自动执行. 在实际项目中, 很容易出现“测试程序比软件本体还要多”的情况. 甚至, 还有一种软件开发方法叫做测试驱动开发, 这种开发方法要求在实际编码之前先写出测试用例.
所以, 如果你目前还对软件测试知之甚少, 并且没有在实际的软件开发中应用过任何测试手段, 你现在可以开始着手学习了.
Last updated
Was this helpful?