【发布时间】:2018-01-08 03:33:13
【问题描述】:
我正在编写一个第 1 阶段的程序集引导加载程序,我试图将 FAT12 文件系统加载到内存中,以便我可以加载我的第 2 阶段引导加载程序。我已经设法将 FAT 加载到内存中,但是我正在努力将根目录加载到内存中。
我目前正在使用this 作为参考,并制作了以下内容:
.load_root:
;es is 0x7c0
xor dx, dx ; blank dx for division
mov si, fat_loaded ; inform user that FAT is loaded
call print
mov al, [FATcount] ; calculate how many sectors into the disk must be loaded
mul word [SectorsPerFAT]
add al, [ReservedSectors]
div byte [SectorsPerTrack]
mov ch, ah ; Store quotient in ch for cylinder number
mov cl, al ; Store remainder in cl for sector number
xor dx, dx
xor ax, ax
mov al, ch ; get back to "absolute" sector number
mul byte [SectorsPerTrack]
add al, cl
mul word [BytesPerSector]
mov bx,ax ; Memory offset to load to data into memory after BOTH FATs (should be 0x2600, physical address should be 0xA200)
xor dx, dx ; blank dx for division
mov ax, 32
mul word [MaxDirEntries]
div word [BytesPerSector] ; number of sectors root directory takes up (should be 14)
xor dh, dh ; head 0
mov dl, [boot_device] ; boot device
mov ah, 0x02 ; select read mode
int 13h
cmp ah, 0
je .load_OS
mov si, error_text
call print
jmp $
但是,如果我使用 gdb 检查0xA200 的内存,我只会看到 0。我的根目录确实包含一个文件——我在根目录中放置了一个名为 OS.BIN 的文件进行测试。
在读取操作后在 gdb 中使用 info registers 会得到以下输出:
eax 0xe 14
ecx 0x101 257
edx 0x0 0
ebx 0x2600 9728
esp 0x76d0 0x76d0
ebp 0x0 0x0
esi 0x16d 365
edi 0x0 0
eip 0x7cdd 0x7cdd
eflags 0x246 [ PF ZF IF ]
cs 0x0 0
ss 0x53 83
ds 0x7c0 1984
es 0x7c0 1984
fs 0x0 0
gs 0x0 0
操作状态为 0,读取的扇区数为 14,es:bx 指向 0xA200,但x/32b 0xa200 显示 32 个 0,我希望看到 OS.BIN 的数据。
编辑
我在中断之前做了info registers,输出如下:
eax 0x20e 526
ecx 0x101 257
edx 0x0 0
ebx 0x2600 9728
esp 0x76d0 0x76d0
ebp 0x0 0x0
esi 0x161 353
edi 0x0 0
eip 0x7cc8 0x7cc8
eflags 0x246 [ PF ZF IF ]
cs 0x0 0
ss 0x53 83
ds 0x7c0 1984
es 0x7c0 1984
fs 0x0 0
gs 0x0 0
和后面一样,只是函数请求号被状态码代替了。
我哪里错了?我是否从错误的 CHS 地址读取?还是其他一些简单的错误?我该如何纠正这个问题?
我正在使用fat_imgen 制作我的磁盘映像。创建磁盘镜像的命令是fat_imgen -c -f floppy.flp -F -s bootloader.bin,添加OS.BIN到镜像的命令是fat_imgen -m -f floppy.flp -i OS.BIN
我有一个BIOS Parameter Block (BPB),它表示使用 FAT12 的 1.44MB 软盘:
jmp short loader
times 9 db 0
BytesPerSector: dw 512
SectorsPerCluster: db 1
ReservedSectors: dw 1
FATcount: db 2
MaxDirEntries: dw 224
TotalSectors: dw 2880
db 0
SectorsPerFAT: dw 9
SectorsPerTrack: dw 18
NumberOfHeads: dw 2
dd 0
dd 0
dw 0
BootSignature: db 0x29
VolumeID: dd 77
VolumeLabel: db "Bum'dOS ",0
FSType: db "FAT12 "
我有另一个似乎可以工作的函数,它将 FAT12 表加载到内存地址 0x7c0:0x0200(物理地址 0x07e00):
;;;Start loading File Allocation Table (FAT)
.load_fat:
mov ax, 0x07c0 ; address from start of programs
mov es, ax
mov ah, 0x02 ; set to read
mov al, [SectorsPerFAT] ; how many sectors to load
xor ch, ch ; cylinder 0
mov cl, [ReservedSectors] ; Load FAT1
add cl, byte 1
xor dh, dh ; head 0
mov bx, 0x0200 ; read data to 512B after start of code
int 13h
cmp ah, 0
je .load_root
mov si, error_text
call print
hlt
【问题讨论】:
-
请提供minimal reproducible example。此外,使用调试器验证磁盘读取的输入参数。
-
@Jester 我认为我不能进一步减少代码——这部分没有按预期工作,但我不知道为什么。如果您需要任何具体的附加信息,我可以提供,但目前我不知道要添加(或删除)什么。
-
这不完整。我无法运行它。它缺少测试它所需的所有其他代码,缺少用于创建磁盘映像或映像本身的命令。喝完咖啡会看看你的注册更新:)
-
@Jester 啊,好的。我会在几个滴答声中将它的当前状态推送到一个新的 git 分支并给你链接。
-
@WORD_559 不要只给我们链接,在问题中发布任何需要的内容。
标签: assembly x86 nasm bootloader fat