本文介绍了最简单的链式加载启动管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了从闪存驱动器启动,我们在实模式下使用BIOS中断13h加载磁盘,并指定了磁盘0x80.如此链接

In order to boot from flash memory drive we load disks using the BIOS interrupt 13h in real mode with specifying the disk 0x80. Another disks should be accessed by 0x81, 0x82... as mentioned over this link

我正在尝试制作简单的GRUB .

我的第一步是从闪存驱动器启动(将MBR加载到0x7C00并打印一条消息,作为正确启动的证明)并读取我的主HDD(我假设它的编号为0x81,并且前15个扇区需要重新启动)再次进入0x7C00.

My very first step is to boot from flash memory drive (Load MBR into 0x7C00 and print a message as a proof of correct boot) and read the my main HDD (which I assume it is numbered 0x81 and that the first 15 sectors are needed for booting) again into 0x7C00.

我想这个天真的主意应该让我进入主硬盘的引导加载程序,但这不是预期的.你能告诉我出什么问题了吗.

I suppose that this naive idea should drop me into my main HDD's bootloader, but it is not as expected. Would you please tell me what is wrong.

顺便问一下,我应该如何获得HDD的数量?

By the way, how should I get the numbers of HDDs?

请注意,我的主硬盘包含带有多个操作系统的grub2.

Please note that my main HDD contains grub2 with several operating systems.

对我来说,这是一个理论上的问题,但是由于注释的要求,我添加了代码.

For me this is a theoretical question, but I added the code due to a request in comments.

bootloader.asm:

[bits 16]
[org 0x7C00]

; The bootloader is in charge of writing BPB into MBR in addition to installing this code.
; Then a second sector is written to the drive, this is where the FAT is allocated.
LOADER_OFFSET equ 0x1000

jmp short main
nop
%include "ASM/BPB.asm"

main:
    xor ax, ax
    mov ds, ax
    mov es, ax

    ; Save the boot drive. Basically it should be 0x80
    mov [BOOT_DRIVE], dl
    mov ax, 0x0000                  ; End of stack

    ; Lock and create stack
    cli
    mov ss, ax
    mov sp, 0x0000
    sti

    mov     ah, 0x0e
    mov al, 'X'
    int 0x10

    ; Load the second sector into memory at LOADER_OFFSET
    mov bx, LOADER_OFFSET
    mov al, 1
    mov cl , 0x02
    mov dl, [BOOT_DRIVE]
    call    disk_load

    ; Call the loader using segmentation
    jmp 0x0000:LOADER_OFFSET

; Global variables
BOOT_DRIVE  db 0

%include "ASM/disk_load.asm"

; Bootsector padding
times 510-($-$$) db 0
dw 0xAA55

第二阶段bootloader- loader.asm:

[bits 16]
[org 0x1000]

KERNEL_OFFSET equ 0x7C00

_start:

    xor ax, ax
    xor bx, bx

    mov     ah, 0x0e
    mov al, 'Y'
    int 0x10

    mov bx, KERNEL_OFFSET   
    mov al, 15
    mov dl , 0x81
    mov cl , 0x01
    call    disk_load

    jmp 0x7C0:0000

%include "ASM/disk_load.asm"

times 512-($-$$) db 0

BPB.asm:

BPB:
    iOEM        db  "mkfs.fat"              ; 0x03 ; OEM String
    iSectSize   dw  512                 ; 0x0B ; Bytes per sector
    iClustSize  db  0x40                    ; 0x0D ; Sectors per cluster
    iResSect    dw  0x1                 ; 0x0E ; # of reserved sectors. For now, it should be 1 
                                    ; 0x0E ; unless we need more space to write the bootstrap
                                    ; 0x0E ; sector
    iFatCnt     db  2                   ; 0x10 ; # of fat copies
    iRootSize   dw  1024                    ; 0x11 ; size of root directory
    iTotalSect  dw  0                   ; 0x13 ; total #of sectors if below 32 MB
    iMedia      db  0xF8                    ; 0x15 ; Media Descriptor
    iFatSize    dw  256                 ; 0x16 ; Size of each FAT
    iTrackSect  dw  62                  ; 0x18 ; Sectors per track
    iHeadCnt    dw  63                  ; 0x1A ; number of read-write heads
    iHiddenSect dd  0                   ; 0x1C ; number of hidden sectors
    iSect32     dd  0x003c3000              ; 0x20 ; # of sectors if over 32 MB



EBPB:
    iBootDrive  db  80                  ; 0x24 ; holds drive that the boot sector came from
    iReserved   db  0                   ; 0x25 ; reserved, empty
    iBootSign   db  0x29                    ; 0x26 ; extended boot sector signature
    iVolID      dd  0xA8B531B1              ; 0x27 ; disk serial
    acVolLabel  db  "BIOSver", 0x20, 0x20, 0x20, 0x20   ; 0x2B ; just placeholder. We don't yet use volume labels.
    acFSType    db  "FAT16", 0x20, 0x20, 0x20       ; 0x36 ; file system type

disk_load.asm:

disk_load:
    push dx
    mov ah , 0x02
    mov ch , 0x00
    mov dh , 0x00
    int 0x13
    jc disk_error
    pop dx
    ret

disk_error:
    pop si
    pop ax
    pop cx
    pop dx
    jmp $

; Variables
SECTORS     db 0

制作文件:

ASFLAGS=-g3

all: os.img

os.img: bootloader.bin loader.bin
    cat bin/bootloader.bin bin/loader.bin > bin/os.img


bootloader.bin: ASM/bootloader.asm
    nasm $(ASFLAGS) $^ -f bin -o bin/$@

loader.bin: ASM/loader.asm
    nasm $(ASFLAGS) $^ -f bin -o bin/$@

clean:
    rm -f bin/*.* bin/* os.img

此代码应在屏幕上显示XY,然后将控制权传递给HDD的引导程序.但是我得到的只是XY打印在屏幕上.

This code should print XY to screen and then pass control to the HDD's bootsector. But what I am getting is just XY printed to the screen.

推荐答案

回答我自己的问题,灵感来自于Micheal Petch的上述评论:主要有两个问题:1.使用模拟器并不一定意味着所有驱动器都已加载,这是我的情况2.使用jmp 0x100:0000将磁盘扇区加载到0x0000:0x1000.

Answering my own question inspired from the above comments from Micheal Petch:There are mainly two problems:1. Using emulator does not necessarily means that all drives are loaded which was my case2. Loading the disk sectors to 0x0000:0x1000 with jmp 0x100:0000.

此外,如 rufus 代码(即闪存到0x81,主硬盘到0x80).

In addition, chainloading requires overwriting interrupt 13 to re-arrange the numbers of boot devices as explained in rufus code (i.e. Flash memory to 0x81 and main HDD to 0x80).

这篇关于最简单的链式加载启动管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-10 07:40