-- TOC --
在学习OS的开始,就涉及到一小段汇编代码。这段代码由grub引导,是OS最开始的那一点点代码。学习资料的示例代码用nasm编写,我用intel语法重写了一遍,并用as编译测试通过。
这段代码如下:
.intel_syntax noprefix
MBT_HDR_FLAGS = 0x00010003
MBT_HDR_MAGIC = 0x1BADB002
MBT_HDR2_MAGIC = 0xE85250D6
# -m32
.extern main
.global _start
_start:
jmp _entry
.balign 8
mbt_hdr:
.long MBT_HDR_MAGIC
.long MBT_HDR_FLAGS
.long -(MBT_HDR_MAGIC+MBT_HDR_FLAGS)
.long mbt_hdr
.long _start
.long 0
.long 0
.long _entry
#以上是GRUB所需要的头
.balign 8
mbt2_hdr:
.long MBT_HDR2_MAGIC
.long 0
.long mbt2_hdr_end-mbt2_hdr
.long -(MBT_HDR2_MAGIC+(mbt2_hdr_end-mbt2_hdr))
.word 2,0
.long 24
.long mbt2_hdr
.long _start
.long 0
.long 0
.word 3,0
.long 12
.long _entry
.long 0
.word 0,0
.long 8
mbt2_hdr_end:
#以上是GRUB2所需要的头
#包含两个头是为了同时兼容GRUB、GRUB2
.balign 8
_entry:
cli # shutdown interrupt
#关不可屏蔽中断
in al, 0x70
or al, 0x80
out 0x70, al
#重新加载GDT
lgdt [GDT_PTR]
# 0x8就是kcode_dsc的偏移
jmp far ptr 0x8:_32bits_mode
_32bits_mode:
#下面初始化C语言可能会用到的寄存器
mov ax, 0x10
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
xor edi, edi
xor esi, esi
xor ebp, ebp
xor esp, esp
#初始化栈,C语言需要栈才能工作
mov esp, 0x9000
call main
hlt
GDT_START:
.quad 0
# base=0,length=0xfffff,G=1,D/B=1,L=0,AVL=0,P=1,DPL=0,S=1,T=1,C=1,R=1,A=0
kcode_dsc: .quad 0x00cf9e000000ffff
# base=0,length=0xfffff,G=1,D/B=1,L=0,AVL=0,P=1,DPL=0,S=1,T=0,C=0,R=1,A=0
kdata_dsc: .quad 0x00cf92000000ffff
#k16cd_dsc: .quad 0x00009e000000ffff
#k16da_dsc: .quad 0x000092000000ffff
GDT_END:
GDT_PTR:
.word GDT_END-GDT_START-1
.long GDT_START
整个学习项目源码在这里(经过整理和注释):helloOS
运行方法:
最佳测试方法,在Linux下用一个大文件来虚拟整块硬盘,给这块虚拟硬盘分区并安装BIOS grub,将hos.bin拷贝到虚拟硬盘分区根目录中,最后用qemu在这块虚拟硬盘上启动。在grub下使用如下两条命令即可启动hos.bin:
multiboot2 /hos.bin
boot
上个成功截图,给大家点信心:
完成整个过程有些不容易,下面这些知识会非常有帮助:
本文链接:https://cs.pynote.net/hd/asm/202309245/
-- EOF --
-- MORE --