Better visualization of data formats using assembly POC's to better implement them in C
Are you tired of staring at hex dumps, white papers and manual pages? Want to feel like you truly know how a data type like a file format, or a disk partition LOOKS like. Well I can't help you with the manual pages and white papers, (https://staff.washington.edu/dittrich/misc/fatgen103.pdf, http://www.eit.lth.se/fileadmin/eit/courses/eitn50/Projekt1/FAT12Description.pdf) but here is a great example of implementing a fat12 floppy image in assembly.
;//////////////////////////////////////////////////////////////////////////////// ;// THE SCOTCH-WARE LICENSE (Revision 0): ;// <aaronryool@gmail.com> wrote this file. As long as you retain this notice you ;// can do whatever you want with this stuff. If we meet some day, and you think ;// this stuff is worth it, you can buy me a shot of scotch in return ;//////////////////////////////////////////////////////////////////////////////// ; This assembles to a floppy disk image [bits 16] [org 0x7C00] ;;;;;;;;;;;;;;;;;;;;;;;; ; BIOS Parameter Block jmp short boot_code nop db "MadOSv01" ; OEM identifier dw 512 ; Bytes per sector db 1 ; sectors per cluster dw 1 ; reserved sectors db 1 ; number of fats dw 112 ; directory entries dw 1280 ; logical sectors db 0xFB ; media descriptor type dw 1 ; sectors per fat, fat12/fat16 only dw 18 ; sectors per track dw 2 ; number of heads / sides on media dd 0 ; number of hidden sectors dd 0 ; Large amount of sector on media. This field is set if there are more than 65535 sectors in the volume. ; Extended Boot Record db 0 ; drive number db 0 ; reserved / NT flags (maybe use for MadOS, More research needed) db 0x29 ; signiture, 0x28 or 0x29 for fat12 /fat16 dd 0x1337 ; volume serial number db "MadOS Disk " ; volume label db "FAT12 " ; identifier string ; Boot code boot_code: xor ax, ax mov ds, ax mov es, ax mov ss, ax mov sp, boot_code_end + (1024 * 4) lea si, [message] call print_string jmp $ print_string: lodsb or al, al jz done mov ah, 0x0E int 0x10 jmp print_string done: ret message: db "MadOS disk not bootable...", 0xd, 0xa ;dw 0xAA55 ; bootable partition signiture, uncomment to make the floppy boot boot_code_end: times 450 - (boot_code_end - boot_code) db 0 ;;;;;;;;;;;;;;;;;;;;; ; DATA AREA START ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FAT entries ; an entry is 3 nibbles: ; 000 -> unused ; 0xFF0-0xFF6 -> reserved cluster ; 0xFF7 -> bad cluster ; 0xFF8-0xFFF -> last cluster in file ; *** -> next data cluster fat1: db 0xFB, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0x00, 0x00 ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 times 512 - ($ - fat1) db 0 fat2: times 512 - ($ - fat2) db 0 ;;;;;;;;;;;;;;;;;; ; root directory root: folder: db "folder " db 0x20 | 0x10 ; attributes: a, d dw 0 ; reserved dw 0xA496 ; creation time (h,m,s) dw 0x4793 ; creation date dw 0x4793 ; access date dw 0 ; high order bits of first cluster address, 0 on fat12 dw 0xA496 ; write time (h,m,s) dw 0x4793 ; write date dw 3 ; low order bits of first cluster address dd 64 ; file size file: db "file " db 0x20 ; attributes: a dw 0 ; reserved dw 0xA496 ; creation time (h,m,s) dw 0x4793 ; creation date dw 0x4793 ; access date dw 0 ; high order bits of first cluster address, 0 on fat12 dw 0xA496 ; write time (h,m,s) dw 0x4793 ; write date dw 2 ; low order bits of first cluster address dd 40 ; file size ; padd out the rest of the root directory times (512 * 4) - ($ - root) db 0 times 1024 db 0 ; first two data blocks are reserved ; 2 file file_data: db "This is a file in the root directory :D", 0xa ; cluster padding times 512 - ($ - file_data) db 0 ; 3 folder folder_data: file2: db "file2 " db 0x20 ; attributes: a dw 0 ; reserved dw 0xA496 ; creation time (h,m,s) dw 0x4793 ; creation date dw 0x4793 ; access date dw 0 ; high order bits of first cluster address, 0 on fat12 dw 0xA496 ; write time (h,m,s) dw 0x4793 ; write date dw 4 ; low order bits of first cluster address dd 34 ; file size folder2: db "folder2 " db 0x20 | 0x10 ; attributes: a, d dw 0 ; reserved dw 0xA496 ; creation time (h,m,s) dw 0x4793 ; creation date dw 0x4793 ; access date dw 0 ; high order bits of first cluster address, 0 on fat12 dw 0xA496 ; write time (h,m,s) dw 0x4793 ; write date dw 5 ; low order bits of first cluster address dd 32 ; file size ; cluster padding times 512 - ($ - file2) db 0 ; 4 file2 file2_data: db "This is a file in a sub directory", 0xa ; cluster padding times 512 - ($ - file2_data) db 0 ; 5 folder2_data folder2_data: file3: db "file3 " db 0x20 ; attributes: a dw 0 ; reserved dw 0xA496 ; creation time (h,m,s) dw 0x4793 ; creation date dw 0x4793 ; access date dw 0 ; high order bits of first cluster address, 0 on fat12 dw 0xA496 ; write time (h,m,s) dw 0x4793 ; write date dw 6 ; low order bits of first cluster address dd 1024 ; file size ; cluster padding times 512 - ($ - folder2_data) db 0 ; 6 file3_data file3_data: times 512 - ($ - file3_data) db 'A' ; 7 file3_data2 file3_data2: times 512 - ($ - file3_data2) db 'B' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; padd out the rest of the floppy times ((1024 * 1024) + 461373) - ($ - $$) db 0
So from this exploration, we can construct the following header file as a start:
//////////////////////////////////////////////////////////////////////////////// // THE SCOTCH-WARE LICENSE (Revision 0): // wrote this file. As long as you retain this notice you // can do whatever you want with this stuff. If we meet some day, and you think // this stuff is worth it, you can buy me a shot of scotch in return //////////////////////////////////////////////////////////////////////////////// #ifndef __FAT_H__ #define __FAT_H__ #include <stdint.h> #include <machine.h> typedef struct bpb { char jmp_code[3]; char oem[8]; uint16_t bytes_per_sector; uint8_t sectors_per_cluster; uint16_t reserved_sectors; uint8_t fats; uint16_t dir_entries; uint16_t logical_sectors; uint8_t media_type; uint16_t sectors_per_fat; uint16_t sectors_per_track; uint16_t heads; uint32_t hidden_sectors; uint32_t large_sectors; } bpb_t; typedef struct ebr { uint8_t drive; uint8_t rflags; uint8_t signiture; uint32_t serial; char label[11]; char identifier[8]; char boot_code[448]; uint16_t boot_sign; } ebr_t; typedef struct fat12_partition_info { // see fat12.s for an implementation // in assembly for visualization :D bpb_t bpb; ebr_t ebr; char data[]; } fat12_partition_info_t; typedef struct fat_dir_entry { char name[11]; uint8_t attributes; uint16_t reserved; uint16_t creation_time; uint16_t creation_date; uint16_t access_date; uint16_t caddr_high; uint16_t write_time; uint16_t write_date; uint16_t caddr_low; uint32_t size; } fat_dir_entry_t; const uint8_t fat12_format_stub[122] = { 0xEB, 0x3C, 0x90, 0x4D, 0x61, 0x64, 0x4F, 0x53, 0x76, 0x30, 0x31, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x37, 0x13, 0x00, 0x00, 0x4D, 0x61, 0x64, 0x4F, 0x53, 0x20, 0x44, 0x69, 0x73, 0x6B, 0x20, 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x31, 0xC0, 0x8E, 0xD8, 0x8E, 0xC0, 0x8E, 0xD0, 0xBC, 0x7A, 0x8C, 0x8D, 0x36, 0x5E, 0x7C, 0xE8, 0x02, 0x00, 0xEB, 0xFE, 0xAC, 0x08, 0xC0, 0x74, 0x06, 0xB4, 0x0E, 0xCD, 0x10, 0xEB, 0xF5, 0xC3, 0x4D, 0x61, 0x64, 0x4F, 0x53, 0x20, 0x64, 0x69, 0x73, 0x6B, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x62, 0x6F, 0x6F, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x2E, 0x2E, 0x2E, 0x0D, 0x0A }; ///////////////////////////////////////////// // FAT12 entries // ///////////////////////////////////////////// // an entry is 3 nibbles: // // 000 -> unused // // 0xFF0-0xFF6 -> reserved cluster // // 0xFF7 -> bad cluster // // 0xFF8-0xFFF -> last cluster in file // // *** -> next data cluster // ///////////////////////////////////////////// typedef char fat12_t[]; #define GET_FAT12_ENTRY(n, fat)\ (n % 2 == 0 ? fat[((3 * n) / 2)] | (fat[1 + (3 * n) / 2] & 0x0F) << 8 : \ (fat[(3 * n) / 2] & 0xF0) >> 4 | fat[1 + (3 * n) / 2] << 4) #endif
I have an emulator program that emulates an iphone or android cellphone. Does compiling the assembly code above provide my computer with a "virtual fat12 floppy image"? Also, why fat12 and not any of the other disk formats?
ReplyDelete