Kernel

《自己动手写操作系统》操作实践

这个系列文章是跟着我8年前开始看的一本书《自己动手写操作系统》以及它的第2版《Orange's 一个操作系统的实现》。当时由于年少轻狂以及时运不佳,一直没有机会真正深入下去,今天我重新拿起这本书,继续这段旅程。

源码

      org 07c00h
      mov ax, cs
      mov ds, ax
      mov es, ax
      call DispStr
      jmp $
DispStr:
      mov ax, BootMessage
      mov bp, ax
      mov cx, 16
      mov ax, 01301h
      mov bx, 000ch
      mov dl, 0
      int 10h
      ret
BootMessage:         db "Hello, OS world!"
times 510-($-$$)     db 0
dw 0xaa55

编译

nasm -f bin -o boot.bin boot.asm

十六进制结果

jietu20180727-150229-2x

分析

第511-512字节即为零扇区末尾,一定要标记位55AA,表示为启动盘。
dw 0xaa55是因为Intel是小头党。

制作软盘镜像

dd if=/dev/zero of=floppy.img bs=1024 count=1440
dd if=boot.bin of=floppy.img seek=0 count=1 conv=notrunc

十六进制结果

jietu20180727-150617-2x

分析

软盘镜像实际上只是把boot.bin扩展到1.44MB,全部置零而已。

错误理解

看到有篇文章《ORANGE’S:一个操作系统的实现》第一个例子的实现
文末写了这么一段话:

注意!

我在起床之后查了一些资料,发现 nasm可以直接对asm文件进行编译,生成img格式文件。且运行成功。。。。。。

命令: nasm -o boot.img boot.asm

真是蛋疼

完成于2014.11.29 16:00

实际上他这么理解是错误的。因为实际上,nasm并不会因为output文件名的扩展名差异而做任何改变,你编译出来的boot.img和boot.bin一样都是512bytes,而不是1.44MB。更进一步,你直接把boot.bin扔到VMware的虚拟软驱里面,效果等同于它帮你自动补0。转换为软盘镜像这一步是不必要的。

制作iso镜像

Windows平台:使用UltraISO制作

截图

jietu20180727-145437-2x

gdb

jietu20180731-131440-2x

源码说明

org 07c00h 并不是汇编指令,而是告诉编译器,这段代码要加载到offset位07c00h处,而不是默认的0h处。
mov ax, cs mov ds, ax mov es, ax 这3行在本例中其实用不上,可以删除。

call DispStr 调用DispStr函数,执行完成后返回执行下一行
jmp $ 这是本例最后执行的指令,原地无限死循环jump,可在屏幕上看到闪烁的光标
DispStr: DispStr函数标记
mov ax, BootMessage BootMessage在下方,是一个字符串
mov bp, ax
mov cx, 16
mov ax, 01301h
mov bx, 000ch
mov dl, 0
int 10h
ret
BootMessage: db "Hello, OS world!" db是define bytes
times 510-($-$$) db 0 我们必须让下一行占用2个的0xaa55位于第511和512字节处,这样BIOS就会明白这是一个启动扇区。($-$$)可算出截至目前一共使用了多少个字节,我们需要填充510-($-$$)个字节的0x00。
dw 0xaa55 启动扇区标志