环境
首先,你需要安装NASM汇编器和QEMU来模拟一个虚拟机。用QEMU很好,因为我们不用担心有时候不小心写了烂的OS代码而把硬件给搞坏了;) 。在win 10的wsl或Ubuntu上你可以用这个命令来安装它们(之前可以用sudo apt-get update更新一下软件源):
sudo apt-get install nasm qemu
在Mac上你可以使用homebrew:
brew install nasm
在win 10上,你还要安装X Server,这样QEMU就可以从WSL中打开一个窗口。
Hello World的Bootloader
我们将编写一个软盘引导加载程序,它不需要我们处理文件系统,这有助于使事情尽可能简单。
让我们把Help World World打印到屏幕上。要做到这一点,我们将使用“TTY模式下的写入字符”BIOS中断调用和加载字符串字节指令LoBSB,将地址DS:SI中的字节加载到AL中。下面是:
bits 16 ; tell NASM this is 16 bit code
org 0x7c00 ; tell NASM to start outputting stuff at offset 0x7c00
boot:
mov si,hello ; point si register to hello label memory location
mov ah,0x0e ; 0x0e means 'Write Character in TTY mode'
.loop:
lodsb
or al,al ; is al == 0 ?
jz halt ; if (al == 0) jump to halt label
int 0x10 ; runs BIOS interrupt 0x10 - Video Services
jmp .loop
halt:
cli ; clear interrupt flag
hlt ; halt execution
hello: db "Hello world!",0
times 510 - ($-?) db 0 ; pad remaining 510 bytes with zeroes
dw 0xaa55 ; magic bootloader magic - marks this 512 byte sector bootable!
你可以使用nasm来编译它(把它保存为boot1.asm)
nasm -f bin boot1.asm -o boot1.bin
如果我们运行hexdump boot1.bin,我们可以看到NASM创建了一些代码,填充了一些零点,然后将最后两个字节设置为幻数。
0000000 10be b47c ac0e c008 0474 10cd f7eb f4fa
0000010 6548 6c6c 206f 6f77 6c72 2164 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
0000200
现在我们可以运行这个东西!你可以告诉QEMU使用qemu-system-x86_64 -fda boot1.bin引导软盘。在win 10上,你之前还应该设置环境变量SET DISPLAY=:0(这个其实是指定了X Server的地址)。
你应该得到这样的东西!