我是一个初学汇编程序员,我试图写一个x86内核 Bootstrap 。主引导加载程序似乎工作正常,但辅助引导加载程序有一些问题:当内核分区文件系统丢失/损坏或找不到内核可执行文件(kernel.bin)时,它不会显示错误消息。我的bootloader出现了一些奇怪的情况。我附上了主 Bootstrap 和辅助 Bootstrap 的源代码。我真的很感激你的帮助。谢谢你,谢谢
主引导加载程序:
ORG 0x7c00
BITS 16
start:
mov si, message
call print
mov ah, 2
mov al, 1
mov ch, 0
mov dh, 0
mov dl, 0x80
mov bx, 0x8000
mov cx, 3
int 0x13
jc disk_error
mov si, buffer
cmp byte [si + 0x8000], 0x00
jnz secondary_bootloader_missing
jmp 0x0000:0x8000
disk_error:
mov si, disk_error_message
call print
secondary_bootloader_missing:
mov si, secondary_bootloader_missing_message
call print
cli
hlt
print:
mov bx, 0
loop:
lodsb
cmp al, 0
je done
call _print
jmp loop
done:
ret
_print:
mov ah, 0x0E
int 0x10
ret
message:
db "Bootloader", 0x0A, 0x0A, 0
disk_error_message:
db "Disk error!", 0x0A, 0
secondary_bootloader_missing_message:
db "Secondary bootloader not found - system halted!", 0x0A, 0
buffer:
times 510-($ -$$) db 0
db 0xAA55
辅助 Bootstrap :
ORG 0x8000
BITS 16
section .data
buffer db 16 dup(0)
pit_info db 16 dup(0)
active_partition_info dw 0
section .text
global start
start:
mov ah, 0x00
mov al, 0x03
int 0x10
mov si, starting_message
call print
mov ds, ax
mov es, ax
mov ah, 0x02
mov al, 0x01
mov ch, 0x00
mov dh, 0x00
mov dl, 0x80
mov bx, buffer
int 0x13
jc error_missing_pit
xor cx, cx
mov si, buffer
loop:
mov ax, [si + 0x1C]
test ax, ax
jnz found_bootable
add si, 16
inc cx
cmp cx, 0
jz no_bootable
jmp loop
found_bootable:
mov di, pit_info
mov cx, 16
rep movsb
mov ax, [si + 0x08]
mov [active_partition_info], ax
mov ax, [si + 0x0C]
mov [active_partition_info + 2], ax
mov ah, 0x02
mov bh, 0x00
mov dh, 0x01
mov dl, 0x00
int 0x10
mov si, partition_found_message
mov ax, 0x0000
mov ds, ax
call print
jmp kernel_load
error_missing_pit:
mov si, missing_pit
mov ax, 0x0000
mov ds, ax
call print
cli
hlt
no_bootable:
mov si, no_partition
mov ax, 0x0000
mov ds, ax
call print
cli
hlt
starting_message:
db "Starting the operating system...", 0x0A, 0
missing_pit:
db "Partition Table error!", 0x0A, 0
no_partition:
db "Kernel partition cannot be found - does it have the active flag?", 0x0A, 0
print:
mov bx, 0
call print_loop
ret
print_loop:
mov al, [si]
cmp al, 0
je print_done
mov ah, 0x0E
int 0x10
inc si
jmp print_loop
print_done:
ret
kernel_load:
mov ax, [active_partition_info]
add ax, 19
mov es, ax
mov bx, 0
mov ah, 0x02
mov al, 1
mov ch, 0
mov dh, 0
mov dl, 0x80
mov si, boot_sector_buffer
int 0x13
mov si, file_system_signature
mov cx, 3
repe cmpsb
jnz not_fat12
jmp search_file
not_fat12:
mov si, file_system_error_message
call print
cli
hlt
boot_sector_buffer:
times 512 db 0
file_system_signature:
db 0x55, 0xAA
file_system_error_message:
db "Unknown boot partition file system!", 0
search_file:
mov cx, 11
mov di, kernel_filename
rep cmpsb
je file_found
add bx, 32
cmp bx, 512
jae file_not_found
jmp search_file
file_found:
mov ax, 0x1000
mov cx, 8
mov dx, ax
mov bx, 0
call read_file
jmp 0x1000:0000
file_not_found:
mov si, kernel_not_found_message
call print
cli
hlt
read_file:
pusha
mov ax, cx
mov ah, 0x02
mov al, 1
mov ch, 0
mov dh, 0
int 0x13
jnc read_success
stc
popa
ret
read_success:
add dx, 512
add bx, 1
dec ax
jnz read_loop
popa
ret
read_loop:
pusha
mov ax, cx
mov ah, 0x02
mov al, 1
mov ch, 0
mov dh, 0
int 0x13
jnc read_success
stc
popa
ret
kernel_filename:
db "KERNEL BIN", 0
kernel_not_found_message:
db "Kernel file (kernel.bin) not found!", 0
partition_found_message:
db "Kernel partition found!", 0x0A, 0
1条答案
按热度按时间zysjyyx41#
我试着运行这段代码,我发现一些错误
db 0xAA55
。我把它改成了dw 0xAA55
,我们准备好了。;)1.程序读取以
Unknown boot partition file system!
开头的(扇区3)。所以这些字节序列创建了一些随机指令,这和程序无关。我以“X”开头,后面跟着jmp label
。mov si, buffer
,cmp byte [si + 0x8000], 0x00
。我假设这是第二个 Bootstrap 的代码应该在的位置。si = 0x7c93
+0x8000
=0xfc93
。[0xfc93] = 0x00
。我不知道,也许这应该是cmp byte [0x8000], 0x??
,因为我们加载扇区到0x8000
??我在扇区3的开头插入了X
,如果字节0x8000
与X
不同,这意味着这不是第二个 Bootstrap 。1.我一步一步地浏览了代码,注意到扇区3中的标签是+512字节,所以我将
org 0x8000
更改为org 0x7e00
。现在标签的偏移量计算正确。1.在
search_file:
中,我比较10个字节而不是11个字节,因为0
将与eb
进行比较,当然这将是错误的。错误也是好的,因为这样我就知道消息是正确生成的。;)1.错误信息没有显示,因为
print proc
在扇区2中,未加载到内存。我切换到第一个文件,我决定立即加载所有部门。我在内存中有内核和第二个 Bootstrap 。1.如果没有找到
kernel_filename
程序打印kernel_not_found_message
否则我们有代码进一步假设加载另一个部门(8),这当然是不可用的。es = 0
、bx = 0
、dl = 0
。从fdd读取到IVT。这会生成错误ah = 20h
,文件共享违规。这个程序返回后,我们得到jmp 0x1000:0000
。跳入虚无...1.我假设扇区2是内核,所以我跳转到
0:800a
。1.好的,程序打印
starting_message
,接下来我们读取扇区例程,生成missing_pit
,分区表错误!,ah = 1
,无效的函数号。buffer db 16 dup(21)
是16字节,读扇区例程读取512字节。1.我做了一些修改,使这个代码工作。我在qemu中运行的图像文件是3个文件的组合。
bootloader1.bin
(扇区1)bootloader2.bin
(扇区2,3,4,5,6)activepartition.bin
(第7区)