From 5f2ca55af737beba2821b615c2ce8c3dff6939a4 Mon Sep 17 00:00:00 2001 From: Elaina Claus Date: Thu, 18 Sep 2025 14:19:39 -0400 Subject: [PATCH] move mbr/vbr code to FAT32 system --- include/fat32/FAT32_SYS.nasm | 101 +++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/include/fat32/FAT32_SYS.nasm b/include/fat32/FAT32_SYS.nasm index 7200816..3ad47af 100644 --- a/include/fat32/FAT32_SYS.nasm +++ b/include/fat32/FAT32_SYS.nasm @@ -19,6 +19,107 @@ %include "fat32/bpb_offset_bx.inc" %include "fat32/fat32_structures.inc" +; int read_mbr(int boot_drive, void* dst) +; destination buffer needs 512 bytes of space +FAT32_load_mbr: + __CDECL16_PROC_ENTRY +.proc: + ; read mbr on boot drive to memory (for the partition table) + movzx ax, byte [bp + 4] + push ax ; drive_num (2) + push 0x01 ; count (2) + + push dword 0x0 ; lba (4) + + push word [bp + 6] ; offset = dst + push __STAGE2_SEGMENT ; this segment + call BIOS_int13h_ext_read + add sp, 0xC +.check_sig: + mov bx, [bp + 6] + cmp word [bx + 0x1FE], 0xAA55 ; check for bytes at end + jne ReadMbrData.error_nosign + ; TODO: this needs more error checking, zero checking, check the sig a bunch of stuff... +.endp: + __CDECL16_PROC_EXIT + ret +.error_nosign: + ERROR STAGE2_ERROR_BAD_MBR + +; int read_vbr(int boot_drive, void* buf) +; read vbr on boot partition to memory (for fat bpb/ebpb) +; TODO: seperate validation and loading the sector, just check the 0xAA55 at the end here... +FAT32_load_vbr: + __CDECL16_PROC_ENTRY +.proc: + mov bx, SteviaInfo + mov ax, word [bx + SteviaInfoStruct_t.p16_MbrPtr] + add ax, DISK_PARTITION_TABLE_OFFSET + mov bx, ax ; offset to part table + mov cx, 4 ; only checking 4 entries + +.find_active_L0: + mov al, [bx + PartEntry_t.attributes] + cmp al, 0x80 ; 0x80 == 1000_0000b + je ReadVbrData.check_fstype + add bx, PartEntry_t_size ; next part entry's attributes + loop ReadVbrData.find_active_L0 + jmp ReadVbrData.error_noactive +.check_fstype: + ; check for part_type = 0x0C (DOS 7.1+/W95 FAT32 w/ LBA) or 0x1C (Hidden 0x0C) + __BOCHS_MAGIC_DEBUG + mov al, [bx + PartEntry_t.part_type] + cmp al, 0x0C + je ReadVbrData.active_ok + ; *or* + cmp al, 0x1C + je ReadVbrData.active_ok + + jmp ReadVbrData.error_badparttype ; error if part_type != 0x1C or 0x0C +.active_ok: + movzx ax, byte [bp + 4] + push ax ; drive_num (2) + push 0x01 ; count (2) + + mov eax, dword [bx + PartEntry_t.lba_start] + push dword eax ; lba (4) + + push word [bp + 6] ; offset = dst + push __STAGE2_SEGMENT ; this segment + call BIOS_int13h_ext_read + add sp, 0xC + ; vbr (with fat bpb/ebpb) is at the buffer now +.check_sig: + mov bx, [bp + 6] + cmp word [bx + 0x1FE], 0xAA55 ; check for bytes at end + jne ReadVbrData.error_nosign +.check_FAT_sanity: + ; we only quickly validate that this is *probably* a FAT32 volume + + add bx, 11 ; point bx at start of bpb (skip jmp code and ident) + cmp word [bx + FAT32_bpb_t.u16_TotalSectors16], 0 ; TotalSectors16 should be 0 (use TotalSectors32 in bpb) + jne ReadVbrData.error_totsectors + + cmp word [bx + FAT32_bpb_t.u16_FATSize16], 0 ; FatSize16 will be 0 if FAT32 (use FATSize32 in ebpb) + jne ReadVbrData.error_fatsz + + cmp word [bx + FAT32_bpb_t.u16_RootEntryCount16], 0 ; root dir info is in data clusters on fat32 + jne ReadVbrData.error_rootdir +.endp: + __CDECL16_PROC_EXIT + ret +.error_noactive: + ERROR STAGE2_VBR_E_ACTIVE +.error_nosign: + ERROR STAGE2_VBR_E_SIGN +.error_totsectors: + ERROR STAGE2_VBR_E_TOT +.error_fatsz: + ERROR STAGE2_VBR_E_FATSZ +.error_rootdir: + ERROR STAGE2_VBR_E_DIRENT +.error_badparttype: + ERROR STAGE2_VBR_E_PARTTYPE ; what a 'mount' should probably do at this point... ; - read VBR at partition_lba