1 /*	$NetBSD: mkboothfs.c,v 1.3 2008/05/14 13:29:27 tsutsui Exp $	*/
2 
3 /*-
4  * Copyright (c) 2005, 2006 Izumi Tsutsui.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #if HAVE_NBTOOL_CONFIG_H
28 #include "nbtool_config.h"
29 #include "../../sys/sys/bootblock.h"
30 #else
31 #include <sys/bootblock.h>
32 #endif
33 
34 #include <err.h>
35 #include <fcntl.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 
43 #define BSIZE		512
44 #define BUFSIZE		(8 * 1024)
45 
46 static void usage(void);
47 
48 /*
49  * Creates a file for use by mkisofs's -boot-hfs-file.
50  */
51 
52 int
53 main(int argc, char **argv)
54 {
55 	char *boothfs;
56 	int ofd;
57 	struct apple_drvr_map dm;
58 	struct apple_part_map_entry pme;
59 	char *buf;
60 
61 	if (argc != 2)
62 		usage();
63 
64 	boothfs = argv[1];
65 
66 	buf = malloc(BUFSIZE);
67 	if (buf == NULL)
68 		err(1, "malloc write buffer");
69 
70 	/* create output boot-hfs-file */
71 	if ((ofd = open(boothfs, O_CREAT | O_TRUNC | O_WRONLY, 0644)) == -1)
72 		err(1, "create output boot-hfs-file `%s'", boothfs);
73 
74 	/*
75 	 * Populate 18 byte driver map header in the first 512 byte block
76 	 */
77 	memset(&dm, 0, sizeof dm);
78 	dm.sbSig = htobe16(APPLE_DRVR_MAP_MAGIC);
79 	dm.sbBlockSize = htobe16(2048);
80 	dm.sbBlkCount = htobe32(0);	/* XXX */
81 	dm.sbDevType = htobe16(1);
82 	dm.sbDevID = htobe16(1);
83 	dm.sbData = 0;
84 	dm.sbDrvrCount = 0;
85 
86 	memset(buf, 0, BSIZE);
87 	memcpy(buf, &dm, sizeof(dm));
88 	write(ofd, buf, BSIZE);
89 
90 	/*
91 	 * Write 2048-byte/sector map in the second 512 byte block
92 	 */
93 	memset(&pme, 0, sizeof(pme));
94 	pme.pmSig =		htobe16(APPLE_PART_MAP_ENTRY_MAGIC);
95 	pme.pmMapBlkCnt =	htobe32(1);
96 	pme.pmPyPartStart =	htobe32(1);
97 	pme.pmPartBlkCnt =	htobe32(1);
98 	pme.pmDataCnt =		htobe32(1);
99 	strlcpy(pme.pmPartName, "NetBSD_BootBlock", sizeof(pme.pmPartName));
100 	strlcpy(pme.pmPartType, "Apple_Driver", sizeof(pme.pmPartType));
101 	pme.pmPartStatus =	htobe32(0x3b);
102 	pme.pmBootSize =	htobe32(MACPPC_BOOT_BLOCK_MAX_SIZE);
103 	pme.pmBootLoad =	htobe32(0x4000);
104 	pme.pmBootEntry =	htobe32(0x4000);
105 	strlcpy(pme.pmProcessor, "PowerPC", sizeof(pme.pmProcessor));
106 
107 	memset(buf, 0, BSIZE);
108 	memcpy(buf, &pme, sizeof(pme));
109 	write(ofd, buf, BSIZE);
110 
111 	/*
112 	 * Write 512-byte/sector map in the third 512 byte block
113 	 */
114 	pme.pmPyPartStart =	htobe32(4);
115 	pme.pmPartBlkCnt =	htobe32(4);
116 	pme.pmDataCnt =		htobe32(4);
117 	memset(buf, 0, BSIZE);
118 	memcpy(buf, &pme, sizeof(pme));
119 	write(ofd, buf, BSIZE);
120 
121 	/*
122 	 * Placeholder for 2048 byte padding
123 	 */
124 	memset(buf, 0, BSIZE);
125 	write(ofd, buf, BSIZE);
126 
127 	/*
128 	 * Placeholder for NetBSD bootblock
129 	 */
130 	memset(buf, 0, MACPPC_BOOT_BLOCK_MAX_SIZE);
131 	write(ofd, buf, MACPPC_BOOT_BLOCK_MAX_SIZE);
132 
133 	/*
134 	 * Prepare HFS "bootblock"; enough to pacify mkisofs.
135 	 */
136 	memset(buf, 0, BSIZE * 2);
137 	buf[0] = 0x4c;
138 	buf[1] = 0x4b;
139 	if (write(ofd, buf, BSIZE * 2) != BSIZE * 2)
140 		err(1, "write boot-hfs-file `%s'", boothfs);
141 
142 	free(buf);
143 	close(ofd);
144 	return 0;
145 }
146 
147 static void
148 usage(void)
149 {
150 	const char *prog;
151 
152 	prog = getprogname();
153 	fprintf(stderr, "usage: %s boot-hfs-file\n", prog);
154 	exit(1);
155 }
156