制作带MBR引导扇区的FAT分区:FAT16软盘镜像挂载失败求助
Let's break down why your floppy image isn't mounting as FAT16—there are a couple of critical structural issues in your BPB layout that are throwing off filesystem parsers:
1. Misaligned BPB Due to Short Jump Instruction
The FAT specification requires a 3-byte jump instruction at the start of the bootsector, followed immediately by the 8-byte OEM name at offset 0x003. Your code uses a 2-byte jmp short start, which shifts the entire BPB (and all subsequent fields) by 1 byte. Filesystem tools expect BPB fields at specific offsets, so this misalignment makes them read invalid values entirely.
Fix: Add a nop after the short jump to fill the 3-byte requirement:
BITS 16 jmp short start nop ; <-- Add this to make the jump instruction 3 bytes total iOEM db "ShapeOS" ; Now starts at offset 0x003, as required
2. Incorrect Volume Label Length
The acVolumeLabel field must be exactly 11 bytes long (padded with spaces if needed). Your current "MYVOLUME " only uses 9 bytes, which causes the following acFSType field to be misaligned. Parsers rely on these fixed-length fields to identify the filesystem type correctly.
Fix: Extend the volume label to 11 bytes:
acVolumeLabel db "MYVOLUME " ; 8 letters + 3 spaces = 11 bytes total
3. (Minor) Uninitialized Boot Drive Field
While this won't break mounting, you should capture the boot drive number from the DL register (BIOS passes this value to the bootloader on startup) to make your code more robust for real hardware:
start: cli mov [iBootDrive], dl ; Save BIOS-provided drive number mov ax, 0x07C0 ; ... rest of your setup code ...
Modified Working Bootsector Code
Here's the corrected version of your code with all fixes applied:
BITS 16 jmp short start nop ; Fix 1: 3-byte jump instruction 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 (number of entries) 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 " ; Fix 2: 11-byte volume label acFSType db "FAT16 " ; fs type (8 bytes) start: cli mov [iBootDrive], dl ; Fix 3: Capture boot drive number mov ax, 0x07C0 add ax, 288 mov ss, ax mov sp, 4096 mov ax, 0x07C0 mov ds, ax sti call clear_screen mov si, intro call puts16 mov si, loadmsg call puts16 mov si, failed call puts16 jmp $ intro db 'Shaper Bootloader, written by KingLuigi4932 and Kerndever', 0xD, 0xA, 0 loadmsg db 'Loading kernel... ', 0 failed db 'Failed!', 0xD, 0xA, 0 puts16: mov ah, 0Eh .repeat: lodsb cmp al, 0 je .done int 10h jmp .repeat .done: ret clear_screen: mov AX, 1003h mov BL, 00h int 10h ; Clear screen ;; Set mode to clear screen for all bioses mov AH, 00h int 10h ;; Fill screen with blue background mov AH, 09h mov AL, 20h mov BH, 00h mov BL, 1Eh mov CX, 2000h int 10h ret times 510-($-$$) db 0 dw 0xAA55
Testing the Fixed Image
Rebuild your bootloader and rewrite the image with your existing commands:
nasm -f bin bootloader.asm -o bootloader.bin dd if=/dev/zero of=fat.img bs=512 count=2880 dd status=noxfer conv=notrunc if=bootloader.bin of=fat.img
You should now be able to mount the image (e.g., with mount -o loop fat.img /mnt/floppy on Linux) as a valid FAT16 filesystem.
内容的提问来源于stack exchange,提问作者user8735693

