1/*	$NetBSD: mkboothfs.c,v 1.2 2008/02/27 13:08:52 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
46static void usage(void);
47
48/*
49 * Creates a file for use by mkisofs's -boot-hfs-file.
50 */
51
52int
53main(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
147static void
148usage(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