Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a FAT partition with a bootsector as an MBR

I am helping a friend write a bootloader for his operating system. I have gotten as far as writing a boot parameter block for him. It seems valid, however, when I use DD to burn it to the 1st sector of a 1.44MiB floppy disk image, it is not mountable as a FAT16 filesystem. I do not see any real issue with the code however. Here it is (it is quite well commented too):

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

The commands I use to put this on the first sector of a floppy disk image are:

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

And then:

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

Thanks!


1 Answers

As commented by Shift_Left everything in your BPB is in the wrong place.

  • The BIOS Parameter Block must start at offset 3 within the Boot Sector.
    The jump instruction at offset 0 can be a near jump (jmp near start) or a short jump followed by a padding nop instruction (jmp short start nop).

  • The BPB contains 3 string fields and you've defined them all 1 character short!

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

Given that the Boot Sector will sit in memory at linear address 7C00h and that you initialize the DS segment register to 07C0h, it will be best to assemble this code with an ORG 0 directive on top.

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:
like image 102
Sep Roland Avatar answered Nov 29 '25 16:11

Sep Roland