boot loader的基础
x86芯片总是从16位实模式启动,bios依次查找
初始情况下,int 0x10
中断向控制台输出寄存器al
指向中的字符,lodsb
指令可以将字符从si
指向加载到al
中,并移动一个字节。
lodsb -> al=*si++
nasm(intel 语法)
org 0x7C00 ; BIOS loads our programm at this address
bits 16 ; We're working at 16-bit mode here
start:
;; cli ; Disable the interrupts
mov si, msg ; SI now points to our message
mov ah, 0x0E ; Indicate BIOS we're going to print chars
.loop lodsb ; Loads SI into AL and increments SI [next char]
or al, al ; Checks if the end of the string,i.e. '\0'
jz halt ; Jump to halt if the end
int 0x10 ; Otherwise, call interrupt for printing the char
jmp .loop ; Next iteration of the loop
halt: hlt ; CPU command to halt the execution
cli
jmp halt
msg: db "Hello, World!", 0 ; Our actual message to print
;; Magic numbers
times 510 - ($ - $$) db 0
dw 0xAA55
编译:nasm boot.asm -f bin -o boot.bin
ANSI语法
https://50linesofco.de/post/2018-02-28-writing-an-x86-hello-world-bootloader-with-assembly
.code16 # tell the assembler that we're using 16 bit mode
.global init # makes our label "init" available to the outside
init: # this is the beginning of our binary later.
# do anyting you want
jmp init # jump to "init"
.fill 510-(.-init), 1, 0 # add zeroes to make it 510 bytes long
.word 0xaa55 # magic bytes that tell BIOS that this is bootable
编译、连接、抽取二进制
as -o boot.o boot.s
ld -o boot.bin --oformat binary -e init boot.o
启动:
qemu-system-x86_64 boot.bin # 等价于 -hda boot.bin
qemu-system-x86_64 -hda boot.bin # 等价于 -hda boot.bin
qemu-system-i386 boot.bin
# macos 加上-nographic
qemu-system-i386 -nographic boot.bin
从qemu退出
Exit from QEMU
First press Ctrl+a then press c to get to qemu console then enter quit to exist.
gdb调试
开启监听:
# -S 首行hang住,等待gdb连接
# -s 监听tcp:1234端口
qemu-system-i386 boot.bin -s -S
连接调试:
# -ex 启动执行的命令
# -ex 'set architecture i8086' 显示指令时使用16位
gdb -ex 'target remote :1234' -ex 'set architecture i8086'
# break *0x7c00 # 设置地址断点
# x/20i 0x7c00 # 打印20条指令
# x/10c 0x7c12 # 打印字符串,0x7c12是hello world的存放地址
macos
无法启动:
https://stackoverflow.com/questions/58318920/qemu-not-responding-after-upgrading-to-macos-catalina
加上-nographic
标志即可解决。