Index: Makefile =================================================================== RCS file: /cvsroot/src/distrib/cdrom/Makefile,v retrieving revision 1.24 diff -u -r1.24 Makefile --- Makefile 20 Jan 2005 08:05:55 -0000 1.24 +++ Makefile 15 May 2005 17:08:03 -0000 @@ -58,7 +58,7 @@ SUBDIR= .if !empty(ALL_PORTS:Mmacppc) -SUBDIR+= macppc_installboot +SUBDIR+= macppc_mkboothfs macppc_installboot .endif .if !empty(SUBDIR) @@ -77,6 +77,7 @@ VAX_IBOOT?= ${TOOL_INSTALLBOOT} -m vax -o sunsum,append .if !empty(ALL_PORTS:Mmacppc) MACPPC_IBOOTDIR!= cd ${.CURDIR}/macppc_installboot && ${PRINTOBJDIR} +MACPPC_MKBOOTHFSDIR!= cd ${.CURDIR}/macppc_mkboothfs && ${PRINTOBJDIR} .endif RSYNC_SITE?= rsync://rsync.NetBSD.org/NetBSD/${RELEASENAME}/ @@ -228,7 +229,7 @@ .if !empty(ports:Mmacppc) MKISOFS_ARGS.${image}+= -hfs -part -hide-hfs-list ${.CURDIR}/hide-hfs.lst \ --macbin -map ${.CURDIR}/hfsmap.lst \ - -boot-hfs-file ${MACPPC_IBOOTDIR}/macppcboot.raw + -boot-hfs-file ${MACPPC_MKBOOTHFSDIR}/boothfs .elif defined(USE_APPLE_ISO) || !empty(ports:Mmac68k) MKISOFS_ARGS.${image}+= -apple --macbin -map ${.CURDIR}/hfsmap.lst .endif @@ -358,15 +359,17 @@ # 1. Size the image produced by mkisofs. # 2. Add images added by distrib/common/sunbootcd.sh by rounding to a 320k # boundary and adding each Sun image rounded to a 320k boundary. -# 3. Add 64k if macppc is included (ofwboot munged to one 64k block). -# 4. Add bootfile sizes rounded up to 512 bytes for pmax and vax. -# 5. Round up to a 32k boundary, then add another 32k for TAO padding. +# 3. Add bootfile sizes rounded up to 512 bytes for pmax and vax. +# 4. Round up to a 32k boundary, then add another 32k for TAO padding. .if !empty(BASE_PORTS.${image}:Mmacppc) -size-${image}: all-macppc_installboot +size-${image}: all-macppc_mkboothfs all-macppc_installboot .endif size-${image}: stage-${image} extfileprep fileprep-${image} +.if !empty(BASE_PORTS.${image}:Mmacppc) + ${MACPPC_MKBOOTHFSDIR}/macppc_mkboothfs ${MACPPC_MKBOOTHFSDIR}/boothfs +.endif @size=$$((`cd ${STAGEDIR}/${image} && ${MKISOFS} ${MKISOFS_ARGS} ${MKISOFS_ARGS.${image}} -print-size . 2>&1 | tee /dev/stderr | sed '/=/!d;s/^[^=]*=//'` * 2048)) && \ if [ "${SUN_BOOT_ARGS.${image}}" != "" ]; then \ size=$$(($$(($$size + 327679)) / 327680 * 327680)) && \ @@ -376,9 +379,6 @@ size=$$(($$size + $$(($$(($$bfsize + 327679)) / 327680 * 327680)))); \ done; \ fi && \ - if [ "${BASE_PORTS.${image}:Mmacppc}" != "" ]; then \ - size=$$(($$size + 65536)); \ - fi && \ if [ "${BASE_PORTS.${image}:Mpmax}" != "" ]; then \ size=$$(($$size + $$(($$((`ls -l ${BOOTFILE.pmax} | awk '{print $$5}'` + 511)) / 512 * 512)))); \ fi && \ @@ -405,9 +405,8 @@ ${.TARGET} ${SUN_BOOT_ARGS.${image}} .endif .if !empty(BASE_PORTS.${image}:Mmacppc) - @blknum=$$((`ls -l $@ | awk '{print $$5}'` / 512)) && \ - ${MACPPC_IBOOTDIR}/macppc_installboot $@ $$blknum 756 - dd if=${EXTFILEDIR}/macppc.ofwboot bs=64k count=1 conv=sync >>$@ 2>/dev/null + ${MACPPC_IBOOTDIR}/macppc_installboot \ + $@ ${EXTFILEDIR}/macppc.bootxx /ofwboot .endif .if !empty(BASE_PORTS.${image}:Mpmax) ${PMAX_IBOOT} $@ ${BOOTFILE.pmax} Index: NetBSD-2.0.mk =================================================================== RCS file: /cvsroot/src/distrib/cdrom/NetBSD-2.0.mk,v retrieving revision 1.2 diff -u -r1.2 NetBSD-2.0.mk --- NetBSD-2.0.mk 6 Dec 2004 08:29:25 -0000 1.2 +++ NetBSD-2.0.mk 15 May 2005 17:08:03 -0000 @@ -23,8 +23,10 @@ INTFILES.amd64= boot.amd64:amd64/installation/floppy/boot-big.fs,link # macppc has external bootblock generation tool -EXTFILES.macppc= macppc.ofwboot:macppc/binary/sets/base.tgz,./usr/mdec/ofwboot +EXTFILES.macppc= macppc.bootxx:macppc/binary/sets/base.tgz,./usr/mdec/bootxx \ + macppc.ofwboot:macppc/binary/sets/base.tgz,./usr/mdec/ofwboot INTFILES.macppc= ofwboot.xcf:macppc/installation/ofwboot.xcf,link \ + ofwboot:macppc/binary/sets/base.tgz,./usr/mdec/ofwboot \ netbsd.macppc:macppc/binary/kernel/netbsd-INSTALL.gz,link # BOOTFILE.pmax is absolute Index: NetBSD-current.mk =================================================================== RCS file: /cvsroot/src/distrib/cdrom/NetBSD-current.mk,v retrieving revision 1.2 diff -u -r1.2 NetBSD-current.mk --- NetBSD-current.mk 6 Dec 2004 20:05:10 -0000 1.2 +++ NetBSD-current.mk 15 May 2005 17:08:03 -0000 @@ -23,8 +23,10 @@ INTFILES.amd64= boot.amd64:amd64/installation/floppy/boot-big.fs,link # macppc has external bootblock generation tool -EXTFILES.macppc= macppc.ofwboot:macppc/binary/sets/base.tgz,./usr/mdec/ofwboot +EXTFILES.macppc= macppc.bootxx:macppc/binary/sets/base.tgz,./usr/mdec/bootxx \ + macppc.ofwboot:macppc/binary/sets/base.tgz,./usr/mdec/ofwboot INTFILES.macppc= ofwboot.xcf:macppc/installation/ofwboot.xcf,link \ + ofwboot:macppc/binary/sets/base.tgz,./usr/mdec/ofwboot \ netbsd.macppc:macppc/binary/kernel/netbsd-INSTALL.gz,link # BOOTFILE.pmax is absolute Index: macppc_installboot/Makefile =================================================================== RCS file: /cvsroot/src/distrib/cdrom/macppc_installboot/Makefile,v retrieving revision 1.5 diff -u -r1.5 Makefile --- macppc_installboot/Makefile 19 Mar 2004 08:07:28 -0000 1.5 +++ macppc_installboot/Makefile 15 May 2005 17:08:03 -0000 @@ -1,23 +1,10 @@ -# $NetBSD: Makefile,v 1.5 2004/03/19 08:07:28 jmc Exp $ +# $NetBSD$ +HOSTPROG= macppc_installboot +SRCS= installboot.c cd9660.c cd9660_util.c NOMAN= # defined -.include +HOST_CPPFLAGS+= -I${.CURDIR} -I${NETBSDSRCDIR}/sys +#HOST_CPPFLAGS+= -DDEBUG -HOSTPROG= macppc_installboot -HOST_CPPFLAGS+= -I${NETBSDSRCDIR}/sys/arch -UUDECODE_FILES= bootxx.raw macppcboot.raw - -CLEANFILES+= mkmacppcboot - -all: macppcboot.raw - -.include .include - -mkmacppcboot: mkmacppcboot.c - ${LINK.c} -o ${.TARGET} ${.ALLSRC} - -regen: mkmacppcboot bootxx.raw.uue - ./mkmacppcboot <${.CURDIR}/bootxx.raw | \ - uuencode macppcboot.raw > macppcboot.raw.uue --- /dev/null 2005-05-16 01:55:08.000000000 +0900 +++ macppc_installboot/cd9660.c 2005-05-16 01:53:06.000000000 +0900 @@ -0,0 +1,236 @@ +/* $NetBSD$ */ + +/*- + * Copyright (C) 2005 Izumi Tsutsui + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include +#if defined(__RCSID) && !defined(__lint) +__RCSID("$NetBSD$"); +#endif /* !__lint */ + +#include +#include + +#if !HAVE_NBTOOL_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "installboot.h" + +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#define MAXLEN 16 + + +int +cd9660_match(ib_params *params) +{ + int rv, blocksize; + struct iso_primary_descriptor ipd; + + assert(params != NULL); + assert(params->fstype != NULL); + assert(params->fsfd != -1); + + rv = pread(params->fsfd, &ipd, sizeof(ipd), + ISO_DEFAULT_BLOCK_SIZE * 16); + if (rv == -1) { + warn("Reading primary descriptor in `%s'", params->filesystem); + return 0; + } else if (rv != sizeof(ipd)) { + warnx("Reading primary descriptor in `%s': short read", + params->filesystem); + return 0; + } + + if (ipd.type[0] != ISO_VD_PRIMARY || + strncmp(ipd.id, ISO_STANDARD_ID, sizeof(ipd.id)) != 0 || + ipd.version[0] != 1) { + warnx("Filesystem `%s' is not ISO9660 format", + params->filesystem); + return 0; + } + + blocksize = isonum_723((char *)ipd.logical_block_size); + if (blocksize != ISO_DEFAULT_BLOCK_SIZE) { + warnx("Invalid blocksize %d in `%s'", + blocksize, params->filesystem); + return 0; + } + + params->fstype->blocksize = blocksize; + params->fstype->needswap = 0; + + return 1; +} + +int +cd9660_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks) +{ + uint8_t buf[ISO_DEFAULT_BLOCK_SIZE]; + char name[MAXNAMLEN]; + char *ofwboot; + off_t loc; + int rv, blocksize, found, i; + struct iso_primary_descriptor ipd; + struct iso_directory_record *idr; + + assert(params != NULL); + assert(params->stage2 != NULL); + assert(maxblk != NULL); + assert(blocks != NULL); + +#if 0 + if (params->flags & IB_STAGE2START) + return hardcode_stage2(params, maxblk, blocks); +#endif + + /* The secondary bootstrap must be clearly in /. */ + strlcpy(name, params->stage2, MAXNAMLEN); + ofwboot = name; + if (ofwboot[0] == '/') + ofwboot++; + if (strchr(ofwboot, '/') != NULL) { + warnx("The secondary bootstrap `%s' must be in / " + "on filesystem `%s'", params->stage2, params->filesystem); + return 0; + } + if (strchr(ofwboot, '.') == NULL) { + /* + * XXX should fix isofncmp()? + */ + strlcat(ofwboot, ".", MAXNAMLEN); + } + + rv = pread(params->fsfd, &ipd, sizeof(ipd), + ISO_DEFAULT_BLOCK_SIZE * 16); + if (rv == -1) { + warn("Reading primary descriptor in `%s'", params->filesystem); + return 0; + } else if (rv != sizeof(ipd)) { + warnx("Reading primary descriptor in `%s': short read", + params->filesystem); + return 0; + } + blocksize = isonum_723((char *)ipd.logical_block_size); + + idr = (void *)ipd.root_directory_record; + loc = (off_t)isonum_733(idr->extent) * blocksize; + rv = pread(params->fsfd, buf, blocksize, loc); + if (rv == -1) { + warn("Reading root directory record in `%s'", + params->filesystem); + return 0; + } else if (rv != sizeof(ipd)) { + warnx("Reading root directory record in `%s': short read", + params->filesystem); + return 0; + } + + found = 0; + for (i = 0; i < blocksize - sizeof(struct iso_directory_record); + i += (u_char)idr->length[0]) { + idr = (void *)&buf[i]; + +#ifdef DEBUG + printf("i = %d, idr->length[0] = %3d\n", + i, (u_char)idr->length[0]); +#endif + /* check end of entries */ + if (idr->length[0] == 0) { +#ifdef DEBUG + printf("end of entries\n"); +#endif + break; + } + + if (idr->flags[0] & 2) { + /* skip directory entries */ +#ifdef DEBUG + printf("skip directory entry\n"); +#endif + continue; + } + if (idr->name_len[0] == 1 && + (idr->name[0] == 0 || idr->name[0] == 1)) { + /* skip "." and ".." */ +#ifdef DEBUG + printf("skip dot dot\n"); +#endif + continue; + } +#ifdef DEBUG + { + int j; + + printf("filename:"); + for (j = 0; j < isonum_711(idr->name_len); j++) + printf("%c", idr->name[j]); + printf("\n"); + } +#endif + if (isofncmp(ofwboot, strlen(ofwboot), + idr->name, isonum_711(idr->name_len), 0) == 0) { + found = 1; + /* ISO filesystem always has contiguous file blocks */ + blocks[0].block = (int64_t)isonum_733(idr->extent); + /* XXX bootxx assumes blocksize is 512 */ + blocks[0].block *= blocksize / 512; + blocks[0].blocksize = + roundup(isonum_733(idr->size), blocksize); + *maxblk = 1; +#ifdef DEBUG + printf("block = %ld, blocksize = %ld\n", + (long)blocks[0].block, blocks[0].blocksize); +#endif + break; + } + } + + if (found = 0) { + warnx("Can't find secondary bootstrap `%s' in filesystem `%s'", + params->stage2, params->filesystem); + return 0; + } + + return 1; +} --- /dev/null 2005-05-16 01:55:08.000000000 +0900 +++ macppc_installboot/cd9660_util.c 2005-05-16 01:53:06.000000000 +0900 @@ -0,0 +1,236 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley + * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension + * Support code is derived from software contributed to Berkeley + * by Atsushi Murai (amurai@spec.co.jp). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94 + */ + +/* from NetBSD: cd9660_util.c,v 1.5 2004/12/28 01:12:26 jdolecek Exp */ + + +#include +#include +#include + +#include +#define KASSERT(x) assert(x) /* XXX for */ +#include + +#include "installboot.h" + +static int isochar(const u_char *, const u_char *, int, uint16_t *); +static uint16_t wget(const u_char **, size_t *, int); +static int wput(u_char *, size_t, uint16_t, int); + +int cd9660_utf8_joliet = 1; + +/* + * Get one character out of an iso filename + * Return number of bytes consumed + */ +int +isochar(const u_char *isofn, const u_char *isoend, int joliet_level, + uint16_t *c) +{ + + *c = isofn[0]; + if (joliet_level == 0 || isofn + 1 == isoend) { + /* (00) and (01) are one byte in Joliet, too */ + return 1; + } + + if (cd9660_utf8_joliet) { + *c = (*c << 8) + isofn[1]; + } else { + /* characters outside ISO-8859-1 subset replaced with '?' */ + if (*c != 0) + *c = '?'; + else + *c = isofn[1]; + } + + return 2; +} + +/* + * translate and compare a filename + * Note: Version number plus ';' may be omitted. + */ +int +isofncmp(const u_char *fn, size_t fnlen, const u_char *isofn, size_t isolen, + int joliet_level) +{ + int i, j; + uint16_t fc, ic; + const u_char *isoend = isofn + isolen; + +#ifdef DEBUG + printf("fn = %s, fnlen = %d, isofn = %s, isolen = %d\n", + fn, fnlen, isofn, isolen); +#endif + + while (fnlen > 0) { + fc = wget(&fn, &fnlen, joliet_level); + + if (isofn == isoend) + return fc; + isofn += isochar(isofn, isoend, joliet_level, &ic); + if (ic == ';') { + switch (fc) { + default: + return fc; + case 0: + return 0; + case ';': + break; + } + fn++; + for (i = 0; --fnlen >= 0; i = i * 10 + *fn++ - '0') { + if (*fn < '0' || *fn > '9') { + return -1; + } + } + for (j = 0; isofn != isoend; j = j * 10 + ic - '0') + isofn += isochar(isofn, isoend, + joliet_level, &ic); + return i - j; + } + if (ic != fc) { + if (ic >= 'A' && ic <= 'Z') { + if (ic + ('a' - 'A') != fc) { + if (fc >= 'a' && fc <= 'z') + fc -= 'a' - 'A'; + + return (int)fc - (int)ic; + } + } else + return (int)fc - (int)ic; + } + } + if (isofn != isoend) { + isofn += isochar(isofn, isoend, joliet_level, &ic); + switch (ic) { + default: + return -1; + case '.': + if (isofn != isoend) { + isochar(isofn, isoend, joliet_level, &ic); + if (ic == ';') + return 0; + } + return -1; + case ';': + return 0; + } + } + return 0; +} + +/* + * translate a filename + */ +void +isofntrans(u_char *infn, int infnlen, u_char *outfn, u_short *outfnlen, + int original, int casetrans, int assoc, int joliet_level) +{ + int fnidx = 0; + u_char *infnend = infn + infnlen; + uint16_t c; + int sz; + + if (assoc) { + *outfn++ = ASSOCCHAR; + fnidx++; + } + + for(; infn != infnend; fnidx += sz) { + infn += isochar(infn, infnend, joliet_level, &c); + + if (casetrans && joliet_level == 0 && c >= 'A' && c <= 'Z') + c = c + ('a' - 'A'); + else if (!original && c == ';') { + if (fnidx > 0 && outfn[-1] == '.') + fnidx--; + break; + } + + sz = wput(outfn, MAXNAMLEN - fnidx, c, joliet_level); + if (sz == 0) { + /* not enough space to write the character */ + if (fnidx < MAXNAMLEN) { + *outfn = '?'; + fnidx++; + } + break; + } + outfn += sz; + } + *outfnlen = fnidx; +} + +static uint16_t +wget(const u_char **str, size_t *sz, int joliet_level) +{ + if (joliet_level > 0 && cd9660_utf8_joliet) { + /* decode UTF-8 sequence */ + return wget_utf8((const char **) str, sz); + } else { + /* + * Raw 8-bit characters without any conversion. For Joliet, + * this effectively assumes provided file name is using + * ISO-8859-1 subset. + */ + uint16_t c = *str[0]; + (*str)++; + + return c; + } +} + +static int +wput(u_char *s, size_t n, uint16_t c, int joliet_level) +{ + if (joliet_level > 0 && cd9660_utf8_joliet) { + /* Store Joliet file name encoded into UTF-8 */ + return wput_utf8((char *)s, n, c); + } else { + /* + * Store raw 8-bit characters without any conversion. + * For Joliet case, this filters the Unicode characters + * to ISO-8859-1 subset. + */ + *s = (u_char)c; + return 1; + } +} --- /dev/null 2005-05-16 22:45:24.000000000 +0900 +++ macppc_installboot/installboot.c 2005-05-16 01:53:06.000000000 +0900 @@ -0,0 +1,215 @@ +/* $NetBSD$ */ + +/*- + * Copyright (C) 2005 Izumi Tsutsui + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "installboot.h" + +#define BSIZE 512 +#define MAX_SB_SIZE (64 * 1024) /* XXX */ +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) + +static void usage(void); + +static ib_params installboot_params; + +int +main(int argc, char **argv) +{ + ib_params *params; + uint8_t *bb; + struct apple_part_map_entry pme; + size_t bbi; + struct shared_bbinfo *bbinfop; + off_t partoff; + uint32_t nblk, maxblk, blk_i; + int rv; + ib_block *blocks; + + setprogname(argv[0]); + params = &installboot_params; + memset(params, 0, sizeof(*params)); + params->fsfd = -1; + params->s1fd = -1; + + if (argc != 4) + usage(); + + params->filesystem = argv[1]; + + if ((params->fsfd = open(params->filesystem, O_RDWR, 0600)) == -1) + err(1, "Opening file system `%s' read", params->filesystem); + if (fstat(params->fsfd, ¶ms->fsstat) == -1) + err(1, "Examining file system `%s'", params->filesystem); +#ifdef DEBUG + printf("file system: %s, %ld bytes\n", + params->filesystem, (long)params->fsstat.st_size); +#endif + + /* + * Find space for primary boot from the second (NetBSD_BootBlock) + * partition. + */ + if (pread(params->fsfd, &pme, sizeof pme, BSIZE * 2) != sizeof(pme)) + err(1, "read pme from file system `%s'", params->filesystem); + + if (strcmp(pme.pmPartName, "NetBSD_BootBlock")) + err(1, "invalid partition map in file system `%s'", + params->filesystem); + + /* pmPyPartStart is written by mkisofs */ + partoff = BSIZE * be32toh(pme.pmPyPartStart); + +#ifdef DEBUG + printf("NetBSD partition offset = %ld\n", (long)partoff); +#endif + + params->stage1 = argv[2]; + + if ((params->s1fd = open(params->stage1, O_RDONLY, 0600)) == -1) + err(1, "Opening primary bootstrap `%s'", params->stage1); + if (fstat(params->s1fd, ¶ms->s1stat) == -1) + err(1, "Examining primary bootstrap `%s'", params->stage1); + if (!S_ISREG(params->s1stat.st_mode)) + err(1, "`%s' must be a regular file", params->stage1); + + if (params->s1stat.st_size > MACPPC_BOOT_BLOCK_MAX_SIZE) + err(1, "primary bootrap `%s' too large (%ld bytes)", + params->stage1, (long)params->s1stat.st_size); + +#ifdef DEBUG + printf("primary boot: %s, %ld bytes\n", + params->stage1, (long)params->s1stat.st_size); +#endif + + params->stage2 = argv[3]; + + bb = malloc(MACPPC_BOOT_BLOCK_MAX_SIZE); + if (bb == NULL) + err(1, "Allocating %ul bytes for bbinfo"); + + memset(bb, 0, sizeof(bb)); + rv = read(params->s1fd, bb, params->s1stat.st_size); + + if (rv == -1) + err(1, "Reading `%s'", params->stage1); + + if (memcmp(bb + 1, "ELF", strlen("ELF")) == 0) { + warnx("`%s' is an ELF executable; need raw binary", + params->stage1); + } + + /* look for the bbinfo structure */ + for (bbi = 0; bbi < MACPPC_BOOT_BLOCK_MAX_SIZE; + bbi += sizeof(uint32_t)) { + bbinfop = (void *)(bb + bbi); + if (memcmp(bbinfop->bbi_magic, MACPPC_BBINFO_MAGIC, + sizeof(bbinfop->bbi_magic)) == 0) { +#ifdef DEBUG + printf("magic found: %s\n", bbinfop->bbi_magic); +#endif + break; + } + } + if (bbi >= MACPPC_BOOT_BLOCK_MAX_SIZE) + err(1, "bbinfo structure not found in `%s'", params->stage1); + + maxblk = be32toh(bbinfop->bbi_block_count); + if (maxblk == 0 || + maxblk > (MACPPC_BOOT_BLOCK_MAX_SIZE / sizeof(uint32_t))) + err(1, "bbinfo structure in `%s' has preposterous size `%u'", + params->stage1, maxblk); + + blocks = malloc(sizeof(*blocks) * maxblk); + if (blocks == NULL) { + err(1, "Allocating %lu bytes for blocks", + (unsigned long)sizeof(*blocks) * maxblk); + } + + if (S_ISREG(params->fsstat.st_mode)) { + if (fsync(params->fsfd) == -1) + err(1, "Synchronising file system `%s'", + params->filesystem); + } + + nblk = maxblk; + if (!cd9660_findstage2(params, &nblk, blocks)) { + exit(1); + } + + bbinfop->bbi_block_count = htobe32(nblk); + bbinfop->bbi_block_size = htobe32(blocks[0].blocksize); + for (blk_i = 0; blk_i < nblk; blk_i++) { + bbinfop->bbi_block_table[blk_i] = htobe32(blocks[blk_i].block); + if (blocks[blk_i].blocksize < blocks[0].blocksize && + blk_i + 1 != nblk) { + warnx("Secondary bootstrap `%s' blocks do not have " + "a uniform size", params->stage2); + exit(1); + } + } + + /* XXX no write option */ + + if (pwrite(params->fsfd, bb, MACPPC_BOOT_BLOCK_MAX_SIZE, partoff) != + MACPPC_BOOT_BLOCK_MAX_SIZE) + err(1, "write bootblock"); + + if (S_ISREG(params->fsstat.st_mode)) { + if (fsync(params->fsfd) == -1) + err(1, "Synchronising file system `%s'", + params->filesystem); + } + + free(bb); + + if (close(params->fsfd) == -1) + err(1, "Closing file system `%s'", params->filesystem); + if (close(params->s1fd) == -1) + err(1, "Closing primary bootstrap `%s'", params->stage1); + + return 0; +} + +static void +usage(void) +{ + const char *prog; + + prog = getprogname(); + fprintf(stderr, "usage: %s hybrid-cd-image primary secondary\n", prog); + exit(1); +} --- /dev/null 2005-05-16 01:55:08.000000000 +0900 +++ macppc_installboot/installboot.h 2005-05-16 01:53:06.000000000 +0900 @@ -0,0 +1,145 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn of Wasabi Systems. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _INSTALLBOOT_H +#define _INSTALLBOOT_H + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#include "../../sys/sys/bootblock.h" +#else +#include +#include +#endif + +#include +#include + +typedef enum { + /* flags from global options */ + IB_VERBOSE = 1<<0, /* verbose operation */ + IB_NOWRITE = 1<<1, /* don't write */ + IB_CLEAR = 1<<2, /* clear boot block */ + + /* flags from -o options */ + IB_ALPHASUM = 1<<8, /* set Alpha checksum */ + IB_APPEND = 1<<9, /* append stage 1 to EO(regular)F */ + IB_SUNSUM = 1<<10, /* set Sun checksum */ + IB_STAGE1START= 1<<11, /* start block for stage 1 provided */ + IB_STAGE2START= 1<<12, /* start block for stage 2 provided */ + IB_COMMAND = 1<<13, /* Amiga commandline option */ + IB_RESETVIDEO = 1<<14, /* i386 reset video */ + IB_CONSOLE = 1<<15, /* i386 console */ + IB_CONSPEED = 1<<16, /* i386 console baud rate */ + IB_TIMEOUT = 1<<17, /* i386 boot timeout */ + IB_PASSWORD = 1<<18, /* i386 boot password */ + IB_KEYMAP = 1<<19, /* i386 console keymap */ + IB_CONSADDR = 1<<20, /* i386 console io address */ +} ib_flags; + +typedef struct { + ib_flags flags; /* flags (see above) */ + struct ib_mach *machine; /* machine details (see below) */ + struct ib_fs *fstype; /* file system details (see below) */ + const char *filesystem; /* name of target file system */ + int fsfd; /* open fd to filesystem */ + struct stat fsstat; /* fstat(2) of fsfd */ + const char *stage1; /* name of stage1 bootstrap */ + int s1fd; /* open fd to stage1 */ + struct stat s1stat; /* fstat(2) of s1fd */ + uint64_t s1start; /* start block of stage1 */ + const char *stage2; /* name of stage2 bootstrap */ + uint64_t s2start; /* start block of stage2 */ + /* parsed -o option=value data */ + const char *command; /* name of command string */ + const char *console; /* name of console */ + int conspeed; /* console baud rate */ + int consaddr; /* console io address */ + const char *password; /* boot password */ + int timeout; /* interactive boot timeout */ + const char *keymap; /* keyboard translations */ +} ib_params; + +typedef struct { + uint64_t block; + uint32_t blocksize; +} ib_block; + +struct ib_mach { + const char *name; + int (*setboot) (ib_params *); + int (*clearboot) (ib_params *); + ib_flags valid_flags; +}; + +struct ib_fs { + /* compile time parameters */ + const char *name; + int (*match) (ib_params *); + int (*findstage2) (ib_params *, uint32_t *, ib_block *); + /* run time fs specific parameters */ + uint32_t blocksize; + uint32_t needswap; + off_t sblockloc; /* location of superblock */ +}; + +typedef enum { + BBINFO_BIG_ENDIAN = 0, + BBINFO_LITTLE_ENDIAN = 1, +} bbinfo_endian; + +struct bbinfo_params { + const char *magic; /* magic string to look for */ + uint32_t offset; /* offset to write start of stage1 */ + uint32_t blocksize; /* blocksize of stage1 */ + uint32_t maxsize; /* max size of stage1 */ + uint32_t headeroffset; /* + * header offset (relative to offset) + * to read stage1 into + */ + bbinfo_endian endian; +}; + +int cd9660_match(ib_params *); +int cd9660_findstage2(ib_params *, uint32_t *, ib_block *); + +int isofncmp(const u_char *, size_t, const u_char *, size_t, int); +void isofntrans(u_char *, int, u_char *, u_short *, int, int, int, int); + + +#endif /* _INSTALLBOOT_H */ --- /dev/null 2005-05-16 01:55:08.000000000 +0900 +++ macppc_mkboothfs/Makefile 2005-05-14 23:39:25.000000000 +0900 @@ -0,0 +1,9 @@ +# $NetBSD$ + +HOSTPROG= macppc_mkboothfs +SRCS= mkboothfs.c +NOMAN= # defined + +CLEANFILES+= boothfs + +.include --- /dev/null 2005-05-16 01:55:08.000000000 +0900 +++ macppc_mkboothfs/mkboothfs.c 2005-05-15 04:14:22.000000000 +0900 @@ -0,0 +1,152 @@ +/* $NetBSD$ */ + +/*- + * Copyright (C) 2005 Izumi Tsutsui + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#include "../../sys/sys/bootblock.h" +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BSIZE 512 +#define BUFSIZE (8 * 1024) + +static void usage(void); + +/* + * Creates a file for use by mkisofs's -boot-hfs-file. + */ + +int +main(int argc, char **argv) +{ + char *boothfs; + int ifd, ofd; + struct apple_drvr_map dm; + struct apple_part_map_entry pme; + char *buf; + + if (argc != 2) + usage(); + + boothfs = argv[1]; + + buf = malloc(BUFSIZE); + if (buf == NULL) + err(1, "malloc write buffer"); + + /* create output boot-hfs-file */ + if ((ofd = open(boothfs, O_CREAT | O_TRUNC | O_WRONLY, 0644)) == -1) + err(1, "create output boot-hfs-file `%s'", boothfs); + + /* + * Populate 18 byte driver map header in the first 512 byte block + */ + memset(&dm, 0, sizeof dm); + dm.sbSig = htobe16(APPLE_DRVR_MAP_MAGIC); + dm.sbBlockSize = htobe16(2048); + dm.sbBlkCount = htobe32(333000); /* XXX */ + dm.sbDevType = htobe16(1); + dm.sbDevID = htobe16(1); + dm.sbData = 0; + dm.sbDrvrCount = 0; + + memset(buf, 0, BSIZE); + memcpy(buf, &dm, sizeof dm); + write(ofd, buf, BSIZE); + + /* + * Write 2048-byte/sector map in the second 512 byte block + */ + memset(&pme, 0, sizeof pme); + pme.pmSig = htobe16(APPLE_PART_MAP_ENTRY_MAGIC); + pme.pmPartBlkCnt = pme.pmDataCnt = htobe32(1); + strcpy(pme.pmPartName, "NetBSD_BootBlock"); + strcpy(pme.pmPartType, "Apple_Driver"); + pme.pmPartStatus = htobe32(0x03b); + pme.pmBootSize = htobe32(MACPPC_BOOT_BLOCK_MAX_SIZE); + pme.pmBootLoad = pme.pmBootEntry = htobe32(0x4000); + strcpy(pme.pmProcessor, "PowerPC"); + + memset(buf, 0, BSIZE); + memcpy(buf, &pme, sizeof pme); + write(ofd, buf, BSIZE); + + /* + * Write 512-byte/sector map in the third 512 byte block + */ + pme.pmPartBlkCnt = pme.pmDataCnt = htobe32(4); + memset(buf, 0, BSIZE); + memcpy(buf, &pme, sizeof pme); + write(ofd, buf, BSIZE); + + /* + * Placeholder for 2048 byte padding + */ + memset(buf, 0, BSIZE); + write(ofd, buf, BSIZE); + + /* + * Placeholder for NetBSD bootblock + */ + memset(buf, 0, MACPPC_BOOT_BLOCK_MAX_SIZE); + write(ofd, buf, MACPPC_BOOT_BLOCK_MAX_SIZE); + + /* + * Prepare HFS "bootblock"; enough to pacify mkisofs. + */ + memset(buf, 0, BSIZE * 2); + buf[0] = 0x4c; + buf[1] = 0x4b; + if (write(ofd, buf, BSIZE * 2) != BSIZE * 2) + err(1, "write boot-hfs-file `%s'", boothfs); + + free(buf); + close(ofd); + return 0; +} + +static void +usage(void) +{ + const char *prog; + + prog = getprogname(); + fprintf(stderr, "usage: %s boot-hfs-file\n", prog); + exit(1); +}