xref: /haiku/src/tools/fixup_next_boot_floppy/fixup_next_boot_floppy.c (revision ea3142ecbadfaf6f195ceda6af5c6147077fe821)
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