assembly 程序集引导加载程序无法修复错误和冻结

pgx2nnw8  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(129)

我是一个初学汇编程序员,我试图写一个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
zysjyyx4

zysjyyx41#

我试着运行这段代码,我发现一些错误

  1. Bootloader无法启动,因为存在db 0xAA55。我把它改成了dw 0xAA55,我们准备好了。;)
    1.程序读取以Unknown boot partition file system!开头的(扇区3)。所以这些字节序列创建了一些随机指令,这和程序无关。我以“X”开头,后面跟着jmp label
  2. mov si, buffercmp byte [si + 0x8000], 0x00。我假设这是第二个 Bootstrap 的代码应该在的位置。si = 0x7c93 + 0x8000 = 0xfc93[0xfc93] = 0x00。我不知道,也许这应该是cmp byte [0x8000], 0x??,因为我们加载扇区到0x8000??我在扇区3的开头插入了X,如果字节0x8000X不同,这意味着这不是第二个 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 = 0bx = 0dl = 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区)
; bootloader1.bin

ORG 0x7c00

BITS 16

start:
    mov ah, 0x00                    ; text mode
    mov al, 0x03
    int 0x10

    xor ax, ax                      ; set up segments
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7c00

    mov si, message                 ; "Bootloader - stage 1" 
    call print

    mov ah, 2                       ; load all sectors
    mov al, 5
    mov dh, 0
    mov dl, 0x80
    mov bx, 0x8000
    mov cx, 0x0002                      
    int 0x13

    jc disk_error

    mov si, stage2_bl_kernel        
    call print

    mov si, 0x8000              ; offset of kernel code
    cmp byte [0x8200], 'X'      ; check if this is correct bootloader - stage 2 sector

    jnz secondary_bootloader_missing
    jmp 0x0000:0x8201

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 "Sector 1 (Bootloader - stage 1) - loaded!", 0x0A, 0x0D, 0

disk_error_message:
    db "Disk error!", 0x0A, 0

secondary_bootloader_missing_message:
    db "Sector 3 (Bootloader - stage 2)", 0x0A, 0x0D
    db "Wrong sector - system halted!", 0x0A, 0x0D,0

stage2_bl_kernel:
    db "Sector 2 (Kernel)               - loaded!", 0x0A,0x0D
    db "Sector 3 (Bootloader - stage 2) - loaded!", 0x0A,0x0D,0     
buffer:
    times 510-($ - $$) db 0
    dw 0xAA55
; bootloader2.bin

ORG 0x8000

BITS 16

section .data
    buffer db 512 dup('x')
    pit_info db 16 dup('z')
    active_partition_info dw 0x7878

section .text
    global start
; sector 2
db "KERNEL.BIN"
start:
    ;mov ah, 0x00
    ;mov al, 0x03
    ;int 0x10

    mov si, buffer + 508
    mov di, active_id
    mov cx, 4
    repe cmpsb

    jnz not_act_partition   

    mov si, correct_id
    call print  

    mov si, partition_table_entries
    call print  

    ; check partition table entries

    mov cx, 3
    mov al, 0x31
    mov bx, entry_num
    mov ah, [bx]
    mov si, buffer + 450 
    xor dx, dx              ; if 0 there is no system

    pt_entries:
        push si
        push ax
        push bx
    
        cmp al, [si]
        jz good_sys
        jb other_sys
    
        mov si, entry_msg
        call print 
        mov si, entry_num
        call print
        mov si, entry_msg_empty
        call print
    
        jmp entry_info_done
    
        good_sys:
            mov dx, si
            mov si, entry_msg
            call print 
            mov si, entry_num
            call print
            mov si, entry_msg_sys
            call print
        
            jmp entry_info_done
        
        other_sys:
            mov si, entry_msg
            call print 
            mov si, entry_num
            call print
            mov si, entry_msg_other_sys
            call print
        
            jmp entry_info_done
        
        entry_info_done:
            pop bx
            pop ax
            add ah, 1
            mov [bx], ah
            pop si
            add si, 16
            dec cx
    jnz pt_entries

    cmp dx, 0
    jz no_entry_info

    mov si, entry_found
    call print  

found_bootable:
    sub dx, 2               ; copy entry to pit_info
    mov si, dx
    mov di, pit_info
    mov cx, 16
    rep movsb

    mov ax, 0x4b4f
    mov [active_partition_info], ax

    mov si, starting_message
    call print  
        
    jmp 0x0000:0x8600
    
no_entry_info:  
    mov si, no_entry_info_message
    call print
    cli
    hlt

not_act_partition:
    mov si, not_act_partition_message
    call print
    cli
    hlt

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,0x0D, 0

not_act_partition_message:
    db "Sector 5 (Active partition)", 0x0A,0x0D
    db "Incorrect Signature - system halted!", 0x0A,0x0D, 0

missing_pit: 
    db "Partition Table error!", 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
;-------- sector 3
sector3_start:
db "X"              ; this is marker of 2nd bootloader
jmp search_file

