Assembly 使用引导扇区作为MBR创建FAT分区

Assembly 使用引导扇区作为MBR创建FAT分区,assembly,x86,osdev,fat,mbr,Assembly,X86,Osdev,Fat,Mbr,我正在帮助一位朋友为他的操作系统编写引导程序。我已经为他写了一个启动参数块。但是,当我使用DD将其刻录到1.44MiB软盘映像的第一个扇区时,它似乎是有效的,不能作为FAT16文件系统进行装载。但是,我看不出代码有任何真正的问题。在这里(评论也很好): 我用于将其放在软盘映像的第一个扇区上的命令有: dd if=/dev/zero of=fat.img bs=512 count=2880 然后: dd status=noxfer conv=notrunc if=bootloader.bin of

我正在帮助一位朋友为他的操作系统编写引导程序。我已经为他写了一个启动参数块。但是,当我使用DD将其刻录到1.44MiB软盘映像的第一个扇区时,它似乎是有效的,不能作为FAT16文件系统进行装载。但是,我看不出代码有任何真正的问题。在这里(评论也很好):

我用于将其放在软盘映像的第一个扇区上的命令有:

dd if=/dev/zero of=fat.img bs=512 count=2880

然后:

dd status=noxfer conv=notrunc if=bootloader.bin of=fat.img

谢谢

因为BPB中的所有内容都放错了位置

  • BIOS参数块必须在引导扇区内的偏移量3处开始。
    偏移量0处的跳转指令可以是近跳转(
    jmp-near-start
    )或短跳转,然后是填充
    nop
    指令(
    jmp-short-start

  • BPB包含3个字符串字段,您已将它们全部定义为短1个字符

    iOEM          db "ShapeOS "     ; Must have 8 characters!
    acVolumeLabel db "MYVOLUME   "  ; Must have 11 characters!
    acFSType      db "FAT16   "     ; Must have 8 characters!
    

考虑到引导扇区将位于内存中的线性地址7C00h处,并且您将
DS
段寄存器初始化为07C0h,最好将此代码与顶部的
ORG 0
指令组合在一起

ORG 0
BITS 16

jmp near start

iOEM          db "ShapeOS "
iSectSize     dw 0x200         ; bytes / sector
iClustSize    db 1             ; 1 sector per cluster (for simplicity)
iResCnt       dw 1             ; number of reserved sectors
iFatCnt       db 2             ; # of fat copies
iRootSize     dw 224           ; size of root dir
iTotalSect    dw 2880          ; total sectors
iMedia        db 0xF0          ; media descriptor
iFatSize      dw 9             ; size of each FAT
iTrackSect    dw 9             ; sectors per track
iHeadCnt      dw 2             ; number of r/w heads
iHiddentSect  dd 0             ; number of hidden sectors
iSect32       dd 0             ; number of > 32MB sectors
iBootDrive    db 0             ; holds drive of bootsector
iReserved     db 0             ; empty reserved attribute
iBootSign     db 0x29          ; extended bootsig
iVolID        db "seri"        ; disk serial
acVolumeLabel db "MYVOLUME   " ; volume label
acFSType      db "FAT16   "    ; fs type

start:

而且。。。您的实际文件分配表在哪里?扇区位图在哪里?根目录在哪里?仅仅因为第一个扇区存在并不意味着这是一个有效的FAT16文件系统。所有内容都在错误的位置,因为在跳转到BPB之后需要有一个NOP,
iSectSize
需要从偏移量0x0B开始,所以
iOEM
需要是8字节。如果在此之后仍然存在问题,则需要检查所有其他值,以确保它们的大小正确。创建引导扇区的可能重复不会自动为您提供可装载的文件系统。此外,您可能需要验证OEM节的长度是否正确。我不是说它不是,但是我没有看到任何东西来验证它的正确性。所有其他的评论都是有效的。要添加-1.44MB软盘的每个磁道为18个扇区,而不是9个扇区。格式化任何少于4085个群集的软盘都不是一个好主意。原因是,包括Windows在内的许多操作系统不是通过FSType字符串,而是通过集群的数量来确定FAT文件系统的类型。这一点在操作系统的磁盘格式概述中也有所体现。第15页讨论了FAT12/16/32的确定。对于2880个扇区(1.44MB软盘,每个磁道512个扇区)需要iTrackSect为18,才能使其成为正确的1.44MB软盘。过去有一些使用USB引导的神秘生物传感器,如果它找到的JMP不是
短JMP
(奇怪但真实),可能会拒绝引导。通常最好不要使用近跳。
ORG 0
BITS 16

jmp near start

iOEM          db "ShapeOS "
iSectSize     dw 0x200         ; bytes / sector
iClustSize    db 1             ; 1 sector per cluster (for simplicity)
iResCnt       dw 1             ; number of reserved sectors
iFatCnt       db 2             ; # of fat copies
iRootSize     dw 224           ; size of root dir
iTotalSect    dw 2880          ; total sectors
iMedia        db 0xF0          ; media descriptor
iFatSize      dw 9             ; size of each FAT
iTrackSect    dw 9             ; sectors per track
iHeadCnt      dw 2             ; number of r/w heads
iHiddentSect  dd 0             ; number of hidden sectors
iSect32       dd 0             ; number of > 32MB sectors
iBootDrive    db 0             ; holds drive of bootsector
iReserved     db 0             ; empty reserved attribute
iBootSign     db 0x29          ; extended bootsig
iVolID        db "seri"        ; disk serial
acVolumeLabel db "MYVOLUME   " ; volume label
acFSType      db "FAT16   "    ; fs type

start: