为什么我的操作系统没有被我的引导加载程序文件加载?
我在创建操作系统时遇到问题。 我有 2 个文件(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"
内核.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
I have a problem with the creation of an OS.
I have 2 files (bootloader.s && kernel.s)
but when I compile thoses 2 files and exec there with
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
nothing append (just : "Booting from Hard Disk ...")
I didn't found solution on https://openclassrooms.com/forum/sujet/asm-boot-loader-91783
and the same for others tutorials.
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
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
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
a', %al
int $0x10
jmp .input__done
.input__letter__z:
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
z', %al int $0x10 jmp .input__done .input__letter__e: 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
e', %al int $0x10 jmp .input__done .input__letter__r: 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
r', %al int $0x10 jmp .input__done .input__letter__t: 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
t', %al int $0x10 jmp .input__done .input__letter__y: 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
y', %al int $0x10 jmp .input__done .input__letter__u: 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
u', %al int $0x10 jmp .input__done .input__letter__i: 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
i', %al int $0x10 jmp .input__done .input__letter__o: 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
o', %al int $0x10 jmp .input__done .input__letter__p: 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
p', %al int $0x10 jmp .input__done .input__letter__q: 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
q', %al int $0x10 jmp .input__done .input__letter__s: 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
s', %al int $0x10 jmp .input__done .input__letter__d: 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
d', %al int $0x10 jmp .input__done .input__letter__f: 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
f', %al int $0x10 jmp .input__done .input__letter__g: 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
g', %al int $0x10 jmp .input__done .input__letter__h: 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
h', %al int $0x10 jmp .input__done .input__letter__j: 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
j', %al int $0x10 jmp .input__done .input__letter__k: 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
k', %al int $0x10 jmp .input__done .input__letter__l: 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
l', %al int $0x10 jmp .input__done .input__letter__m: 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
m', %al int $0x10 jmp .input__done .input__letter__w: 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
w', %al int $0x10 jmp .input__done .input__letter__x: 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
x', %al int $0x10 jmp .input__done .input__letter__c: 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
c', %al int $0x10 jmp .input__done .input__letter__v: 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
v', %al int $0x10 jmp .input__done .input__letter__b: 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
b', %al int $0x10 jmp .input__done .input__letter__n: 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
n', %al int $0x10 jmp .input__done .input__letter__space: 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
', %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, %alF', %al int $0x10 # saut vers le kernel jmp BASE bootdrv: .int 0 .fill 510-(.-init), 1, 0 .word 0xaa55 .include "kernel.s"kernel.s
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看到kernel.s文件有一个
.org 0x1000
指令,我们知道.set BASE, 0x1000
指的是线性地址0x1000 。为了让 BIOS 加载内核,我们应该将%es:%bx
设置为 0x0000:0x1000。由于您的 bootloader.s 文件使用 7C00h 源,因此
%ds
和%es
的正确设置为零:由于您的 kernel.s 文件使用
.org 0x1000
,因此%ds
和%es
的正确设置为零:这个
int $0x10
应该做什么?如果
int $0x13
调用成功,则%ah
仍将包含 0x02,但这会导致无意义的 SetCursorPosition 调用,并且如果int $0 x13
调用不成功,然后%ah
将保存一个状态字节,这将导致调用一些随机视频 BIOS 调用!提示 1:始终检查 BIOS 向您报告的进位标志,以便您可以处理错误...
提示 2:最好省略
mov $0, %dl
指令,并使用 BIOS 在将控制权传递给引导加载程序时放入%dl
寄存器中的值。当
%al
不等于 224 时会发生什么?执行在某些数据中失败,绝对不是代码!我建议一步一步地进行,并简化当前代码(两个文件)以不使用那些与键盘相关的端口。
F', %al 整数 $0x10在需要键盘输入的地方,您应该使用 BIOS(就像您已经在使用其他任何东西一样):
这个
int $0x10
应该做什么?如果
int $0x13
调用成功,则%ah
仍将包含 0x02,但这会导致无意义的 SetCursorPosition 调用,并且如果int $0 x13
调用不成功,然后%ah
将保存一个状态字节,这将导致调用一些随机视频 BIOS 调用!提示 1:始终检查 BIOS 向您报告的进位标志,以便您可以处理错误...
提示 2:最好省略
mov $0, %dl
指令,并使用 BIOS 在将控制权传递给引导加载程序时放入%dl
寄存器中的值。当
%al
不等于 224 时会发生什么?执行在某些数据中失败,绝对不是代码!我建议一步一步地进行,并简化当前代码(两个文件)以不使用那些与键盘相关的端口。
在需要键盘输入的地方,您应该使用 BIOS(就像您已经在使用其他任何东西一样):
Seeing that the kernel.s file has an
.org 0x1000
directive, we know that the.set BASE, 0x1000
refers to the linear address 0x1000. In order to have BIOS load the kernel we should set%es:%bx
to 0x0000:0x1000.Because your bootloader.s file uses an origin of 7C00h, the correct setting for
%ds
and%es
is zero:Because your kernel.s file uses
.org 0x1000
, the correct setting for%ds
and%es
is zero:What is this
int $0x10
supposed to do?If the
int $0x13
call was successfull then%ah
would still contain 0x02, but that would lead to a non-sensical SetCursorPosition invokation, and if theint $0x13
call was unsuccessfull then%ah
would hold a status byte which would lead to invoking some random video BIOS call!Tip 1: Always check the carry flag that BIOS reports to you so you can deal with errors...
Tip 2: Better leave out the
mov $0, %dl
instruction and use the value that BIOS put in the%dl
register when it passed control to your bootloader.What happens when
%al
is not equal to 224? The execution falls through in some data, definitely not code!I would suggest to take it one step at a time, and simplify your current code (both files) to not use those keyboard related ports.
F', %al int $0x10Where keyboard input is needed you should use BIOS (like you're already using for anything else):
What is this
int $0x10
supposed to do?If the
int $0x13
call was successfull then%ah
would still contain 0x02, but that would lead to a non-sensical SetCursorPosition invokation, and if theint $0x13
call was unsuccessfull then%ah
would hold a status byte which would lead to invoking some random video BIOS call!Tip 1: Always check the carry flag that BIOS reports to you so you can deal with errors...
Tip 2: Better leave out the
mov $0, %dl
instruction and use the value that BIOS put in the%dl
register when it passed control to your bootloader.What happens when
%al
is not equal to 224? The execution falls through in some data, definitely not code!I would suggest to take it one step at a time, and simplify your current code (both files) to not use those keyboard related ports.
Where keyboard input is needed you should use BIOS (like you're already using for anything else):