学院的操作系统实验全都参照于渊的《自己动手写操作系统》。这本书虽然确实是好书,但却是 2005 年成书的,距离现在已经十几年了。其中使用的 bochs 虚拟机已经是时代的眼泪。更常见的是 gcc 工具链和 qemu。比如打开项目目录发现一堆神秘的 *.S *.ld……

第一章、第二章: as, ld, qemu

nasm --> as, ld
bochs --> qemu

nasm

nasm 又是 Intel 格式语法的汇编器。学院开的汇编语言也教的是 Intel。似乎过去 masm 非常流行?

但开源世界都是 AT&T。各种项目里一堆 *.S 显然不是给 nasm 编译的。所以到底应该用啥呢?

as!

书中提到了 gas 而不用。其实 gas 是 GNU Assembler,而 gas 这个名字也已经成为时代的眼泪,现在只有属于 binutils 包的 as。没想到吧,as 不是 gcc 软件包的。

除了 as, 我们实际上还需要 ld 来完全替代掉 nasm 的功能。ld 其实也是 binutils 包而非 gcc 的。这因为nasm 带的伪指令可以控制段的位置,而 as 不行,必须通过 ld 实现。

bochs

说实话这是我第一次听说这个虚拟机……

我选择 qemu!

动手

  1. 准备好工具链
  2. 阅读第一、二章
  3. 阅读 https://medium.com/@g33konaut/writing-an-x86-hello-world-boot-loader-with-assembly-3e4c5bdd96cf

更多内容可以阅读参考资料。我搜了一大圈才找到上面的帖子然后发现他覆盖的很全。但我觉得也有错误:全程都应该使用 -Ttext 0x7c00 参数,否则就不是合法的 MBR 程序。

但我也不懂为什么这个参数可以消除 relocation truncated to fit: R_X86_64_16 的错误。我对这个错误的理解就是某个使用的内存地址超过了 16 位地址空间。难道 ld 默认把程序放在比较高的位置?这合理吗?

参考资料

https://sourceware.org/binutils/docs/as/index.html#SEC_Contents

https://ftp.gnu.org/old-gnu/Manuals/gas-2.9.1/html_chapter/as_toc.html

https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_toc.html

https://medium.com/@g33konaut/writing-an-x86-hello-world-boot-loader-with-assembly-3e4c5bdd96cf

https://unix.stackexchange.com/questions/276480/booting-a-raw-disk-image-in-qemu

https://en.wikipedia.org/wiki/BIOS_interrupt_call

第三章

To be continued