Search code examples
assemblyx86-16bootloaderdisk-partitioningfat32

Disk image appears non-bootable when specifying a partition table in an MBR


I recently added a FAT32 partition table to my bootloader and now BIOS won't recognize it as a bootable MBR. I believe the binary is 512 Bytes and there is a valid signature. Is it something wrong with the "TIMES 499" or something else?

[BITS 16]
[ORG 0x7c00]

mov ah, 0x0e        ; Starts TTY mode to display booting message
mov al, 'L'
int 0x10
mov al, 'o'
int 0x10
mov al, 'a'
int 0x10
mov al, 'd'
int 0x10
mov al, 'i'
int 0x10
mov al, 'n'
int 0x10
mov al, 'g'
int 0x10
mov al, '.'
int 0x10
int 0x10
int 0x10

TIMES 499 - ($ - $$) DB 0 ; Zerofill

; ------------- Partition Table

; Partition #1
DQ 0x00000000
DB 0x0c ; Type Code
DW 0x0000
DB 0x00
DQ 0x000003E8 ; LBA Begin
DQ 0x000186A0 ; # of Sectors

; Partition #2
DQ 0x00000000
DB 0x0c ; Type Code
DW 0x0000
DB 0x00
DQ 0x00018A88 ; LBA Begin
DQ 0x000186A0 ; # of Sectors

; Partition #3
DQ 0x00000000
DB 0x0c ; Type Code
DW 0x0000
DB 0x00
DQ 0x00031128 ; LBA Begin
DQ 0x000186A0 ; # of Sectors

; Partition #4
DQ 0x00000000
DB 0x0c ; Type Code
DW 0x0000
DB 0x00
DQ 0x000497C8 ; LBA Begin
DQ 0x000186A0 ; # of Sectors

; ------------- End Partition Table

DW 0xAA55 ; MBR Signature

I expected "Loading..." but instead got "No Bootable Device."


Solution

  • @Jester is correct that the partition table entries should start at byte 446 and not 499 and your partition entries are greater than 16 bytes each. As a result your MBR is larger than 512 bytes and the 0xaa55 disk signature isn't in the last 2 bytes so the machine doesn't see this as bootable media.

    The partition table must be 64 bytes in size. 446+64(partition table size)+2(boot signature)=512. They layout of each partition entry is:

    enter image description here

    It is unclear where you got the layout for your partition entries but the MBR should have looked like this given what appear to be the entries you were trying to generate:

    [BITS 16]
    [ORG 0x7c00]
    
    mov ah, 0x0e        ; Starts TTY mode to display booting message
    mov al, 'L'
    int 0x10
    mov al, 'o'
    int 0x10
    mov al, 'a'
    int 0x10
    mov al, 'd'
    int 0x10
    mov al, 'i'
    int 0x10
    mov al, 'n'
    int 0x10
    mov al, 'g'
    int 0x10
    mov al, '.'
    int 0x10
    int 0x10
    int 0x10
    jmp $                  ; End with an infinite loop
    
    TIMES 446 - ($ - $$) DB 0 ; Zerofill
    
    ; ------------- Partition Table
    
    ; Partition #1
    DB 0x00                ; Status (bootable?)
    DB 0x00, 0x00, 0x00    ; CHS Start
    DB 0x0c                ; Type Code
    DB 0x00, 0x00, 0x00    ; CHS End
    DD 0x000003E8          ; LBA Begin
    DD 0x000186A0          ; # of Sectors
    
    ; Partition #2
    DB 0x00                ; Status (bootable?)
    DB 0x00, 0x00, 0x00    ; CHS Start
    DB 0x0c                ; Type Code
    DB 0x00, 0x00, 0x00    ; CHS End
    DD 0x00018A88          ; LBA Begin
    DD 0x000186A0          ; # of Sectors
    
    ; Partition #3
    DB 0x00                ; Status (bootable?)
    DB 0x00, 0x00, 0x00    ; CHS Start
    DB 0x0c                ; Type Code
    DB 0x00, 0x00, 0x00    ; CHS End
    DD 0x00031128          ; LBA Begin
    DD 0x000186A0          ; # of Sectors
    
    ; Partition #4
    DB 0x00                ; Status (bootable?)
    DB 0x00, 0x00, 0x00    ; CHS Start
    DB 0x0c                ; Type Code
    DB 0x00, 0x00, 0x00    ; CHS End
    DD 0x000497C8          ; LBA Begin
    DD 0x000186A0          ; # of Sectors
    
    ; ------------- End Partition Table
    
    DW 0xAA55 ; MBR Signature
    

    When I run SFDISK on the disk image file with:

    sfdisk disk.img
    

    I get these partition entries listed:

    Device     Boot  Start    End Sectors  Size Id Type
    disk.img1         1000 100999  100000 48.8M  c W95 FAT32 (LBA)
    disk.img2       101000 200999  100000 48.8M  c W95 FAT32 (LBA)
    disk.img3       201000 300999  100000 48.8M  c W95 FAT32 (LBA)
    disk.img4       301000 400999  100000 48.8M  c W95 FAT32 (LBA)
    

    Booting it in QEMU with the disk image as hard drive A using:

    qemu-system-i386 -hda disk.img
    

    I get this on the display:

    enter image description here