这是我的引导加载程序代码,这是一个显示寄存器图片的文档(以防我做错了什么很重要),内存中位置 0x10000 的内容(我告诉引导加载程序加载内核),我的内核的源程序集,以及运行 Qemu 时的屏幕输出。
kernelStub.bin 一开始就有EB 1B(右跳转命令)。hda.img 在第二个扇区开始的 55 AA 之后有 EB 1B。进位标志在我的 load_mem 子例程中很清楚,表明它认为负载是好的。除了前两个总是 63 61 之外,所有字节都在内存中。
为什么 load_mem 例程总是错误地将扇区 2 的前两个字节加载到地址 0x10000 中,然后将其余部分正确?
引导加载程序代码:
更新:更改jmp SYSADDR:0000为jmp 0x1000:0x0000根据 Matthew Slattery 的更正。
;Very minimal boot loader 
BITS 16                ;Tell assembler to use 16-bit mode
jmp start              ;Jump over defines
SYSADDR  dw 0x1000     ;Load system at 0x10000
DRIVENUM db 0x80       ;Variable for drive number
HEADNUM  db 0
CYLNUM   db 0          ;Low bits of cylinder number
SECTNUM  db 2          ;Bits 6 and 7 high bits of cylinder number (0),
                       ;Bits 0-5 starting sector number (2)
NUMKERNELSECTS db 0x01 ;Will Probably Change! Number of sectors
                       ;to read from disk
load_msg    db 'Loading OS', 0
msg_2       db 'carry flag not clear', 0
load_worked db 'Load worked', 0
start:
    mov ax, 0x07C0     ;Set data segment to where BIOS loaded boot loader
    mov ds, ax
    mov si, load_msg   ;Simple text string to indicate loading
    call show_message
    call load_mem      ;Subroutine to load bytes from disk to location
                       ;pointed to by es
    jmp 0x1000:0x0000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Subroutines
;;;Show Message;;;
show_message:
    mov ah, 0x0E       ;int 0x10 print character to screen function
.repeat:
    lodsb              ;Get char pointed to by si, puts in al
    cmp al, 0          ;see if char is 0 (null)
    je .done           ;null signifies done
    int 0x10           ;If not null, print to screen
    jmp .repeat        ;Get next char
.done:
    ret
;;;Load Memory;;;
load_mem:
    xor ah, ah         ;ah=0, reset drive
    int 0x13           ;Call drive reset
    mov ax, [SYSADDR]
    mov es, ax         ;Destination- es:bx
    mov bx, 0
    mov dl, [DRIVENUM]
    mov dh, [HEADNUM]
    mov al, [NUMKERNELSECTS]
    mov ch, [CYLNUM]
    mov cl, [SECTNUM]
    mov ah, 0x02       ;ah=2, read drive
    int 0x13           ;Call read interrupt
    jnc exit           ;If carry flag is clear, exit
exit:
    ret
times 510 - ($-$$) db 0;Pad sector with 0
dw 0xAA55              ;Boot signature