file_system_error_message:
    db "Unknown boot partition file system!", 0

search_file:
    mov cx, 10
    mov di, kernel_filename
    rep cmpsb

    je kernel_found
    add bx, 32
    cmp bx, 512
    jae file_not_found
    jmp search_file

kernel_found:
    mov si, kernel_found_message
    call print

load_partition:
    mov ah, 0x02                
    mov al, 0x01
    mov ch, 0x00
    mov cl, 0x07
    mov dh, 0x00
    mov dl, 0x80    
    mov bx, buffer
    int 0x13
    jc load_failed

    mov si, act_part_loaded
    call print

    jmp 0x0000:0x800a

file_not_found:
    mov si, kernel_not_found_message
    call print
    cli
    hlt

load_failed:
    mov si, load_failed_message
    call print
    cli
    hlt

kernel_filename:
    db "KERNEL.BIN", 0

active_id:
    db 0x41, 0x63, 0x74, 0x50           

kernel_not_found_message:
    db "Sector 2 (Kernel)",0x0A,0x0D
    db "Wrong sector - system halted!", 0x0A, 0x0D,0

kernel_found_message:
    db "Sector 2 (Kernel)               - correct sector!", 0x0A,0x0D, 0

load_failed_message:
    db "Sector 5 (Active partition)", 0x0A,0x0D
    db "Disk error!", 0x0A,0x0D, 0

act_part_loaded:
    db "Sector 5 (Active partition)     - loaded!", 0x0A,0x0D,0 

correct_id:
    db "Sector 5 (Active partition)     - correct signature!", 0x0A,0x0D,0

partition_table_entries:    
    db "Partition Table entries:", 0x0A,0x0D, 0 

no_entry_info_message:
    db "Sector 5 (Active partition)", 0x0A,0x0D
    db "Partition Table - All entries are incorrect!", 0x0A,0x0D, 0

entry_msg:   
    db "Entry ",0
 
entry_msg_empty:     
    db " - Free slot.",0x0A,0x0D,0

entry_msg_other_sys:    
    db " - Other system",0x0A,0x0D,0

entry_msg_sys:  
    db " - Good system <3",0x0A,0x0D,0  

entry_found:    
    db "Entry found!",0x0A,0x0D,0

entry_num:
    db 0x31,0x00

no_partition:
    db "Kernel partition cannot be found - does it have the active flag?", 0x0A, 0

    ;times 308 db 33
    ;boot_sector_buffer1:
    times 1022 - ($ - sector3_start) db 0x00
; activepartition.bin

ORG 0x8600

BITS 16

start:  
mov si, cmd
call print

system_stop:
    hlt
    jmp system_stop

print:
    mov bx, 0

loop:
    lodsb
    cmp al, 0
    je done
    call _print
    jmp loop

done:
    ret

_print:
    mov ah, 0x0E
    int 0x10
    ret

cmd:
    db "Cmd: > ", 0x0A, 0x0D, 0

    times 448-($ - $$) db 0
    ; PT0 - Empty entry
    ; PT1 - System
    ; PT2 - Other system
    db 'P','T','0','D','r','v',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    db 'P','T','2','D','r','v',0x80,'O','t','h','e','r',' ','s','y','s'
    db 'P','T','1','D','r','v',0x80,'D','r','v','P','a','r','a','m','s'
    times 12 db 0
    dw 0x6341,0x5074        ; 7PAc
; makefile

BUILD_DIR = build
SRC_DIR = src
IMG_NAME = dev

dev: bl1 bl2 ap image
    C:\Program Files\qemu\qemu-system-i386 -hda $(BUILD_DIR)\$(IMG_NAME).img

image: $(BUILD_DIR)\bootloader1.bin $(BUILD_DIR)\bootloader2.bin
    @dd if=$(BUILD_DIR)\bootloader1.bin of=$(BUILD_DIR)\$(IMG_NAME).img bs=512
    @dd if=$(BUILD_DIR)\bootloader2.bin of=$(BUILD_DIR)\$(IMG_NAME).img bs=512 seek=1
    @dd if=$(BUILD_DIR)\activepartition.bin of=$(BUILD_DIR)\$(IMG_NAME).img bs=512 seek=6

    @objdump -b binary -m i8086 -M intel -D $(BUILD_DIR)\$(IMG_NAME).img
    @hexdump -C $(BUILD_DIR)\$(IMG_NAME).img    

clean:
    rm -f $(BUILD_DIR)\bootloader1.bin $(BUILD_DIR)\bootloader2.bin

bl1:
    nasm -g -fbin $(SRC_DIR)\bootloader1.asm -o $(BUILD_DIR)\bootloader1.bin
bl2:
    nasm -g -fbin $(SRC_DIR)\bootloader2.asm -o $(BUILD_DIR)\bootloader2.bin
ap:
    nasm -g -fbin $(SRC_DIR)\activepartition.asm -o 
    $(BUILD_DIR)\activepartition.bin

相关问题