汇编引导加载程序不显示错误并冻结

问题描述 投票:0回答:1

我是一名初级汇编程序员,我正在尝试为内核编写 x86 引导加载程序。主引导加载程序似乎工作正常,但辅助引导加载程序有一些问题:当内核分区文件系统丢失/损坏或找不到内核可执行文件 (kernel.bin) 时,它不会显示错误消息。我的引导加载程序发生了一些奇怪的事情。我附上了主引导加载程序和辅助引导加载程序源代码。我真的很感激一些帮助。谢谢!

主引导加载程序:


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

辅助引导加载程序:



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
assembly filesystems kernel bootloader
1个回答
0
投票

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

  1. Bootloader 无法启动,因为有

    db 0xAA55
    。我将其更改为
    dw 0xAA55
    ,我们就可以开始了。 ;)

  2. 程序读取以

    Unknown boot partition file system!
    开头的(扇区3)。 所以这些字节序列创建了一些随机指令,而这没有任何内容 与程序有关。我以“X”开始这个部分,然后是
    jmp label

  3. mov si, buffer
    cmp byte [si + 0x8000], 0x00
    。我假设这是第二个代码的位置 引导加载程序应该是。
    si = 0x7c93
    +
    0x8000
    =
    0xfc93
    [0xfc93] = 0x00
    。 我不知道,也许这应该是
    cmp byte [0x8000], 0x??
    因为我们加载扇区 到
    0x8000
    ??我在第 3 扇区的开头插入了
    X
    ,如果字节
    0x8000
    X
    不同 这意味着这不是第二个引导加载程序。

  4. 我一步一步地浏览了代码,我注意到扇区 3 中的标签到目前为止已经有 +512 字节了 我将

    org 0x8000
    更改为
    org 0x7e00
    。现在标签的偏移量已正确计算。

  5. search_file:
    中,我比较 10 个字节而不是 11 个字节,因为
    0
    将与
    eb
    进行比较,当然 这将是错误的。嗯,错误也很好,因为这样我就知道消息是正确生成的。 ;)

  6. 未显示错误消息,因为

    print proc
    位于未加载到内存的扇区2中。 我切换到第一个文件,并决定立即加载所有扇区。我内存中有内核和第二个引导程序。

  7. 如果找不到

    kernel_filename
    ,程序会打印
    kernel_not_found_message
    ,否则我们有代码 它还假设加载另一个扇区(8),这当然是不可用的。
    es = 0
    bx = 0
    dl = 0
    。从 fdd 读取到 IVT。这会产生错误
    ah = 20h
    , 文件共享违规。该程序返回后,我们有
    jmp 0x1000:0000
    。跳到虚无...

  8. 我假设扇区 2 是内核,所以我跳转到

    0:800a

  9. 好的,程序打印

    starting_message
    ,接下来我们读取了生成的扇区例程
    missing_pit
    ,分区表错误!,
    ah = 1
    ,无效的功能号。
    buffer db 16 dup(21)
    是 16字节,读扇区例程读取512字节。

  10. 我做了一些修改以使这段代码正常工作。 我在 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 sector 2 - bootloader stage 2
    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

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  
    cli

    system_stop:
        hlt
        jmp system_stop
    
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, 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 0x8c00

BITS 16

start:  
    mov si, actpart
    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

actpart:
    db "Active Partition loaded!", 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
© www.soinside.com 2019 - 2024. All rights reserved.