DF-3128 / craftvar.c
/* * DF-3128 bisect tool: FAT32 image crafter with per-field overrides. * usage: ./craftvar <variant> <out.img> * b = baseline crafted (BytesPerSec=512 SecPerClust=1 Res=1 FATs=1 * RootDirEnts=0 Sectors=0 Media=0xF8 FATsecs16=0 * Huge=0xC0000000 BigFAT=0x100 Ext=0x0080 FSVers=0 RootClust=2 * FSInfo=0 Backup=0), 512 MiB sparse device * f2 = b + FATs=2 * r32 = b + ResSectors=32 * fi = b + FSInfo=1 Backup=2 * md = b + Media=0xF0 (FAT[0]=0x0FFFFFF0) * all = all of the above * ex = all + ExtFlags=0 * st = all + SecPerTrack=32 Heads=64 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <fcntl.h> #include <unistd.h> static uint8_t bs[512]; static void w16(uint8_t *p, uint16_t v) { p[0] = v; p[1] = v >> 8; } static void w32(uint8_t *p, uint32_t v) { w16(p, v); w16(p + 2, v >> 16); } int main(int argc, char **argv) { const char *v; uint8_t fat[8]; uint32_t res = 1, fat0; uint8_t fats = 1, media = 0xF8; uint16_t fsinfo = 0, backup = 0, ext = 0x0080, spt = 63, heads = 255; uint64_t devsz = 512LL * 1024 * 1024; int fd; if (argc != 3) { fprintf(stderr, "usage: %s variant out.img\n", argv[0]); return 1; } v = argv[1]; if (strchr(v, '2')) fats = 2; if (strchr(v, 'r')) res = 32; if (strchr(v, 'i')) { fsinfo = 1; backup = 2; } if (strchr(v, 'm')) media = 0xF0; if (strchr(v, 'e')) ext = 0; if (strchr(v, 't')) { spt = 32; heads = 64; } memset(bs, 0, sizeof(bs)); bs[0] = 0xEB; bs[1] = 0x3C; bs[2] = 0x90; memcpy(bs + 3, "DF3128 ", 8); w16(bs + 11, 512); bs[13] = 1; w16(bs + 14, res); bs[16] = fats; w16(bs + 17, 0); /* FAT32 */ w16(bs + 19, 0); bs[21] = media; w16(bs + 22, 0); w16(bs + 24, spt); w16(bs + 26, heads); w32(bs + 28, 0); w32(bs + 32, 0xC0000000u); /* claim 1.5 TiB */ w32(bs + 36, 0x00000100u); /* 128 KiB FAT */ w16(bs + 40, ext); w16(bs + 42, 0); w32(bs + 44, 2); w16(bs + 48, fsinfo); w16(bs + 50, backup); bs[510] = 0x55; bs[511] = 0xAA; fat0 = 0x0FFFFFFFu & 0xFFFFFF00u; fat0 |= media; /* media-ID word */ w32(fat + 0, fat0); w32(fat + 4, 0x0FFFFFFFu); fd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd < 0) { perror("open"); return 1; } if (ftruncate(fd, devsz)) { perror("ftruncate"); return 1; } if (pwrite(fd, bs, 512, 0) != 512) { perror("pwrite bs"); return 1; } if (pwrite(fd, fat, 8, (uint64_t)res * 512) != 8) { perror("pwrite fat"); return 1; } close(fd); printf("%s: res=%u fats=%u media=%#x fat0=%#010x fsinfo=%u backup=%u ext=%#x spt=%u heads=%u\n", v, (unsigned)res, fats, media, fat0, fsinfo, backup, ext, spt, heads); return 0; } |