【问题标题】:Creating a FAT partition with a bootsector as an MBR使用引导扇区作为 MBR 创建 FAT 分区
【发布时间】:2018-07-05 23:37:48
【问题描述】:

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

BITS 16

jmp short 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:
    cli
    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

我用来把它放在软盘映像的第一个扇区的命令是:

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

然后:

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

谢谢!

【问题讨论】:

  • 还有...您的实际文件分配表在哪里?扇区位图在哪里?根目录在哪里?仅仅因为第一个扇区存在并不意味着这是一个有效的 FAT16 文件系统。
  • 一切都在错误的地方,因为在跳过 BPB 后需要有一个 NOP 并且iSectSize 需要从偏移量 0x0B 开始,所以iOEM 需要是 8 个字节。如果之后仍有问题,则需要检查所有其他值以确保它们的大小正确。
  • FAT 12 Implementation的可能重复
  • 创建引导扇区不会自动为您提供可挂载的文件系统。此外,您可能想要验证您的 OEM 部分的长度字节数是否正确。我不是说它不是,但我没有看到任何东西可以验证它是正确的。
  • 其他所有cmets都有效。想要添加 - 一张 1.44MB 的软盘是每个磁道 18 个扇区而不是 9 个扇区。格式化任何少于 4085 个簇的软盘是个坏主意。原因是包括 Windows 在内的许多操作系统不是通过 FSType 字符串,而是通过簇的数量来确定 FAT 文件系统的类型。这也在staff.washington.edu/dittrich/misc/fatgen103.pdf对其操作系统的磁盘格式的一般概述中有所体现。第 15 页讨论 FAT12/16/32 的确定。

标签: assembly x86 osdev fat mbr


【解决方案1】:

作为commented by Shift_Left,您的 BPB 中的所有内容都在错误的位置。

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

  • 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:

【讨论】:

  • 对于 2880 个扇区(1.44MB 软盘,每个磁道 512 个扇区)需要 iTrackSect 为 18 才能成为合适的 1.44MB 软盘。如果它找到的 JMP 不是 short jmp.(奇怪但真实),曾经有一些带有 USB 引导的深奥 BIOS 可能会拒绝引导它。通常最好不要使用近跳。
猜你喜欢
  • 2017-06-12
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 2016-02-15
  • 1970-01-01
  • 2017-03-27
  • 1970-01-01
  • 2013-07-16
相关资源
最近更新 更多