DF-2831 / genimg2831.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | /* * DF-2831 image generator: 8 MiB MBR disk, one DFLYBSD slice s1 at LBA 128 * (8000 sectors) containing a VALID disklabel64 with partition 'a' * (p_boffset 64 KiB, p_bsize 2 MiB, fstype FS_SWAP) so /dev/vnXs1a exists * and swapon(2) exercises dssize() -> op_getpartbounds() label walk. * * On-disk layout per sys/sys/disklabel64.h: * [512 reserved][magic I][crc I][align I][nparts I][stor_uuid 16] * [total_size Q][bbase Q][pbase Q][pstop Q][abase Q] * [packname 64][reserved 64][partition64 x 16 (64 bytes each)] */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define SECT 512 #define NSLICE1 128 /* s1 start LBA */ #define SSLICE1 8000 /* s1 size in sectors */ #define NPARTS 16 static uint32_t crc32_buf(const unsigned char *b, size_t n) { /* reflected crc32, poly 0xedb88320, init/final xor 0xffffffff */ static uint32_t tab[256]; static int init; uint32_t c; size_t i; int k; if (!init) { for (i = 0; i < 256; i++) { c = i; for (k = 0; k < 8; k++) c = (c & 1) ? 0xedb88320U ^ (c >> 1) : c >> 1; tab[i] = c; } init = 1; } c = 0xffffffffU; for (i = 0; i < n; i++) c = tab[(c ^ b[i]) & 0xff] ^ (c >> 8); return c ^ 0xffffffffU; } int main(int argc, char **argv) { const char *path = argc > 1 ? argv[1] : "/root/df2831.img"; uint64_t psize_a = argc > 2 ? strtoull(argv[2], NULL, 0) : 2UL * 1024 * 1024; size_t nsec = 16384; /* 8 MiB */ size_t sl_bytes = SSLICE1 * SECT; unsigned char *img; unsigned char *lab; size_t off_magic, off_end, base; uint32_t c; FILE *f; img = calloc(1, nsec * SECT); /* protective MBR: one DFLYBSD (0x6C) slice */ img[446 + 4] = 0x6C; img[446 + 8] = NSLICE1 & 0xff; img[446 + 9] = (NSLICE1 >> 8) & 0xff; img[446 + 10] = (NSLICE1 >> 16) & 0xff; img[446 + 11] = (NSLICE1 >> 24) & 0xff; img[446 + 12] = SSLICE1 & 0xff; img[446 + 13] = (SSLICE1 >> 8) & 0xff; img[446 + 14] = (SSLICE1 >> 16) & 0xff; img[446 + 15] = (SSLICE1 >> 24) & 0xff; img[510] = 0x55; img[511] = 0xAA; lab = calloc(1, 512 + 16 + 16 + 40 + 64 + 64 + NPARTS * 64); off_magic = 512; /* d_magic */ *(uint32_t *)(lab + off_magic) = 0xc4464c59U; /* d_align */ *(uint32_t *)(lab + off_magic + 8) = 512; /* d_npartitions */ *(uint32_t *)(lab + off_magic + 12) = NPARTS; /* d_stor_uuid */ memset(lab + off_magic + 16, 0x33, 16); /* d_total_size, d_bbase, d_pbase, d_pstop, d_abase */ *(uint64_t *)(lab + off_magic + 32) = sl_bytes; *(uint64_t *)(lab + off_magic + 32 + 8) = 4096; /* bbase */ *(uint64_t *)(lab + off_magic + 32 + 16) = 65536; /* pbase */ *(uint64_t *)(lab + off_magic + 32 + 24) = sl_bytes - 4096; /* pstop */ *(uint64_t *)(lab + off_magic + 32 + 32) = 0; /* abase */ /* d_packname at 512+16+16+40 */ strcpy((char *)lab + 512 + 16 + 16 + 40, "df2831"); /* partitions at 512+16+16+40+64+64 */ base = 512 + 16 + 16 + 40 + 64 + 64; /* partition 'a' (0): fstype FS_SWAP(1), size from argv */ *(uint64_t *)(lab + base + 0 * 64) = 65536; /* p_boffset */ *(uint64_t *)(lab + base + 0 * 64 + 8) = psize_a; /* p_bsize */ lab[base + 0 * 64 + 16] = 1; /* p_fstype */ /* partition 'c' (2): whole slice, unused */ *(uint64_t *)(lab + base + 2 * 64) = 0; *(uint64_t *)(lab + base + 2 * 64 + 8) = sl_bytes; lab[base + 2 * 64 + 16] = 0; /* crc over d_magic .. d_partitions[NPARTS) */ off_end = base + NPARTS * 64; c = crc32_buf(lab + off_magic, off_end - off_magic); *(uint32_t *)(lab + off_magic + 4) = c; memcpy(img + NSLICE1 * SECT, lab, off_end); free(lab); f = fopen(path, "wb"); fwrite(img, 1, nsec * SECT, f); fclose(f); free(img); printf("df2831.img: 8MiB, s1=%u/%u sectors, label64 crc=%08x\n", NSLICE1, SSLICE1, c); return 0; } |