gpt4 book ai didi

assembly - 最简单的链式加载引导管理器

转载 作者:行者123 更新时间:2023-12-02 01:15:40 26 4
gpt4 key购买 nike

为了从闪存驱动器启动,我们在实模式下使用 BIOS 中断 13h 加载磁盘并指定磁盘 0x80。另一个磁盘应该由 0x81、0x82... 访问,如 this link 中所述

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

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

我想这个天真的想法应该让我进入我的主硬盘的引导加载程序,但它并不像预期的那样。你能告诉我哪里出了问题吗?

顺便问一下,我应该如何获取硬盘的数量?

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

编辑:对我来说这是一个理论问题,但由于评论中的要求,我添加了代码。

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

第二阶段引导加载程序-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

磁盘加载.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 打印到屏幕上。

最佳答案

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

此外,链式加载需要覆盖中断 13 以重新安排启动设备的数量,如 rufus 中所述。代码(即闪存到 0x81,主硬盘到 0x80)。

关于assembly - 最简单的链式加载引导管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42790410/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com