1 /* 2 * Copyright 2020, François Revol, revol@free.fr. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <fcntl.h> 7 #include <stddef.h> 8 #include <stdio.h> 9 #include <stdint.h> 10 #include <unistd.h> 11 #include <arpa/inet.h> 12 13 #include <disklabel.h> 14 15 /* for now we actually write all of the disk label here. */ 16 17 //#define DL_SIZE (sizeof(disklabel)) 18 #define DL_SIZE (offsetof(struct disk_label, dl_un.DL_v3_checksum) + sizeof(uint16_t)) 19 #define SUM_CNT (offsetof(struct disk_label, dl_un.DL_v3_checksum) / sizeof(uint16_t)) 20 21 // could not get ByteOrder.h to include 22 #define H2B32 htonl 23 #define H2B16 htons 24 #define B2H16 ntohs 25 26 // see https://unix.superglobalmegacorp.com/darwin01/newsrc/machdep/i386/checksum_16.c.html 27 static uint16_t checksum_16(uint16_t *p, int count) 28 { 29 uint32_t sum = 0; 30 for (;count--;) 31 sum += B2H16(*p++); 32 // sum both shorts 33 sum = (sum & 0x0ffff) + (sum >> 16); 34 if (sum > 65535) 35 sum -= 65535; 36 return sum; 37 } 38 39 int main(int argc, char **argv) 40 { 41 int fd; 42 unsigned int i; 43 uint16_t sum; 44 struct disk_label disklabel = { 45 H2B32(DL_V3), 46 H2B32(0), 47 H2B32(0), 48 "NextBoot",//"HaikuBoot", 49 H2B32(0), 50 H2B32(0xa991637a), //H2B32(0x4841494b), // dl_tag: 'HAIK' 51 "Sony MPX-111N 2880-512", // same as NS image, not sure it matters 52 "removable_rw_floppy", 53 H2B32(1024), // !! 1024 bytes / sector !! 54 H2B32(2), 55 H2B32(9), 56 H2B32(80), 57 H2B32(300), 58 H2B16(96), 59 H2B16(0), 60 H2B16(0), 61 H2B16(0), 62 H2B16(0), 63 H2B16(0), 64 H2B32(0x20),H2B32(0xffffffff), // boot block locations XXX: move it closer to start? 65 "fdmach", //"haiku_loader", 66 "silly", //"schredder", 67 'a', 'b', 68 // partitions 69 { 70 // Nextstep uses this: 71 { H2B32(0), H2B32(0x540), H2B16(0x2000), H2B16(0x400), 't', H2B16(0x20), H2B16(0x800), 0, 1, "", 1, "4.3BSD"}, 72 { H2B32(-1), H2B32(-1), H2B16(-1), H2B16(-1), 0, H2B16(-1), H2B16(-1), -1, 0, "", 0, ""}, 73 { H2B32(-1), H2B32(-1), H2B16(-1), H2B16(-1), 0, H2B16(-1), H2B16(-1), -1, 0, "", 0, ""}, 74 { H2B32(-1), H2B32(-1), H2B16(-1), H2B16(-1), 0, H2B16(-1), H2B16(-1), -1, 0, "", 0, ""}, 75 { H2B32(-1), H2B32(-1), H2B16(-1), H2B16(-1), 0, H2B16(-1), H2B16(-1), -1, 0, "", 0, ""}, 76 { H2B32(-1), H2B32(-1), H2B16(-1), H2B16(-1), 0, H2B16(-1), H2B16(-1), -1, 0, "", 0, ""}, 77 { H2B32(-1), H2B32(-1), H2B16(-1), H2B16(-1), 0, H2B16(-1), H2B16(-1), -1, 0, "", 0, ""}, 78 { H2B32(-1), H2B32(-1), H2B16(-1), H2B16(-1), 0, H2B16(-1), H2B16(-1), -1, 0, "", 0, ""} 79 } 80 }; 81 fd = open(argv[1], O_RDWR); 82 if (fd < 0) { 83 return 1; 84 } 85 //XXX: implement support simple checksum of existing label? 86 /* 87 if (read(fd, bootblock, DL_SIZE) < DL_SIZE) { 88 perror("read"); 89 return 1; 90 } 91 */ 92 sum = checksum_16((uint16_t *)&disklabel, SUM_CNT); 93 fprintf(stderr, "checksum: 0x%04x\n", sum); 94 disklabel.dl_un.DL_v3_checksum = H2B16(sum); 95 lseek(fd, 0LL, SEEK_SET); 96 write(fd, &disklabel, DL_SIZE); 97 return 0; 98 } 99