为什么我的引导程序文件没有加载我的操作系统



我在创建操作系统时遇到问题。我有两个文件(bootloader.s&&kernel.s(但当我编译这两个文件并用执行时

as -o bootloader.o bootloader.s
ld -o bootloader.bin --oformat binary -e init -Ttext 0x7c00 -o bootloader.bin bootloader.o
qemu-system-x86_64 bootloader.bin

无附加(只是:"从硬盘启动…"(

我在上找不到解决方案https://openclassrooms.com/forum/sujet/asm-boot-loader-91783其他教程也是如此。

bootloader.s

.code16 # use 16 bits
.set BASE, 0x1000
.set KSIZE, 1
.global init
init:
mov $0x100, %ax
mov %ax, %ds
mov %ax, %es
# initialisation du segment de pile
mov $0x8000, %ax
mov %ax, %ss
mov $0xf000, %sp
mov $0x0e,  %ah
in  $0x64,  %al
test    $1, %al
jz  init_next
in  $0x60,  %al
cmp $224,   %al
je  init_next
init_next:
mov     BASE, %ax
mov     %ax, %es
xor     %bx, %bx
# charger le noyau
mov $0x02, %ah
mov KSIZE, %al
mov $0, %ch
mov $2, %cl
mov $0, %dh
mov $0, %dl
int $0x13
mov $'F', %al
int $0x10

# saut vers le kernel
jmp BASE

bootdrv: .int 0

.fill 510-(.-init), 1, 0
.word 0xaa55
.include "kernel.s"

kernel.s

.code16
.global init
.org 0x1000
start:
mov $0x1000, %ax
mov %ax, %ds
mov %ax, %es
# initialisation du segment de pile
mov $0x8000, %ax
mov %ax, %ss
mov $0xf000, %sp
mov $0x0e,  %ah
in  $0x64,  %al
test    $1, %al
jz  next
in  $0x60,  %al
cmp $224,   %al
je  next
data:
msg: .asciz "Hello world !"
msg2: .asciz "I hope you're well : "
test_int: .int 0
#msg3: .asciz "Just a test for the size of the bootloader"
print_str:
push %ax
.print_str__run:
lodsb
cmp $0, %al
je  .print_str__done
int $0x10
jmp .print_str__run
.print_str__done:
pop %ax
ret
print_nl:
push %ax
.print_nl__run:
mov $10, %al
int $0x10
mov $13, %al
int $0x10
pop %ax
ret

input:
.input__run:
in  $0x64,  %al
and $1, %al
jz  .input__run
in  $0x60,  %al # get input keyboard
mov %al,    %bl
cmp $0x0,   %bl
je  .input__run
shr $4, %bl # move to right 4 bits
cmp $0x0, %bl
je  .input__number
jmp .input__letter

.input__number:
add $47,    %al
int $0x10
jmp .input__done
.input__letter:
cmp $0x10,  %al
je .input__letter__a
cmp $0x11,  %al
je .input__letter__z
cmp $0x12,  %al
je .input__letter__e
cmp $0x13,  %al
je .input__letter__r
cmp $0x14,  %al
je .input__letter__t
cmp $0x15,  %al
je .input__letter__y
cmp $0x16,  %al
je .input__letter__u
cmp $0x17,  %al
je .input__letter__i
cmp $0x18,  %al
je .input__letter__o
cmp $0x19,  %al
je .input__letter__p
cmp $0x1e,  %al
je .input__letter__q
cmp $0x1f,  %al
je .input__letter__s
cmp $0x20,  %al
je .input__letter__d
cmp $0x21,  %al
je .input__letter__f
cmp $0x22,  %al
je .input__letter__g
cmp $0x23,  %al
je .input__letter__h
cmp $0x24,  %al
je .input__letter__j
cmp $0x25,  %al
je .input__letter__k
cmp $0x26,  %al
je .input__letter__l
cmp $0x27,  %al
je .input__letter__m
cmp $0x2c,  %al
je .input__letter__w
cmp $0x2d,  %al
je .input__letter__x
cmp $0x2e,  %al
je .input__letter__c
cmp $0x2f,  %al
je .input__letter__v
cmp $0x30,  %al
je .input__letter__b
cmp $0x31,  %al
je .input__letter__n
cmp $0x39,  %al
je .input__letter__space
jmp .input__run
.input__letter__a:
mov $'a',   %al
int $0x10
jmp .input__done
.input__letter__z:
mov $'z',   %al
int $0x10
jmp .input__done
.input__letter__e:
mov $'e',   %al
int $0x10
jmp .input__done
.input__letter__r:
mov $'r',   %al
int $0x10
jmp .input__done
.input__letter__t:
mov $'t',   %al
int $0x10
jmp .input__done
.input__letter__y:
mov $'y',   %al
int $0x10
jmp .input__done
.input__letter__u:
mov $'u',   %al
int $0x10
jmp .input__done
.input__letter__i:
mov $'i',   %al
int $0x10
jmp .input__done
.input__letter__o:
mov $'o',   %al
int $0x10
jmp .input__done
.input__letter__p:
mov $'p',   %al
int $0x10
jmp .input__done
.input__letter__q:
mov $'q',   %al
int $0x10
jmp .input__done
.input__letter__s:
mov $'s',   %al
int $0x10
jmp .input__done
.input__letter__d:
mov $'d',   %al
int $0x10
jmp .input__done
.input__letter__f:
mov $'f',   %al
int $0x10
jmp .input__done
.input__letter__g:
mov $'g',   %al
int $0x10
jmp .input__done
.input__letter__h:
mov $'h',   %al
int $0x10
jmp .input__done
.input__letter__j:
mov $'j',   %al
int $0x10
jmp .input__done
.input__letter__k:
mov $'k',   %al
int $0x10
jmp .input__done
.input__letter__l:
mov $'l',   %al
int $0x10
jmp .input__done
.input__letter__m:
mov $'m',   %al
int $0x10
jmp .input__done
.input__letter__w:
mov $'w',   %al
int $0x10
jmp .input__done
.input__letter__x:
mov $'x',   %al
int $0x10
jmp .input__done
.input__letter__c:
mov $'c',   %al
int $0x10
jmp .input__done
.input__letter__v:
mov $'v',   %al
int $0x10
jmp .input__done
.input__letter__b:
mov $'b',   %al
int $0x10
jmp .input__done
.input__letter__n:
mov $'n',   %al
int $0x10
jmp .input__done
.input__letter__space:
mov $' ',   %al
int $0x10
jmp .input__done
.input__done:
ret
next:
.key_wait:
in  $0x64,  %al
and $1, %al
jz  .key_wait
in  $0x60,  %al
cmp $0x10,  %al # 'a' pressed
je .code
mov %al,    %bl
cmp $0x0,   %bl
je  .key_wait
shr $4, %bl
cmp $0x0, %bl
je  .number
jmp .normal

.number:
add $47,    %al
int $0x10
jmp .key_wait
.normal:
int $0x10
jmp .key_wait
.code:
#mov $8, %al
#mov %al, test_int
call print_nl
mov $msg, %si
call print_str
call print_nl
mov $msg2, %si
call print_str
code__input:
call input
mov $0x0, %al
mov     BASE, %ax
mov     %ax, %es
xor     %bx, %bx

看到kernel.s文件有一个.org 0x1000指令,我们知道.set BASE, 0x1000指的是线性地址0x1000。为了让BIOS加载内核,我们应该将%es:%bx设置为0x0000:0x1000。

xor %ax, %ax
mov %ax, %es
mov BASE, %bx

init:
mov $0x100, %ax
mov %ax, %ds
mov %ax, %es

因为引导加载程序.s文件使用7C00h的原点,所以%ds%es的正确设置为零:

init:
xor %ax, %ax
mov %ax, %ds
mov %ax, %es

.org 0x1000
start:
mov $0x1000, %ax
mov %ax, %ds
mov %ax, %es

因为内核.s文件使用.org 0x1000,所以%ds%es的正确设置为零:

.org 0x1000
start:
xor %ax, %ax
mov %ax, %ds
mov %ax, %es

mov $0, %dl
int $0x13
mov $'F', %al
int $0x10

这个int $0x10应该做什么
如果int $0x13调用成功,则%ah仍将包含0x02,但这将导致无意义的SetCursorPosition调用;如果int $0x13调用失败,则%ah将保留一个状态字节,这将导致调用一些随机视频BIOS调用!

提示1:总是检查BIOS报告给你的进位标志,这样你就可以处理错误
提示2:最好不要使用mov $0, %dl指令,而是使用BIOS在将控制权传递给引导程序时放入%dl寄存器的值。


cmp $224,   %al
je  next
data:
msg: .asciz "Hello world !"

%al不等于224时会发生什么?执行失败在某些数据中,绝对不是代码!

我建议一步一个脚印,将当前代码(两个文件(简化为不使用那些与键盘相关的端口
在需要键盘输入的地方,您应该使用BIOS(就像您已经在使用其他任何东西一样(:

mov  ah, 00h   ; BIOS.WaitKeyboardKeypress
int  16h       ; -> AH is scancode, AL is ASCII code

相关内容

最新更新