Import usr.sbin/installboot.

This commit is contained in:
Evgeniy Ivanov
2012-01-10 12:46:52 +04:00
committed by Ben Gras
parent 4c4c045f87
commit 9f8e6353e5
28 changed files with 7382 additions and 0 deletions

View File

@@ -0,0 +1,451 @@
/* $NetBSD: alpha.c,v 1.21 2011/08/14 17:50:17 christos Exp $ */
/*-
* 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.
*
* 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.
*/
/*
* Copyright (c) 1999 Ross Harvey. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ross Harvey
* for the NetBSD Project.
* 4. 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.
*/
/*
* Copyright (c) 1999 Christopher G. Demetriou. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christopher G. Demetriou
* for the NetBSD Project.
* 4. 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 <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: alpha.c,v 1.21 2011/08/14 17:50:17 christos Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
#define SUN_DKMAGIC 55998 /* XXX: from <dev/sun/disklabel.h> */
static void resum(ib_params *, struct alpha_boot_block * const bb,
uint16_t *bb16);
static void sun_bootstrap(ib_params *, struct alpha_boot_block * const);
static void check_sparc(const struct alpha_boot_block * const,
const char *);
static int alpha_clearboot(ib_params *);
static int alpha_setboot(ib_params *);
struct ib_mach ib_mach_alpha =
{ "alpha", alpha_setboot, alpha_clearboot, no_editboot,
IB_STAGE1START | IB_ALPHASUM | IB_APPEND | IB_SUNSUM };
static int
alpha_clearboot(ib_params *params)
{
struct alpha_boot_block bb;
uint64_t cksum;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(sizeof(struct alpha_boot_block) == ALPHA_BOOT_BLOCK_BLOCKSIZE);
if (params->flags & (IB_STAGE1START | IB_APPEND)) {
warnx("Can't use `-b bno' or `-o append' with `-c'");
return (0);
}
rv = pread(params->fsfd, &bb, sizeof(bb), ALPHA_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
return (0);
} else if (rv != sizeof(bb)) {
warnx("Reading `%s': short read", params->filesystem);
return (0);
}
ALPHA_BOOT_BLOCK_CKSUM(&bb, &cksum);
if (cksum != bb.bb_cksum) { // XXX check bb_cksum endian?
warnx(
"Old boot block checksum invalid (was %#llx, calculated %#llx)",
(unsigned long long)le64toh(bb.bb_cksum),
(unsigned long long)le64toh(cksum));
warnx("Boot block invalid");
return (0);
}
if (params->flags & IB_VERBOSE) {
printf("Old bootstrap start sector: %llu\n",
(unsigned long long)le64toh(bb.bb_secstart));
printf("Old bootstrap size: %llu\n",
(unsigned long long)le64toh(bb.bb_secsize));
printf("Old bootstrap checksum: %#llx\n",
(unsigned long long)le64toh(bb.bb_cksum));
}
bb.bb_secstart = bb.bb_secsize = bb.bb_flags = 0;
ALPHA_BOOT_BLOCK_CKSUM(&bb, &bb.bb_cksum);
if (params->flags & IB_SUNSUM)
sun_bootstrap(params, &bb);
printf("New bootstrap start sector: %llu\n",
(unsigned long long)le64toh(bb.bb_secstart));
printf("New bootstrap size: %llu\n",
(unsigned long long)le64toh(bb.bb_secsize));
printf("New bootstrap checksum: %#llx\n",
(unsigned long long)le64toh(bb.bb_cksum));
if (params->flags & IB_VERBOSE)
printf("%slearing boot block\n",
(params->flags & IB_NOWRITE) ? "Not c" : "C");
if (params->flags & IB_NOWRITE)
return (1);
rv = pwrite(params->fsfd, &bb, sizeof(bb), ALPHA_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
return (0);
} else if (rv != sizeof(bb)) {
warnx("Writing `%s': short write", params->filesystem);
return (0);
}
return (1);
}
static int
alpha_setboot(ib_params *params)
{
struct alpha_boot_block bb;
uint64_t startblock;
int retval;
char *bootstrapbuf;
size_t bootstrapsize;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
assert(sizeof(struct alpha_boot_block) == ALPHA_BOOT_BLOCK_BLOCKSIZE);
retval = 0;
bootstrapbuf = NULL;
/*
* Allocate a buffer, with space to round up the input file
* to the next block size boundary, and with space for the boot
* block.
*/
bootstrapsize = roundup(params->s1stat.st_size,
ALPHA_BOOT_BLOCK_BLOCKSIZE);
bootstrapbuf = malloc(bootstrapsize);
if (bootstrapbuf == NULL) {
warn("Allocating %lu bytes", (unsigned long) bootstrapsize);
goto done;
}
memset(bootstrapbuf, 0, bootstrapsize);
/* read the file into the buffer */
rv = pread(params->s1fd, bootstrapbuf, params->s1stat.st_size, 0);
if (rv == -1) {
warn("Reading `%s'", params->stage1);
goto done;
} else if (rv != params->s1stat.st_size) {
warnx("Reading `%s': short read", params->stage1);
goto done;
}
rv = pread(params->fsfd, &bb, sizeof(bb), ALPHA_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != sizeof(bb)) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
if (params->flags & IB_SUNSUM)
check_sparc(&bb, "Initial");
/* fill in the updated bootstrap fields */
if (params->flags & IB_APPEND) {
struct stat filesyssb;
if (fstat(params->fsfd, &filesyssb) == -1) {
warn("Examining `%s'", params->filesystem);
goto done;
}
if (!S_ISREG(filesyssb.st_mode)) {
warnx(
"`%s' must be a regular file to append a bootstrap",
params->filesystem);
goto done;
}
startblock = howmany(filesyssb.st_size,
ALPHA_BOOT_BLOCK_BLOCKSIZE);
} else if (params->flags & IB_STAGE1START) {
startblock = params->s1start;
} else {
startblock = ALPHA_BOOT_BLOCK_OFFSET /
ALPHA_BOOT_BLOCK_BLOCKSIZE + 1;
}
bb.bb_secsize =
htole64(howmany(params->s1stat.st_size,
ALPHA_BOOT_BLOCK_BLOCKSIZE));
bb.bb_secstart = htole64(startblock);
bb.bb_flags = 0;
ALPHA_BOOT_BLOCK_CKSUM(&bb, &bb.bb_cksum);
if (params->flags & IB_SUNSUM)
sun_bootstrap(params, &bb);
if (params->flags & IB_VERBOSE) {
printf("Bootstrap start sector: %llu\n",
(unsigned long long)startblock);
printf("Bootstrap sector count: %llu\n",
(unsigned long long)le64toh(bb.bb_secsize));
printf("New boot block checksum: %#llx\n",
(unsigned long long)le64toh(bb.bb_cksum));
printf("%sriting bootstrap\n",
(params->flags & IB_NOWRITE) ? "Not w" : "W");
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
rv = pwrite(params->fsfd, bootstrapbuf, bootstrapsize,
startblock * ALPHA_BOOT_BLOCK_BLOCKSIZE);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if ((size_t)rv != bootstrapsize) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
}
if (params->flags & IB_VERBOSE)
printf("Writing boot block\n");
rv = pwrite(params->fsfd, &bb, sizeof(bb), ALPHA_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != sizeof(bb)) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
} else {
retval = 1;
}
done:
if (bootstrapbuf)
free(bootstrapbuf);
return (retval);
}
/*
* The Sun and alpha checksums overlay, and the Sun magic number also
* overlays the alpha checksum. If you think you are smart: stop here
* and do exercise one: figure out how to salt unimportant uint16_t
* words in mid-sector so that the alpha and sparc checksums match,
* and so the Sun magic number is embedded in the alpha checksum.
*
* The last uint64_t in the sector is the alpha arithmetic checksum.
* The last uint16_t in the sector is the sun xor checksum.
* The penultimate uint16_t in the sector is the sun magic number.
*
* A: 511 510 509 508 507 506 505 504
* S: 510 511 508 509 506 507 504 505
* 63 : : : 32:31 : : : 0
* | : : : \:| : : : |
* 7654321076543210765432107654321076543210765432107654321076543210
* |-- sparc --||-- sparc --|
* |-- checksum --||-- magic --|
* |----------------------- alpha checksum -----------------------|
* 1011111011011010
* b e d a
*/
static void
resum(ib_params *params, struct alpha_boot_block * const bb, uint16_t *bb16)
{
static uint64_t lastsum;
if (bb16 != NULL)
memcpy(bb, bb16, sizeof(*bb));
ALPHA_BOOT_BLOCK_CKSUM(bb, &bb->bb_cksum);
if (bb16 != NULL)
memcpy(bb16, bb, sizeof(*bb));
if ((params->flags & IB_VERBOSE) && lastsum != bb->bb_cksum)
printf("alpha checksum now %016llx\n",
(unsigned long long)le64toh(bb->bb_cksum));
lastsum = bb->bb_cksum;
}
static void
sun_bootstrap(ib_params *params, struct alpha_boot_block * const bb)
{
# define BB_ADJUST_OFFSET 64
static char our_int16s[] = "\2\3\6\7\12";
uint16_t i, j, chkdelta, sunsum, bb16[256];
/*
* Theory: the alpha checksum is adjusted so bits 47:32 add up
* to the Sun magic number. Then, another adjustment is computed
* so bits 63:48 add up to the Sun checksum, and applied in pieces
* so it changes the alpha checksum but not the Sun value.
*
* Note: using memcpy(3) instead of a union as a strict c89/c9x
* conformance experiment and to avoid a public interface delta.
*/
assert(sizeof(bb16) == sizeof(*bb));
memcpy(bb16, bb, sizeof(bb16));
for (i = 0; our_int16s[i]; ++i) {
j = BB_ADJUST_OFFSET + our_int16s[i];
if (bb16[j]) {
warnx("Non-zero bits %04x in bytes %d..%d",
bb16[j], j * 2, j * 2 + 1);
bb16[j] = 0;
resum(params, bb, bb16);
}
}
/*
* Make alpha checksum <47:32> come out to the sun magic.
*/
bb16[BB_ADJUST_OFFSET + 2] = htobe16(SUN_DKMAGIC) - bb16[254];
resum(params, bb, bb16);
sunsum = compute_sunsum(bb16); /* might be the final value */
if (params->flags & IB_VERBOSE)
printf("target sun checksum is %04x\n", sunsum);
/*
* Arrange to have alpha 63:48 add up to the sparc checksum.
*/
chkdelta = sunsum - bb16[255];
bb16[BB_ADJUST_OFFSET + 3] = chkdelta >> 1;
bb16[BB_ADJUST_OFFSET + 7] = chkdelta >> 1;
/*
* By placing half the correction in two different uint64_t words at
* positions 63:48, the sparc sum will not change but the alpha sum
* will have the full correction, but only if the target adjustment
* was even. If it was odd, reverse propagate the carry one place.
*/
if (chkdelta & 1) {
if (params->flags & IB_VERBOSE)
printf("target adjustment %04x was odd, correcting\n",
chkdelta);
assert(bb16[BB_ADJUST_OFFSET + 6] == 0);
assert(bb16[BB_ADJUST_OFFSET + 012] == 0);
bb16[BB_ADJUST_OFFSET + 6] += 0x8000;
bb16[BB_ADJUST_OFFSET + 012] += 0x8000;
}
resum(params, bb, bb16);
if (params->flags & IB_VERBOSE)
printf("final harmonized checksum: %016llx\n",
(unsigned long long)le64toh(bb->bb_cksum));
check_sparc(bb, "Final");
}
static void
check_sparc(const struct alpha_boot_block * const bb, const char *when)
{
uint16_t bb16[256];
#define wmsg "%s sparc %s 0x%04x invalid, expected 0x%04x"
memcpy(bb16, bb, sizeof(bb16));
if (compute_sunsum(bb16) != bb16[255])
warnx(wmsg, when, "checksum", bb16[255], compute_sunsum(bb16));
if (bb16[254] != htobe16(SUN_DKMAGIC))
warnx(wmsg, when, "magic number", bb16[254],
htobe16(SUN_DKMAGIC));
}

View File

@@ -0,0 +1,173 @@
/* $NetBSD: amiga.c,v 1.7 2010/01/14 16:27:49 tsutsui Exp $ */
/*-
* Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Michael Hitch.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: amiga.c,v 1.7 2010/01/14 16:27:49 tsutsui Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "installboot.h"
/* XXX Must be kept in sync with bbstart.s! */
#define CMDLN_LOC 0x10
#define CMDLN_LEN 0x20
#define CHKSUMOFFS 1
u_int32_t chksum(u_int32_t *, int);
static int amiga_setboot(ib_params *);
struct ib_mach ib_mach_amiga =
{ "amiga", amiga_setboot, no_clearboot, no_editboot,
IB_STAGE1START | IB_STAGE2START | IB_COMMAND };
static int
amiga_setboot(ib_params *params)
{
int retval;
ssize_t rv;
char *dline;
int sumlen;
u_int32_t sum2, sum16;
struct stat bootstrapsb;
u_int32_t block[128*16];
retval = 0;
if (fstat(params->s1fd, &bootstrapsb) == -1) {
warn("Examining `%s'", params->stage1);
goto done;
}
if (!S_ISREG(bootstrapsb.st_mode)) {
warnx("`%s' must be a regular file", params->stage1);
goto done;
}
rv = pread(params->s1fd, &block, sizeof(block), 0);
if (rv == -1) {
warn("Reading `%s'", params->stage1);
goto done;
} else if (rv != sizeof(block)) {
warnx("Reading `%s': short read", params->stage1);
goto done;
}
/* XXX the choices should not be hardcoded */
sum2 = chksum(block, 1024/4);
sum16 = chksum(block, 8192/4);
if (sum16 == 0xffffffff) {
sumlen = 8192/4;
} else if (sum2 == 0xffffffff) {
sumlen = 1024/4;
} else {
errx(1, "%s: wrong checksum", params->stage1);
/* NOTREACHED */
}
if (sum2 == sum16) {
warnx("eek - both sums are the same");
}
if (params->flags & IB_COMMAND) {
dline = (char *)&(block[CMDLN_LOC/4]);
/* XXX keep the default default line in sync with bbstart.s */
if (strcmp(dline, "netbsd -ASn2") != 0) {
errx(1, "Old bootblock version? Can't change command line.");
}
(void)strncpy(dline, params->command, CMDLN_LEN-1);
block[1] = 0;
block[1] = 0xffffffff - chksum(block, sumlen);
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
if (params->flags & IB_VERBOSE)
printf("Writing boot block\n");
rv = pwrite(params->fsfd, &block, sizeof(block), 0);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != sizeof(block)) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
} else {
retval = 1;
}
done:
return (retval);
}
u_int32_t
chksum(block, size)
u_int32_t *block;
int size;
{
u_int32_t sum, lastsum;
int i;
sum = 0;
for (i=0; i<size; i++) {
lastsum = sum;
sum += htobe32(block[i]);
if (sum < lastsum)
++sum;
}
return sum;
}

View File

@@ -0,0 +1,145 @@
/* $NetBSD: emips.c,v 1.1 2011/01/26 01:18:55 pooka Exp $ */
/*-
* Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Simon Burge.
*
* 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.
*/
/*
* Copyright (c) 1999 Ross Harvey. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ross Harvey
* for the NetBSD Project.
* 4. 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.
*/
/*
* Copyright (c) 1999 Christopher G. Demetriou. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christopher G. Demetriou
* for the NetBSD Project.
* 4. 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 <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: emips.c,v 1.1 2011/01/26 01:18:55 pooka Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/exec_elf.h>
#include "installboot.h"
static int emips_clearboot(ib_params *);
static int emips_setboot(ib_params *);
struct ib_mach ib_mach_emips =
{ "emips", emips_setboot, emips_clearboot, no_editboot,
IB_STAGE1START | IB_APPEND | IB_SUNSUM };
static int
emips_clearboot(ib_params *params)
{
/* Nothing to do */
return (1);
}
static int
emips_setboot(ib_params *params)
{
/* Nothing to do */
return (1);
}

View File

@@ -0,0 +1,62 @@
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: ews4800mips.c,v 1.2 2006/02/18 10:08:07 dsl Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <unistd.h>
#include <err.h>
#include <stdio.h>
#include "installboot.h"
static int ews4800mips_setboot(ib_params *);
struct ib_mach ib_mach_ews4800mips =
{ "ews4800mips", ews4800mips_setboot, no_clearboot, no_editboot, 0};
struct bbinfo_params ews4800mips_bbparams = {
EWS4800MIPS_BBINFO_MAGIC,
EWS4800MIPS_BOOT_BLOCK_OFFSET,
EWS4800MIPS_BOOT_BLOCK_BLOCKSIZE,
EWS4800MIPS_BOOT_BLOCK_MAX_SIZE,
0,
BBINFO_BIG_ENDIAN,
};
static int
ews4800mips_setboot(ib_params *params)
{
u_int8_t buf[EWS4800MIPS_BOOT_BLOCK_MAX_SIZE];
int rv;
rv = pread(params->s1fd, buf, sizeof buf, 0);
if (rv == -1) {
warn("Reading `%s'", params->stage1);
return 0;
} else if (rv != sizeof buf) {
warnx("Reading `%s' : short read", params->stage1);
return 0;
}
if (params->flags & IB_NOWRITE)
return 1;
if (params->flags & IB_VERBOSE)
printf("Writing boot block\n");
rv = pwrite(params->fsfd, buf, sizeof buf, 0);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
return 0;
} else if (rv != sizeof buf) {
warnx("Writing `%s': short write", params->filesystem);
return 0;
}
return 1;
}

View File

@@ -0,0 +1,214 @@
/* $NetBSD: hp300.c,v 1.13 2011/02/10 23:25:11 tsutsui Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: hp300.c,v 1.13 2011/02/10 23:25:11 tsutsui Exp $");
#endif /* !__lint */
/* We need the target disklabel.h, not the hosts one..... */
#ifdef HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#include <nbinclude/sys/disklabel.h>
#else
#include <sys/disklabel.h>
#endif
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <md5.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
static int hp300_setboot(ib_params *);
struct ib_mach ib_mach_hp300 =
{ "hp300", hp300_setboot, no_clearboot, no_editboot, IB_APPEND };
static int
hp300_setboot(ib_params *params)
{
int retval;
uint8_t *bootstrap;
ssize_t rv;
struct partition *boot;
struct hp300_lifdir *lifdir;
int offset;
int i;
unsigned int secsize = HP300_SECTSIZE;
uint64_t boot_size, boot_offset;
struct disklabel *label;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
retval = 0;
bootstrap = MAP_FAILED;
label = malloc(params->sectorsize);
if (label == NULL) {
warn("Failed to allocate memory for disklabel");
goto done;
}
if (params->flags & IB_APPEND) {
if (!S_ISREG(params->fsstat.st_mode)) {
warnx(
"`%s' must be a regular file to append a bootstrap",
params->filesystem);
goto done;
}
boot_offset = roundup(params->fsstat.st_size, HP300_SECTSIZE);
} else {
/*
* The bootstrap can be well over 8k, and must go into a BOOT
* partition. Read NetBSD label to locate BOOT partition.
*/
if (pread(params->fsfd, label, params->sectorsize,
LABELSECTOR * params->sectorsize)
!= (ssize_t)params->sectorsize) {
warn("reading disklabel");
goto done;
}
/* And a quick validation - must be a big-endian label */
secsize = be32toh(label->d_secsize);
if (label->d_magic != htobe32(DISKMAGIC) ||
label->d_magic2 != htobe32(DISKMAGIC) ||
secsize == 0 || secsize & (secsize - 1) ||
be16toh(label->d_npartitions) > MAXMAXPARTITIONS) {
warnx("Invalid disklabel in %s", params->filesystem);
goto done;
}
i = be16toh(label->d_npartitions);
for (boot = label->d_partitions; ; boot++) {
if (--i < 0) {
warnx("No BOOT partition");
goto done;
}
if (boot->p_fstype == FS_BOOT)
break;
}
boot_size = be32toh(boot->p_size) * (uint64_t)secsize;
boot_offset = be32toh(boot->p_offset) * (uint64_t)secsize;
/*
* We put the entire LIF file into the BOOT partition even when
* it doesn't start at the beginning of the disk.
*
* Maybe we ought to be able to take a binary file and add
* it to the LIF filesystem.
*/
if (boot_size < (uint64_t)params->s1stat.st_size) {
warn("BOOT partition too small (%llu < %llu)",
(unsigned long long)boot_size,
(unsigned long long)params->s1stat.st_size);
goto done;
}
}
bootstrap = mmap(NULL, params->s1stat.st_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE, params->s1fd, 0);
if (bootstrap == MAP_FAILED) {
warn("mmaping `%s'", params->stage1);
goto done;
}
/* Relocate files, sanity check LIF directory on the way */
lifdir = (void *)(bootstrap + HP300_SECTSIZE * 2);
for (i = 0; i < 8; lifdir++, i++) {
int32_t addr = be32toh(lifdir->dir_addr);
int32_t limit = (params->s1stat.st_size - 1) / HP300_SECTSIZE + 1;
int32_t end = addr + be32toh(lifdir->dir_length);
if (end > limit) {
warnx("LIF entry %d larger (%d %d) than LIF file",
i, end, limit);
goto done;
}
if (addr != 0 && boot_offset != 0)
lifdir->dir_addr = htobe32(addr + boot_offset
/ HP300_SECTSIZE);
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
/* Write LIF volume header and directory to sectors 0 and 1 */
rv = pwrite(params->fsfd, bootstrap, 1024, 0);
if (rv != 1024) {
if (rv == -1)
warn("Writing `%s'", params->filesystem);
else
warnx("Writing `%s': short write", params->filesystem);
goto done;
}
/* Write files to BOOT partition */
offset = boot_offset <= HP300_SECTSIZE * 16 ? HP300_SECTSIZE * 16 : 0;
i = roundup(params->s1stat.st_size, secsize) - offset;
rv = pwrite(params->fsfd, bootstrap + offset, i, boot_offset + offset);
if (rv != i) {
if (rv == -1)
warn("Writing boot filesystem of `%s'",
params->filesystem);
else
warnx("Writing boot filesystem of `%s': short write",
params->filesystem);
goto done;
}
retval = 1;
done:
if (label != NULL)
free(label);
if (bootstrap != MAP_FAILED)
munmap(bootstrap, params->s1stat.st_size);
return retval;
}

View File

@@ -0,0 +1,220 @@
/* $NetBSD: hp700.c,v 1.4 2008/04/28 20:24:16 martin Exp $ */
/*-
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: hp700.c,v 1.4 2008/04/28 20:24:16 martin Exp $");
#endif /* !__lint */
/* We need the target disklabel.h, not the hosts one..... */
#ifdef HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#include <nbinclude/sys/disklabel.h>
#else
#include <sys/disklabel.h>
#endif
#include <sys/param.h>
#include <sys/stat.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
#define HP700_LABELOFFSET 512
#define HP700_LABELSIZE 404 /* reserve 16 partitions */
#define HP700_BOOT_BLOCK_SIZE 8192
static int hp700_clearboot(ib_params *);
static int hp700_setboot(ib_params *);
struct ib_mach ib_mach_hp700 =
{ "hp700", hp700_setboot, hp700_clearboot, no_editboot, 0};
static int
hp700_clearboot(ib_params *params)
{
char bb[HP700_BOOT_BLOCK_SIZE];
int retval, eol;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
retval = 0;
/* read disklabel on the target disk */
rv = pread(params->fsfd, bb, sizeof bb, 0);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != sizeof bb) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
/* clear header */
memset(bb, 0, HP700_LABELOFFSET);
eol = HP700_LABELOFFSET + HP700_LABELSIZE;
memset(&bb[eol], 0, sizeof bb - eol);
if (params->flags & IB_VERBOSE) {
printf("%slearing bootstrap\n",
(params->flags & IB_NOWRITE) ? "Not c" : "C");
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
rv = pwrite(params->fsfd, bb, sizeof bb, 0);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != HP700_BOOT_BLOCK_SIZE) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
} else
retval = 1;
done:
return (retval);
}
static int
hp700_setboot(ib_params *params)
{
struct stat bootstrapsb;
char bb[HP700_BOOT_BLOCK_SIZE];
struct {
char l_off[HP700_LABELOFFSET];
struct disklabel l;
char l_pad[HP700_BOOT_BLOCK_SIZE
- HP700_LABELOFFSET - sizeof(struct disklabel)];
} label;
unsigned int secsize, npart;
int retval;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
retval = 0;
/* read disklabel on the target disk */
rv = pread(params->fsfd, &label, HP700_BOOT_BLOCK_SIZE, 0);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != HP700_BOOT_BLOCK_SIZE) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
if (fstat(params->s1fd, &bootstrapsb) == -1) {
warn("Examining `%s'", params->stage1);
goto done;
}
if (!S_ISREG(bootstrapsb.st_mode)) {
warnx("`%s' must be a regular file", params->stage1);
goto done;
}
/* check if valid disklabel exists */
secsize = be32toh(label.l.d_secsize);
npart = be16toh(label.l.d_npartitions);
if (label.l.d_magic != htobe32(DISKMAGIC) ||
label.l.d_magic2 != htobe32(DISKMAGIC) ||
secsize == 0 || secsize & (secsize - 1) ||
npart > MAXMAXPARTITIONS) {
warnx("No disklabel in `%s'", params->filesystem);
/* then check if boot partition exists */
} else if (npart < 1 || label.l.d_partitions[0].p_size == 0) {
warnx("Partition `a' doesn't exist in %s", params->filesystem);
/* check if the boot partition is below 2GB */
} else if (be32toh(label.l.d_partitions[0].p_offset) +
be32toh(label.l.d_partitions[0].p_size) >
((unsigned)2*1024*1024*1024) / secsize) {
warnx("WARNING: Partition `a' of `%s' exceeds 2GB boundary.",
params->filesystem);
warnx("WARNING: It won't boot since hp700 PDC can handle only 2GB.");
}
/* read boot loader */
memset(&bb, 0, sizeof bb);
rv = read(params->s1fd, &bb, sizeof bb);
if (rv == -1) {
warn("Reading `%s'", params->stage1);
goto done;
}
/* then, overwrite disklabel */
memcpy(&bb[HP700_LABELOFFSET], &label.l, HP700_LABELSIZE);
if (params->flags & IB_VERBOSE) {
printf("Bootstrap start sector: %#x\n", 0);
printf("Bootstrap byte count: %#zx\n", rv);
printf("%sriting bootstrap\n",
(params->flags & IB_NOWRITE) ? "Not w" : "W");
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
/* write boot loader and disklabel into the target disk */
rv = pwrite(params->fsfd, &bb, HP700_BOOT_BLOCK_SIZE, 0);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != HP700_BOOT_BLOCK_SIZE) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
} else
retval = 1;
done:
return (retval);
}

View File

@@ -0,0 +1,552 @@
/* $NetBSD: i386.c,v 1.37 2011/08/14 17:50:17 christos Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: i386.c,v 1.37 2011/08/14 17:50:17 christos Exp $");
#endif /* !__lint */
#include <sys/param.h>
#ifndef HAVE_NBTOOL_CONFIG_H
#include <sys/ioctl.h>
#include <sys/dkio.h>
#endif
#include <assert.h>
#include <errno.h>
#include <err.h>
#include <md5.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
static const struct console_name {
const char *name; /* Name of console selection */
const int dev; /* value matching CONSDEV_* from sys/arch/i386/stand/lib/libi386.h */
} consoles[] = {
{ "pc", 0 /* CONSDEV_PC */ },
{ "com0", 1 /* CONSDEV_COM0 */ },
{ "com1", 2 /* CONSDEV_COM1 */ },
{ "com2", 3 /* CONSDEV_COM2 */ },
{ "com3", 4 /* CONSDEV_COM3 */ },
{ "com0kbd", 5 /* CONSDEV_COM0KBD */ },
{ "com1kbd", 6 /* CONSDEV_COM1KBD */ },
{ "com2kbd", 7 /* CONSDEV_COM2KBD */ },
{ "com3kbd", 8 /* CONSDEV_COM3KBD */ },
{ "auto", -1 /* CONSDEV_AUTO */ },
};
static int i386_setboot(ib_params *);
static int i386_editboot(ib_params *);
struct ib_mach ib_mach_i386 =
{ "i386", i386_setboot, no_clearboot, i386_editboot,
IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | IB_CONSADDR |
IB_KEYMAP | IB_PASSWORD | IB_TIMEOUT |
IB_MODULES | IB_BOOTCONF };
struct ib_mach ib_mach_amd64 =
{ "amd64", i386_setboot, no_clearboot, i386_editboot,
IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | IB_CONSADDR |
IB_KEYMAP | IB_PASSWORD | IB_TIMEOUT |
IB_MODULES | IB_BOOTCONF };
/*
* Attempting to write the 'labelsector' (or a sector near it - within 8k?)
* using the non-raw disk device fails silently. This can be detected (today)
* by doing a fsync() and a read back.
* This is very likely to affect installboot, indeed the code may need to
* be written into the 'labelsector' itself - especially on non-512 byte media.
* We do all writes with a read verify.
* If EROFS is returned we also try to enable writes to the label sector.
* (Maybe these functions should be in the generic part of installboot.)
*/
static int
pwrite_validate(int fd, const void *buf, size_t n_bytes, off_t offset)
{
void *r_buf;
ssize_t rv;
r_buf = malloc(n_bytes);
if (r_buf == NULL)
return -1;
rv = pwrite(fd, buf, n_bytes, offset);
if (rv == -1) {
free(r_buf);
return -1;
}
fsync(fd);
if (pread(fd, r_buf, rv, offset) == rv && memcmp(r_buf, buf, rv) == 0) {
free(r_buf);
return rv;
}
free(r_buf);
errno = EROFS;
return -1;
}
static int
write_boot_area(ib_params *params, uint8_t *buf, size_t len)
{
int rv, i;
/*
* Writing the 'label' sector (likely to be bytes 512-1023) could
* fail, so we try to avoid writing that area.
* Unfortunately, if we are accessing the raw disk, and the sector
* size is larger than 512 bytes that is also doomed.
* See how we get on....
*
* NB: Even if the physical sector size is not 512, the space for
* the label is 512 bytes from the start of the disk.
* So all the '512' constants in these functions are correct.
*/
/* Write out first 512 bytes - the pbr code */
rv = pwrite_validate(params->fsfd, buf, 512, 0);
if (rv == 512) {
/* That worked, do the rest */
if (len == 512)
return 1;
len -= 512 * 2;
rv = pwrite_validate(params->fsfd, buf + 512 * 2, len, 512 * 2);
if (rv != (ssize_t)len)
goto bad_write;
return 1;
}
if (rv != -1 || (errno != EINVAL && errno != EROFS))
goto bad_write;
if (errno == EINVAL) {
/* Assume the failure was due to to the sector size > 512 */
rv = pwrite_validate(params->fsfd, buf, len, 0);
if (rv == (ssize_t)len)
return 1;
if (rv != -1 || (errno != EROFS))
goto bad_write;
}
#ifdef DIOCWLABEL
/* Pesky label is protected, try to unprotect it */
i = 1;
rv = ioctl(params->fsfd, DIOCWLABEL, &i);
if (rv != 0) {
warn("Cannot enable writes to the label sector");
return 0;
}
/* Try again with label write-enabled */
rv = pwrite_validate(params->fsfd, buf, len, 0);
/* Reset write-protext */
i = 0;
ioctl(params->fsfd, DIOCWLABEL, &i);
if (rv == (ssize_t)len)
return 1;
#endif
bad_write:
if (rv == -1)
warn("Writing `%s'", params->filesystem);
else
warnx("Writing `%s': short write, %u bytes",
params->filesystem, rv);
return 0;
}
static void
show_i386_boot_params(struct x86_boot_params *bpp)
{
size_t i;
printf("Boot options: ");
printf("timeout %d, ", le32toh(bpp->bp_timeout));
printf("flags %x, ", le32toh(bpp->bp_flags));
printf("speed %d, ", le32toh(bpp->bp_conspeed));
printf("ioaddr %x, ", le32toh(bpp->bp_consaddr));
for (i = 0; i < __arraycount(consoles); i++) {
if (consoles[i].dev == (int)le32toh(bpp->bp_consdev))
break;
}
if (i == __arraycount(consoles))
printf("console %d\n", le32toh(bpp->bp_consdev));
else
printf("console %s\n", consoles[i].name);
if (bpp->bp_keymap[0])
printf(" keymap %s\n", bpp->bp_keymap);
}
static int
is_zero(const uint8_t *p, unsigned int len)
{
return len == 0 || (p[0] == 0 && memcmp(p, p + 1, len - 1) == 0);
}
static int
update_i386_boot_params(ib_params *params, struct x86_boot_params *bpp)
{
struct x86_boot_params bp;
uint32_t bplen;
size_t i;
bplen = le32toh(bpp->bp_length);
if (bplen > sizeof bp)
/* Ignore pad space in bootxx */
bplen = sizeof bp;
/* Take (and update) local copy so we handle size mismatches */
memset(&bp, 0, sizeof bp);
memcpy(&bp, bpp, bplen);
if (params->flags & IB_TIMEOUT)
bp.bp_timeout = htole32(params->timeout);
if (params->flags & IB_RESETVIDEO)
bp.bp_flags ^= htole32(X86_BP_FLAGS_RESET_VIDEO);
if (params->flags & IB_CONSPEED)
bp.bp_conspeed = htole32(params->conspeed);
if (params->flags & IB_CONSADDR)
bp.bp_consaddr = htole32(params->consaddr);
if (params->flags & IB_CONSOLE) {
for (i = 0; i < __arraycount(consoles); i++)
if (strcmp(consoles[i].name, params->console) == 0)
break;
if (i == __arraycount(consoles)) {
warnx("invalid console name, valid names are:");
(void)fprintf(stderr, "\t%s", consoles[0].name);
for (i = 1; consoles[i].name != NULL; i++)
(void)fprintf(stderr, ", %s", consoles[i].name);
(void)fprintf(stderr, "\n");
return 1;
}
bp.bp_consdev = htole32(consoles[i].dev);
}
if (params->flags & IB_PASSWORD) {
if (params->password[0]) {
MD5_CTX md5ctx;
MD5Init(&md5ctx);
MD5Update(&md5ctx, params->password,
strlen(params->password));
MD5Final(bp.bp_password, &md5ctx);
bp.bp_flags |= htole32(X86_BP_FLAGS_PASSWORD);
} else {
memset(&bp.bp_password, 0, sizeof bp.bp_password);
bp.bp_flags &= ~htole32(X86_BP_FLAGS_PASSWORD);
}
}
if (params->flags & IB_KEYMAP)
strlcpy(bp.bp_keymap, params->keymap, sizeof bp.bp_keymap);
if (params->flags & IB_MODULES)
bp.bp_flags ^= htole32(X86_BP_FLAGS_NOMODULES);
if (params->flags & IB_BOOTCONF)
bp.bp_flags ^= htole32(X86_BP_FLAGS_NOBOOTCONF);
if (params->flags & (IB_NOWRITE | IB_VERBOSE))
show_i386_boot_params(&bp);
/* Check we aren't trying to set anything we can't save */
if (!is_zero((char *)&bp + bplen, sizeof bp - bplen)) {
warnx("Patch area in stage1 bootstrap is too small");
return 1;
}
memcpy(bpp, &bp, bplen);
return 0;
}
static int
i386_setboot(ib_params *params)
{
unsigned int u;
ssize_t rv;
uint32_t *magic, expected_magic;
union {
struct mbr_sector mbr;
uint8_t b[8192];
} disk_buf, bootstrap;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
/*
* There is only 8k of space in a FFSv1 partition (and ustarfs)
* so ensure we don't splat over anything important.
*/
if (params->s1stat.st_size > (off_t)(sizeof bootstrap)) {
warnx("stage1 bootstrap `%s' (%u bytes) is larger than 8192 bytes",
params->stage1, (unsigned int)params->s1stat.st_size);
return 0;
}
if (params->s1stat.st_size < 3 * 512 && params->s1stat.st_size != 512) {
warnx("stage1 bootstrap `%s' (%u bytes) is too small",
params->stage1, (unsigned int)params->s1stat.st_size);
return 0;
}
/* Read in the existing disk header and boot code */
rv = pread(params->fsfd, &disk_buf, sizeof (disk_buf), 0);
if (rv != sizeof(disk_buf)) {
if (rv == -1)
warn("Reading `%s'", params->filesystem);
else
warnx("Reading `%s': short read, %ld bytes"
" (should be %ld)", params->filesystem, (long)rv,
(long)sizeof(disk_buf));
return 0;
}
if (disk_buf.mbr.mbr_magic != le16toh(MBR_MAGIC)) {
if (params->flags & IB_VERBOSE) {
printf(
"Ignoring PBR with invalid magic in sector 0 of `%s'\n",
params->filesystem);
}
memset(&disk_buf, 0, 512);
}
/* Read the new bootstrap code. */
rv = pread(params->s1fd, &bootstrap, params->s1stat.st_size, 0);
if (rv != params->s1stat.st_size) {
if (rv == -1)
warn("Reading `%s'", params->stage1);
else
warnx("Reading `%s': short read, %ld bytes"
" (should be %ld)", params->stage1, (long)rv,
(long)params->s1stat.st_size);
return 0;
}
/*
* The bootstrap code is either 512 bytes for booting FAT16, or best
* part of 8k (with bytes 512-1023 all zeros).
*/
if (params->s1stat.st_size == 512) {
/* Magic number is at end of pbr code */
magic = (void *)(bootstrap.b + 512 - 16 + 4);
expected_magic = htole32(X86_BOOT_MAGIC_FAT);
} else {
/* Magic number is at start of sector following label */
magic = (void *)(bootstrap.b + 512 * 2 + 4);
expected_magic = htole32(X86_BOOT_MAGIC_1);
/*
* For a variety of reasons we restrict our 'normal' partition
* boot code to a size which enable it to be used as mbr code.
* IMHO this is bugus (dsl).
*/
if (!is_zero(bootstrap.b + 512-2-64, 64)) {
warnx("Data in mbr partition table of new bootstrap");
return 0;
}
if (!is_zero(bootstrap.b + 512, 512)) {
warnx("Data in label part of new bootstrap");
return 0;
}
/* Copy mbr table and label from existing disk buffer */
memcpy(bootstrap.b + 512-2-64, disk_buf.b + 512-2-64, 64);
memcpy(bootstrap.b + 512, disk_buf.b + 512, 512);
}
/* Validate the 'magic number' that marks the parameter block */
if (*magic != expected_magic) {
warnx("Invalid magic in stage1 bootstrap %x != %x",
*magic, expected_magic);
return 0;
}
/*
* If the partition has a FAT (or NTFS) filesystem, then we must
* preserve the BIOS Parameter Block (BPB).
* It is also very likely that there isn't 8k of space available
* for (say) bootxx_msdos, and that blindly installing it will trash
* the FAT filesystem.
* To avoid this we check the number of 'reserved' sectors to ensure
* there there is enough space.
* Unfortunately newfs(8) doesn't (yet) splat the BPB (which is
* effectively the FAT superblock) when a filesystem is initailised
* so this code tends to complain rather too often,
* Specifying 'installboot -f' will delete the old BPB info.
*/
if (!(params->flags & IB_FORCE)) {
#define USE_F ", use -f (may invalidate filesystem)"
/*
* For FAT compatibility, the pbr code starts 'jmp xx; nop'
* followed by the BIOS Parameter Block (BPB).
* The 2nd byte (jump offset) is the size of the nop + BPB.
*/
if (bootstrap.b[0] != 0xeb || bootstrap.b[2] != 0x90) {
warnx("No BPB in new bootstrap %02x:%02x:%02x" USE_F,
bootstrap.b[0], bootstrap.b[1], bootstrap.b[2]);
return 0;
}
/* Find size of old BPB, and copy into new bootcode */
if (!is_zero(disk_buf.b + 3 + 8, disk_buf.b[1] - 1 - 8)) {
struct mbr_bpbFAT16 *bpb = (void *)(disk_buf.b + 3 + 8);
/* Check enough space before the FAT for the bootcode */
u = le16toh(bpb->bpbBytesPerSec)
* le16toh(bpb->bpbResSectors);
if (u != 0 && u < params->s1stat.st_size) {
warnx("Insufficient reserved space before FAT "
"(%u bytes available)" USE_F, u);
return 0;
}
/* Check we have enough space for the old bpb */
if (disk_buf.b[1] > bootstrap.b[1]) {
/* old BPB is larger, allow if extra zeros */
if (!is_zero(disk_buf.b + 2 + bootstrap.b[1],
disk_buf.b[1] - bootstrap.b[1])) {
warnx("Old BPB too big" USE_F);
return 0;
}
u = bootstrap.b[1];
} else {
/* Old BPB is shorter, leave zero filled */
u = disk_buf.b[1];
}
memcpy(bootstrap.b + 2, disk_buf.b + 2, u);
}
#undef USE_F
}
/*
* Fill in any user-specified options into the
* struct x86_boot_params
* that follows the magic number.
* See sys/arch/i386/stand/bootxx/bootxx.S for more information.
*/
if (update_i386_boot_params(params, (void *)(magic + 1)))
return 0;
if (params->flags & IB_NOWRITE) {
return 1;
}
/* Copy new bootstrap data into disk buffer, ignoring label area */
memcpy(&disk_buf, &bootstrap, 512);
if (params->s1stat.st_size > 512 * 2) {
memcpy(disk_buf.b + 2 * 512, bootstrap.b + 2 * 512,
params->s1stat.st_size - 2 * 512);
/* Zero pad to 512 byte sector boundary */
memset(disk_buf.b + params->s1stat.st_size, 0,
(8192 - params->s1stat.st_size) & 511);
}
return write_boot_area(params, disk_buf.b, sizeof disk_buf.b);
}
static int
i386_editboot(ib_params *params)
{
int retval;
uint8_t buf[512];
ssize_t rv;
uint32_t magic;
uint32_t offset;
struct x86_boot_params *bpp;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
retval = 0;
/*
* Read in the existing bootstrap.
* Look in any of the first 4 sectors.
*/
bpp = NULL;
for (offset = 0; offset < 4 * 512; offset += 512) {
rv = pread(params->fsfd, &buf, sizeof buf, offset);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != sizeof buf) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
/* Magic number is 4 bytes in (to allow for a jmps) */
/* Also allow any of the magic numbers. */
magic = le32toh(*(uint32_t *)(buf + 4)) | 0xf;
if (magic != (X86_BOOT_MAGIC_1 | 0xf))
continue;
/* The parameters are just after the magic number */
bpp = (void *)(buf + 8);
break;
}
if (bpp == NULL) {
warnx("Invalid magic in existing bootstrap");
goto done;
}
/*
* Fill in any user-specified options into the
* struct x86_boot_params
* that's 8 bytes in from the start of the third sector.
* See sys/arch/i386/stand/bootxx/bootxx.S for more information.
*/
if (update_i386_boot_params(params, bpp))
goto done;
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
/*
* Write boot code back
*/
rv = pwrite(params->fsfd, buf, sizeof buf, offset);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != sizeof buf) {
warnx("Writing `%s': short write, %zd bytes (should be %zu)",
params->filesystem, rv, sizeof(buf));
goto done;
}
retval = 1;
done:
return retval;
}

View File

@@ -0,0 +1,250 @@
/* $NetBSD: landisk.c,v 1.5 2009/05/07 07:03:39 lukem Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: landisk.c,v 1.5 2009/05/07 07:03:39 lukem Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <md5.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
static int landisk_setboot(ib_params *);
struct ib_mach ib_mach_landisk =
{ "landisk", landisk_setboot, no_clearboot, no_editboot,
IB_TIMEOUT };
static int
landisk_setboot(ib_params *params)
{
struct mbr_sector mbr;
struct landisk_boot_params bp, *bpp;
uint8_t *bootstrapbuf;
ssize_t rv;
uint32_t magic;
size_t bootstrapsize;
int retval, i;
uint32_t bplen;
int bpbsize;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
retval = 0;
bootstrapbuf = NULL;
/*
* There is only 8k of space in a FFSv1 partition (and ustarfs)
* so ensure we don't splat over anything important.
*/
if (params->s1stat.st_size > 8192) {
warnx("stage1 bootstrap `%s' is larger than 8192 bytes",
params->stage1);
goto done;
}
/*
* Read in the existing MBR.
*/
rv = pread(params->fsfd, &mbr, sizeof(mbr), MBR_BBSECTOR);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != sizeof(mbr)) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
if (mbr.mbr_magic != le16toh(MBR_MAGIC)) {
if (params->flags & IB_VERBOSE) {
printf(
"Ignoring MBR with invalid magic in sector 0 of `%s'\n",
params->filesystem);
}
memset(&mbr, 0, sizeof(mbr));
}
/*
* Allocate a buffer, with space to round up the input file
* to the next block size boundary, and with space for the boot
* block.
*/
bootstrapsize = roundup(params->s1stat.st_size, 512);
bootstrapbuf = malloc(bootstrapsize);
if (bootstrapbuf == NULL) {
warn("Allocating %zu bytes", bootstrapsize);
goto done;
}
memset(bootstrapbuf, 0, bootstrapsize);
/*
* Read the file into the buffer.
*/
rv = pread(params->s1fd, bootstrapbuf, params->s1stat.st_size, 0);
if (rv == -1) {
warn("Reading `%s'", params->stage1);
goto done;
} else if (rv != params->s1stat.st_size) {
warnx("Reading `%s': short read", params->stage1);
goto done;
}
magic = *(uint32_t *)(bootstrapbuf + 512 * 2 + 4);
if (magic != htole32(LANDISK_BOOT_MAGIC_1)) {
warnx("Invalid magic in stage1 boostrap %x != %x",
magic, htole32(LANDISK_BOOT_MAGIC_1));
goto done;
}
/*
* Determine size of BIOS Parameter Block (BPB) to copy from
* original MBR to the temporary buffer by examining the first
* few instruction in the new bootblock. Supported values:
* 2b a0 11 jmp ENDOF(mbr_bpbFAT32)+1, nop
* (anything else) ; don't preserve
*/
bpbsize = 0;
#if 0
if (bootstrapbuf[1] == 0xa0 && bootstrapbuf[2] == 0x11 &&
(bootstrapbuf[0] == 0x2b /*|| bootstrapbuf[0] == 0x1d*/)) {
bpbsize = bootstrapbuf[0] + 2 - MBR_BPB_OFFSET;
}
#endif
/*
* Ensure bootxx hasn't got any code or data (i.e, non-zero bytes) in
* the partition table.
*/
for (i = 0; i < (int)sizeof(mbr.mbr_parts); i++) {
if (*(uint8_t *)(bootstrapbuf + MBR_PART_OFFSET + i) != 0) {
warnx(
"Partition table has non-zero byte at offset %d in `%s'",
MBR_PART_OFFSET + i, params->stage1);
goto done;
}
}
#if 0
/*
* Copy the BPB and the partition table from the original MBR to the
* temporary buffer so that they're written back to the fs.
*/
if (bpbsize != 0) {
if (params->flags & IB_VERBOSE)
printf("Preserving %d (%#x) bytes of the BPB\n",
bpbsize, bpbsize);
(void)memcpy(bootstrapbuf + MBR_BPB_OFFSET, &mbr.mbr_bpb,
bpbsize);
}
#endif
memcpy(bootstrapbuf + MBR_PART_OFFSET, &mbr.mbr_parts,
sizeof(mbr.mbr_parts));
/*
* Fill in any user-specified options into the
* struct landisk_boot_params
* that's 8 bytes in from the start of the third sector.
* See sys/arch/landisk/stand/bootxx/bootxx.S for more information.
*/
bpp = (void *)(bootstrapbuf + 512 * 2 + 8);
bplen = le32toh(bpp->bp_length);
if (bplen > sizeof bp)
/* Ignore pad space in bootxx */
bplen = sizeof bp;
/* Take (and update) local copy so we handle size mismatches */
memset(&bp, 0, sizeof bp);
memcpy(&bp, bpp, bplen);
if (params->flags & IB_TIMEOUT)
bp.bp_timeout = htole32(params->timeout);
/* Check we aren't trying to set anything we can't save */
if (bplen < sizeof bp && memcmp((char *)&bp + bplen,
(char *)&bp + bplen + 1,
sizeof bp - bplen - 1) != 0) {
warnx("Patch area in stage1 bootstrap is too small");
goto done;
}
memcpy(bpp, &bp, bplen);
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
/*
* Write MBR code to sector zero.
*/
rv = pwrite(params->fsfd, bootstrapbuf, 512, 0);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != 512) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
}
/*
* Skip disklabel in sector 1 and write bootxx to sectors 2..N.
*/
rv = pwrite(params->fsfd, bootstrapbuf + 512 * 2,
bootstrapsize - 512 * 2, 512 * 2);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if ((size_t)rv != bootstrapsize - 512 * 2) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
}
retval = 1;
done:
if (bootstrapbuf)
free(bootstrapbuf);
return retval;
}

View File

@@ -0,0 +1,186 @@
/* $NetBSD: macppc.c,v 1.11 2008/05/24 19:15:21 tsutsui Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: macppc.c,v 1.11 2008/05/24 19:15:21 tsutsui Exp $");
#endif /* !__lint */
#include <sys/param.h>
#ifndef HAVE_NBTOOL_CONFIG_H
#include <sys/ioctl.h>
#include <sys/dkio.h>
#include <errno.h>
#endif
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
static struct bbinfo_params bbparams = {
MACPPC_BBINFO_MAGIC,
MACPPC_BOOT_BLOCK_OFFSET,
MACPPC_BOOT_BLOCK_BLOCKSIZE,
MACPPC_BOOT_BLOCK_MAX_SIZE,
0,
BBINFO_BIG_ENDIAN,
};
static int writeapplepartmap(ib_params *, struct bbinfo_params *, uint8_t *);
static int macppc_clearboot(ib_params *);
static int macppc_setboot(ib_params *);
struct ib_mach ib_mach_macppc =
{ "macppc", macppc_setboot, macppc_clearboot, no_editboot,
IB_STAGE2START };
static int
macppc_clearboot(ib_params *params)
{
assert(params != NULL);
/* XXX: maybe clear the apple partition map too? */
return (shared_bbinfo_clearboot(params, &bbparams, NULL));
}
static int
macppc_setboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_setboot(params, &bbparams, writeapplepartmap));
}
static int
writeapplepartmap(ib_params *params, struct bbinfo_params *bb_params,
uint8_t *bb)
{
struct apple_drvr_map dm;
struct apple_part_map_entry pme;
int rv;
assert (params != NULL);
assert (bb_params != NULL);
assert (bb != NULL);
if (params->flags & IB_NOWRITE)
return (1);
/* block 0: driver map */
if (pread(params->fsfd, &dm, MACPPC_BOOT_BLOCK_BLOCKSIZE, 0) !=
MACPPC_BOOT_BLOCK_BLOCKSIZE) {
warn("Can't read sector 0 of `%s'", params->filesystem);
return (0);
}
dm.sbSig = htobe16(APPLE_DRVR_MAP_MAGIC);
dm.sbBlockSize = htobe16(512);
dm.sbBlkCount = htobe32(0);
rv = pwrite(params->fsfd, &dm, MACPPC_BOOT_BLOCK_BLOCKSIZE, 0);
#ifdef DIOCWLABEL
if (rv == -1 && errno == EROFS) {
/*
* block 0 is LABELSECTOR which might be protected by
* bounds_check_with_label(9).
*/
int enable;
enable = 1;
rv = ioctl(params->fsfd, DIOCWLABEL, &enable);
if (rv != 0) {
warn("Cannot enable writes to the label sector");
return 0;
}
rv = pwrite(params->fsfd, &dm, MACPPC_BOOT_BLOCK_BLOCKSIZE, 0);
/* Reset write-protect. */
enable = 0;
(void)ioctl(params->fsfd, DIOCWLABEL, &enable);
}
#endif
if (rv != MACPPC_BOOT_BLOCK_BLOCKSIZE) {
warn("Can't write sector 0 of `%s'", params->filesystem);
return (0);
}
/* block 1: Apple Partition Map */
memset(&pme, 0, sizeof(pme));
pme.pmSig = htobe16(APPLE_PART_MAP_ENTRY_MAGIC);
pme.pmMapBlkCnt = htobe32(2);
pme.pmPyPartStart = htobe32(1);
pme.pmPartBlkCnt = htobe32(2);
pme.pmDataCnt = htobe32(2);
strlcpy(pme.pmPartName, "Apple", sizeof(pme.pmPartName));
strlcpy(pme.pmPartType, "Apple_partition_map", sizeof(pme.pmPartType));
pme.pmPartStatus = htobe32(0x37);
if (pwrite(params->fsfd, &pme, MACPPC_BOOT_BLOCK_BLOCKSIZE,
1 * MACPPC_BOOT_BLOCK_BLOCKSIZE) != MACPPC_BOOT_BLOCK_BLOCKSIZE) {
warn("Can't write Apple Partition Map into sector 1 of `%s'",
params->filesystem);
return (0);
}
/* block 2: NetBSD partition */
memset(&pme, 0, sizeof(pme));
pme.pmSig = htobe16(APPLE_PART_MAP_ENTRY_MAGIC);
pme.pmMapBlkCnt = htobe32(2);
pme.pmPyPartStart = htobe32(4);
pme.pmPartBlkCnt = htobe32(0x7fffffff);
pme.pmDataCnt = htobe32(0x7fffffff);
strlcpy(pme.pmPartName, "NetBSD", sizeof(pme.pmPartName));
strlcpy(pme.pmPartType, "NetBSD/macppc", sizeof(pme.pmPartType));
pme.pmPartStatus = htobe32(0x3b);
pme.pmBootSize = htobe32(roundup(params->s1stat.st_size, 512));
pme.pmBootLoad = htobe32(0x4000);
pme.pmBootEntry = htobe32(0x4000);
strlcpy(pme.pmProcessor, "PowerPC", sizeof(pme.pmProcessor));
if (pwrite(params->fsfd, &pme, MACPPC_BOOT_BLOCK_BLOCKSIZE,
2 * MACPPC_BOOT_BLOCK_BLOCKSIZE) != MACPPC_BOOT_BLOCK_BLOCKSIZE) {
warn("Can't write Apple Partition Map into sector 2 of `%s'",
params->filesystem);
return (0);
}
return (1);
}

View File

@@ -0,0 +1,166 @@
/* $NetBSD: news.c,v 1.7 2008/04/28 20:24:16 martin Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn and Izumi Tsutsui.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: news.c,v 1.7 2008/04/28 20:24:16 martin Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
static int news_copydisklabel(ib_params *, struct bbinfo_params *, uint8_t *);
static int news68k_clearboot(ib_params *);
static int news68k_setboot(ib_params *);
static int newsmips_clearboot(ib_params *);
static int newsmips_setboot(ib_params *);
struct ib_mach ib_mach_news68k =
{ "news68k", news68k_setboot, news68k_clearboot, no_editboot,
IB_STAGE2START };
struct ib_mach ib_mach_newsmips =
{ "newsmips", newsmips_setboot, newsmips_clearboot, no_editboot,
IB_STAGE2START };
/*
* news68k specific support
*/
static struct bbinfo_params news68k_bbparams = {
NEWS68K_BBINFO_MAGIC,
NEWS_BOOT_BLOCK_OFFSET, /* write all 8K (including disklabel) */
NEWS_BOOT_BLOCK_BLOCKSIZE,
NEWS_BOOT_BLOCK_MAX_SIZE,
0,
BBINFO_BIG_ENDIAN,
};
static int
news68k_clearboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_clearboot(params, &news68k_bbparams,
news_copydisklabel));
}
static int
news68k_setboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_setboot(params, &news68k_bbparams,
news_copydisklabel));
}
/*
* newsmips specific support
*/
static struct bbinfo_params newsmips_bbparams = {
NEWSMIPS_BBINFO_MAGIC,
NEWS_BOOT_BLOCK_OFFSET, /* write all 8K (including disklabel) */
NEWS_BOOT_BLOCK_BLOCKSIZE,
NEWS_BOOT_BLOCK_MAX_SIZE,
0,
BBINFO_BIG_ENDIAN,
};
static int
newsmips_clearboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_clearboot(params, &newsmips_bbparams,
news_copydisklabel));
}
static int
newsmips_setboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_setboot(params, &newsmips_bbparams,
news_copydisklabel));
}
/*
* news_copydisklabel --
* copy disklabel from existing location on disk into bootstrap,
* as the primary bootstrap contains the disklabel.
*/
static int
news_copydisklabel(ib_params *params, struct bbinfo_params *bbparams,
uint8_t *bb)
{
uint8_t boot00[NEWS_BOOT_BLOCK_BLOCKSIZE];
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(bbparams != NULL);
assert(bb != NULL);
/* Read label sector to copy disklabel from */
memset(boot00, 0, sizeof(boot00));
rv = pread(params->fsfd, boot00, sizeof(boot00), 0);
if (rv == -1) {
warn("Reading label sector from `%s'", params->filesystem);
return (0);
}
/* Copy disklabel */
memcpy(bb + NEWS_BOOT_BLOCK_LABELOFFSET,
boot00 + NEWS_BOOT_BLOCK_LABELOFFSET,
sizeof(boot00) - NEWS_BOOT_BLOCK_LABELOFFSET);
return (1);
}

View File

@@ -0,0 +1,267 @@
/* $NetBSD: next68k.c,v 1.7 2010/01/07 13:26:00 tsutsui Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight and Christian Limpach.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: next68k.c,v 1.7 2010/01/07 13:26:00 tsutsui Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <md5.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
static uint16_t nextstep_checksum(const void *, const void *);
static int next68k_setboot(ib_params *);
struct ib_mach ib_mach_next68k =
{ "next68k", next68k_setboot, no_clearboot, no_editboot, 0};
static uint16_t
nextstep_checksum(const void *vbuf, const void *vlimit)
{
const uint16_t *buf = vbuf;
const uint16_t *limit = vlimit;
u_int sum = 0;
while (buf < limit) {
sum += be16toh(*buf++);
}
sum += (sum >> 16);
return (sum & 0xffff);
}
static int
next68k_setboot(ib_params *params)
{
int retval, labelupdated;
uint8_t *bootbuf;
size_t bootsize;
ssize_t rv;
uint32_t cd_secsize;
int sec_netonb_mult;
struct next68k_disklabel *next68klabel;
uint16_t *checksum;
uint32_t fp, b0, b1;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
retval = 0;
labelupdated = 0;
bootbuf = NULL;
next68klabel = malloc(NEXT68K_LABEL_SIZE);
if (next68klabel == NULL) {
warn("Allocating %lu bytes", (unsigned long)NEXT68K_LABEL_SIZE);
goto done;
}
/*
* Read in the next68k disklabel
*/
rv = pread(params->fsfd, next68klabel, NEXT68K_LABEL_SIZE,
NEXT68K_LABEL_SECTOR * params->sectorsize + NEXT68K_LABEL_OFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
}
if (rv != NEXT68K_LABEL_SIZE) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
if (be32toh(next68klabel->cd_version) == NEXT68K_LABEL_CD_V3) {
checksum = &next68klabel->NEXT68K_LABEL_cd_v3_checksum;
} else {
checksum = &next68klabel->cd_checksum;
}
if (nextstep_checksum (next68klabel, checksum) !=
be16toh(*checksum)) {
warn("Disklabel checksum invalid on `%s'",
params->filesystem);
goto done;
}
cd_secsize = be32toh(next68klabel->cd_secsize);
sec_netonb_mult = (cd_secsize / params->sectorsize);
/*
* Allocate a buffer, with space to round up the input file
* to the next block size boundary, and with space for the boot
* block.
*/
bootsize = roundup(params->s1stat.st_size, cd_secsize);
bootbuf = malloc(bootsize);
if (bootbuf == NULL) {
warn("Allocating %zu bytes", bootsize);
goto done;
}
memset(bootbuf, 0, bootsize);
/*
* Read the file into the buffer.
*/
rv = pread(params->s1fd, bootbuf, params->s1stat.st_size, 0);
if (rv == -1) {
warn("Reading `%s'", params->stage1);
goto done;
} else if (rv != params->s1stat.st_size) {
warnx("Reading `%s': short read", params->stage1);
goto done;
}
if (bootsize > be16toh(next68klabel->cd_front) * cd_secsize -
NEXT68K_LABEL_SIZE) {
warnx("Boot program is larger than front porch space");
goto done;
}
fp = be16toh(next68klabel->cd_front);
b0 = be32toh(next68klabel->cd_boot_blkno[0]);
b1 = be32toh(next68klabel->cd_boot_blkno[1]);
if (b0 > fp)
b0 = fp;
if (b1 > fp)
b1 = fp;
if (((bootsize / cd_secsize) > b1 - b0) ||
((bootsize / cd_secsize) > fp - b1)) {
if (2 * bootsize > (fp * cd_secsize - NEXT68K_LABEL_SIZE))
/* can only fit one copy */
b0 = b1 = NEXT68K_LABEL_SIZE / cd_secsize;
else {
if (2 * bootsize > (fp * cd_secsize -
NEXT68K_LABEL_DEFAULTBOOT0_1 *
params->sectorsize))
/* can fit two copies starting after label */
b0 = NEXT68K_LABEL_SIZE / cd_secsize;
else
/* can fit two copies starting at default 1 */
b0 = NEXT68K_LABEL_DEFAULTBOOT0_1 /
sec_netonb_mult;
/* try to fit 2nd copy at default 2 */
b1 = NEXT68K_LABEL_DEFAULTBOOT0_2 / sec_netonb_mult;
if (fp < b1)
b1 = fp;
if (bootsize / cd_secsize > (fp - b1))
/* fit 2nd copy before front porch */
b1 = fp - bootsize / cd_secsize;
}
}
if (next68klabel->cd_boot_blkno[0] != (int32_t)htobe32(b0)) {
next68klabel->cd_boot_blkno[0] = htobe32(b0);
labelupdated = 1;
}
if (next68klabel->cd_boot_blkno[1] != (int32_t)htobe32(b1)) {
next68klabel->cd_boot_blkno[1] = htobe32(b1);
labelupdated = 1;
}
if (params->flags & IB_VERBOSE)
printf("Boot programm locations%s: %d %d\n",
labelupdated ? " updated" : "", b0 * sec_netonb_mult,
b1 * sec_netonb_mult);
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
/*
* Write the updated next68k disklabel
*/
if (labelupdated) {
if (params->flags & IB_VERBOSE)
printf ("Writing updated label\n");
*checksum = htobe16(nextstep_checksum (next68klabel,
checksum));
rv = pwrite(params->fsfd, next68klabel, NEXT68K_LABEL_SIZE,
NEXT68K_LABEL_SECTOR * params->sectorsize +
NEXT68K_LABEL_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
}
if (rv != NEXT68K_LABEL_SIZE) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
}
}
b0 *= sec_netonb_mult;
b1 *= sec_netonb_mult;
/*
* Write boot program to locations b0 and b1 (if different).
*/
for (;;) {
if (params->flags & IB_VERBOSE)
printf ("Writing boot program at %d\n", b0);
rv = pwrite(params->fsfd, bootbuf, bootsize,
b0 * params->sectorsize);
if (rv == -1) {
warn("Writing `%s' at %d", params->filesystem, b0);
goto done;
}
if ((size_t)rv != bootsize) {
warnx("Writing `%s' at %d: short write",
params->filesystem, b0);
goto done;
}
if (b0 == b1)
break;
b0 = b1;
}
retval = 1;
done:
if (bootbuf)
free(bootbuf);
if (next68klabel)
free(next68klabel);
return retval;
}

View File

@@ -0,0 +1,369 @@
/* $NetBSD: pmax.c,v 1.14 2009/04/05 11:55:39 lukem Exp $ */
/*-
* Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Simon Burge.
*
* 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.
*
* 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.
*/
/*
* Copyright (c) 1999 Ross Harvey. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ross Harvey
* for the NetBSD Project.
* 4. 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.
*/
/*
* Copyright (c) 1999 Christopher G. Demetriou. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christopher G. Demetriou
* for the NetBSD Project.
* 4. 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 <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: pmax.c,v 1.14 2009/04/05 11:55:39 lukem Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/exec_elf.h>
#include "installboot.h"
static int load_bootstrap(ib_params *, char **,
uint32_t *, uint32_t *, size_t *);
static int pmax_clearboot(ib_params *);
static int pmax_setboot(ib_params *);
struct ib_mach ib_mach_pmax =
{ "pmax", pmax_setboot, pmax_clearboot, no_editboot,
IB_STAGE1START | IB_APPEND | IB_SUNSUM };
static int
pmax_clearboot(ib_params *params)
{
struct pmax_boot_block bb;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(sizeof(struct pmax_boot_block) == PMAX_BOOT_BLOCK_BLOCKSIZE);
rv = pread(params->fsfd, &bb, sizeof(bb), PMAX_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
return (0);
} else if (rv != sizeof(bb)) {
warnx("Reading `%s': short read", params->filesystem);
return (0);
}
if (le32toh(bb.magic) != PMAX_BOOT_MAGIC) {
warnx(
"Old boot block magic number invalid; boot block invalid");
return (0);
}
bb.map[0].num_blocks = bb.map[0].start_block = bb.mode = 0;
bb.magic = htole32(PMAX_BOOT_MAGIC);
if (params->flags & IB_SUNSUM) {
uint16_t sum;
sum = compute_sunsum((uint16_t *)&bb);
if (! set_sunsum(params, (uint16_t *)&bb, sum))
return (0);
}
if (params->flags & IB_VERBOSE)
printf("%slearing boot block\n",
(params->flags & IB_NOWRITE) ? "Not c" : "C");
if (params->flags & IB_NOWRITE)
return (1);
rv = pwrite(params->fsfd, &bb, sizeof(bb), PMAX_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
return (0);
} else if (rv != sizeof(bb)) {
warnx("Writing `%s': short write", params->filesystem);
return (0);
}
return (1);
}
static int
pmax_setboot(ib_params *params)
{
struct pmax_boot_block bb;
uint32_t startblock;
int retval;
char *bootstrapbuf;
size_t bootstrapsize;
uint32_t bootstrapload, bootstrapexec;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
assert(sizeof(struct pmax_boot_block) == PMAX_BOOT_BLOCK_BLOCKSIZE);
retval = 0;
bootstrapbuf = NULL;
if (! load_bootstrap(params, &bootstrapbuf, &bootstrapload,
&bootstrapexec, &bootstrapsize))
goto done;
rv = pread(params->fsfd, &bb, sizeof(bb), PMAX_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != sizeof(bb)) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
/* fill in the updated boot block fields */
if (params->flags & IB_APPEND) {
if (! S_ISREG(params->fsstat.st_mode)) {
warnx(
"`%s' must be a regular file to append a bootstrap",
params->filesystem);
goto done;
}
startblock = howmany(params->fsstat.st_size,
PMAX_BOOT_BLOCK_BLOCKSIZE);
} else if (params->flags & IB_STAGE1START) {
startblock = params->s1start;
} else {
startblock = PMAX_BOOT_BLOCK_OFFSET / PMAX_BOOT_BLOCK_BLOCKSIZE
+ 1;
}
bb.map[0].start_block = htole32(startblock);
bb.map[0].num_blocks =
htole32(howmany(bootstrapsize, PMAX_BOOT_BLOCK_BLOCKSIZE));
bb.magic = htole32(PMAX_BOOT_MAGIC);
bb.load_addr = htole32(bootstrapload);
bb.exec_addr = htole32(bootstrapexec);
bb.mode = htole32(PMAX_BOOTMODE_CONTIGUOUS);
if (params->flags & IB_SUNSUM) {
uint16_t sum;
sum = compute_sunsum((uint16_t *)&bb);
if (! set_sunsum(params, (uint16_t *)&bb, sum))
goto done;
}
if (params->flags & IB_VERBOSE) {
printf("Bootstrap start sector: %u\n",
le32toh(bb.map[0].start_block));
printf("Bootstrap sector count: %u\n",
le32toh(bb.map[0].num_blocks));
printf("Bootstrap load address: %#x\n",
le32toh(bb.load_addr));
printf("Bootstrap exec address: %#x\n",
le32toh(bb.exec_addr));
printf("%sriting bootstrap\n",
(params->flags & IB_NOWRITE) ? "Not w" : "W");
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
rv = pwrite(params->fsfd, bootstrapbuf, bootstrapsize,
startblock * PMAX_BOOT_BLOCK_BLOCKSIZE);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if ((size_t)rv != bootstrapsize) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
}
if (params->flags & IB_VERBOSE)
printf("Writing boot block\n");
rv = pwrite(params->fsfd, &bb, sizeof(bb), PMAX_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != sizeof(bb)) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
} else {
retval = 1;
}
done:
if (bootstrapbuf)
free(bootstrapbuf);
return (retval);
}
#define MAX_SEGMENTS 10 /* We can load up to 10 segments */
struct seglist {
Elf32_Addr addr;
Elf32_Off f_offset;
Elf32_Word f_size;
};
static int
load_bootstrap(ib_params *params, char **data,
uint32_t *loadaddr, uint32_t *execaddr, size_t *len)
{
int i, nsegs;
Elf32_Addr lowaddr, highaddr;
Elf32_Ehdr ehdr;
Elf32_Phdr phdr;
struct seglist seglist[MAX_SEGMENTS];
if ((pread(params->s1fd, &ehdr, sizeof(ehdr), 0)) != sizeof(ehdr)) {
warn("Reading `%s'", params->stage1);
return (0);
}
if ((memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) ||
(ehdr.e_ident[EI_CLASS] != ELFCLASS32)) {
warnx("No ELF header in `%s'", params->stage1);
return (0);
}
nsegs = highaddr = 0;
lowaddr = (uint32_t) ULONG_MAX;
for (i = 0; i < le16toh(ehdr.e_phnum); i++) {
if (pread(params->s1fd, &phdr, sizeof(phdr),
(off_t) le32toh(ehdr.e_phoff) + i * sizeof(phdr))
!= sizeof(phdr)) {
warn("Reading `%s'", params->stage1);
return (0);
}
if (le32toh(phdr.p_type) != PT_LOAD)
continue;
seglist[nsegs].addr = le32toh(phdr.p_paddr);
seglist[nsegs].f_offset = le32toh(phdr.p_offset);
seglist[nsegs].f_size = le32toh(phdr.p_filesz);
nsegs++;
if (le32toh(phdr.p_paddr) < lowaddr)
lowaddr = le32toh(phdr.p_paddr);
if (le32toh(phdr.p_paddr) + le32toh(phdr.p_filesz) > highaddr)
highaddr = le32toh(phdr.p_paddr) +
le32toh(phdr.p_filesz);
}
*loadaddr = lowaddr;
*execaddr = le32toh(ehdr.e_entry);
*len = roundup(highaddr - lowaddr, PMAX_BOOT_BLOCK_BLOCKSIZE);
if ((*data = malloc(*len)) == NULL) {
warn("Allocating %lu bytes", (unsigned long) *len);
return (0);
}
/* Now load the bootstrap into memory */
for (i = 0; i < nsegs; i++) {
if ((Elf32_Word)pread(params->s1fd,
*data + seglist[i].addr - lowaddr,
seglist[i].f_size, (off_t)seglist[i].f_offset)
!= seglist[i].f_size) {
warn("Reading `%s'", params->stage1);
return (0);
}
}
return (1);
}

View File

@@ -0,0 +1,128 @@
/* $NetBSD: sparc.c,v 1.11 2008/04/28 20:24:16 martin Exp $ */
/*-
* Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Paul Kranenburg and Luke Mewburn.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: sparc.c,v 1.11 2008/04/28 20:24:16 martin Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
static struct bbinfo_params bbparams = {
SPARC_BBINFO_MAGIC,
SPARC_BOOT_BLOCK_OFFSET,
SPARC_BOOT_BLOCK_BLOCKSIZE,
SPARC_BOOT_BLOCK_MAX_SIZE,
32, /* leave room for a.out header */
BBINFO_BIG_ENDIAN,
};
static int sparc_clearheader(ib_params *, struct bbinfo_params *, uint8_t *);
static int sparc_setheader(ib_params *, struct bbinfo_params *, uint8_t *);
static int sparc_clearboot(ib_params *);
static int sparc_setboot(ib_params *);
struct ib_mach ib_mach_sparc =
{ "sparc", sparc_setboot, sparc_clearboot, no_editboot,
IB_STAGE2START };
static int
sparc_clearboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_clearboot(params, &bbparams, sparc_clearheader));
}
static int
sparc_setboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_setboot(params, &bbparams, sparc_setheader));
}
static int
sparc_clearheader(ib_params *params, struct bbinfo_params *bb_params,
uint8_t *bb)
{
assert(params != NULL);
assert(bb_params != NULL);
assert(bb != NULL);
memset(bb, 0, bb_params->headeroffset);
return (1);
}
static int
sparc_setheader(ib_params *params, struct bbinfo_params *bb_params, uint8_t *bb)
{
assert(params != NULL);
assert(bb_params != NULL);
assert(bb != NULL);
/*
* sun4c/sun4m PROMs require an a.out(5) format header.
* Old-style sun4 PROMs do not expect a header at all.
* To deal with this, we construct a header that is also executable
* code containing a forward branch that gets us past the 32-byte
* header where the actual code begins. In assembly:
* .word MAGIC ! a NOP
* ba,a start !
* .skip 24 ! pad
* start:
*/
#define SUN_MAGIC 0x01030107
#define SUN4_BASTART 0x30800007 /* i.e.: ba,a `start' */
*((uint32_t *)bb) = htobe32(SUN_MAGIC);
*((uint32_t *)bb + 1) = htobe32(SUN4_BASTART);
return (1);
}

View File

@@ -0,0 +1,185 @@
/* $NetBSD: sparc64.c,v 1.18 2010/01/14 16:27:49 tsutsui Exp $ */
/*-
* 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.
*
* 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.
*/
/*
* Copyright (c) 2002 Matthew R. Green
* 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.
*
* 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 <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: sparc64.c,v 1.18 2010/01/14 16:27:49 tsutsui Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
static int sparc64_clearboot(ib_params *);
static int sparc64_setboot(ib_params *);
struct ib_mach ib_mach_sparc64 =
{ "sparc64", sparc64_setboot, sparc64_clearboot, no_editboot, 0};
static int
sparc64_clearboot(ib_params *params)
{
char bb[SPARC64_BOOT_BLOCK_MAX_SIZE];
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
if (params->flags & (IB_STAGE1START | IB_STAGE2START)) {
warnx("`-b bno' and `-B bno' are not supported for %s",
params->machine->name);
return (0);
}
/* first check that it _could_ exist here */
rv = pread(params->fsfd, &bb, sizeof(bb), SPARC64_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
return (0);
} else if (rv != sizeof(bb)) {
warnx("Reading `%s': short read", params->filesystem);
return (0);
}
/* now clear it out to nothing */
memset(&bb, 0, sizeof(bb));
if (params->flags & IB_VERBOSE)
printf("%slearing boot block\n",
(params->flags & IB_NOWRITE) ? "Not c" : "C");
if (params->flags & IB_NOWRITE)
return (1);
rv = pwrite(params->fsfd, &bb, sizeof(bb), SPARC64_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
return (0);
} else if (rv != sizeof(bb)) {
warnx("Writing `%s': short write", params->filesystem);
return (0);
}
return (1);
}
static int
sparc64_setboot(ib_params *params)
{
char bb[SPARC64_BOOT_BLOCK_MAX_SIZE];
int retval;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
retval = 0;
if (params->flags & (IB_STAGE1START | IB_STAGE2START)) {
warnx("`-b bno' and `-B bno' are not supported for %s",
params->machine->name);
goto done;
}
memset(&bb, 0, SPARC64_BOOT_BLOCK_MAX_SIZE);
rv = read(params->s1fd, &bb, sizeof(bb));
if (rv == -1) {
warn("Reading `%s'", params->stage1);
goto done;
}
if (params->flags & IB_VERBOSE) {
printf("Bootstrap start sector: %u\n",
SPARC64_BOOT_BLOCK_OFFSET / SPARC64_BOOT_BLOCK_BLOCKSIZE);
printf("Bootstrap byte count: %u\n", (unsigned)rv);
printf("%sriting bootstrap\n",
(params->flags & IB_NOWRITE) ? "Not w" : "W");
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
rv = pwrite(params->fsfd, &bb, SPARC64_BOOT_BLOCK_MAX_SIZE,
SPARC64_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != SPARC64_BOOT_BLOCK_MAX_SIZE) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
} else
retval = 1;
done:
return (retval);
}

View File

@@ -0,0 +1,85 @@
/* $NetBSD: sun68k.c,v 1.21 2008/04/28 20:24:16 martin Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: sun68k.c,v 1.21 2008/04/28 20:24:16 martin Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include "installboot.h"
static int sun68k_clearboot(ib_params *);
static int sun68k_setboot(ib_params *);
struct ib_mach ib_mach_sun2 =
{ "sun2", sun68k_setboot, sun68k_clearboot, no_editboot,
IB_STAGE2START };
struct ib_mach ib_mach_sun3 =
{ "sun3", sun68k_setboot, sun68k_clearboot, no_editboot,
IB_STAGE2START };
static struct bbinfo_params bbparams = {
SUN68K_BBINFO_MAGIC,
SUN68K_BOOT_BLOCK_OFFSET,
SUN68K_BOOT_BLOCK_BLOCKSIZE,
SUN68K_BOOT_BLOCK_MAX_SIZE,
0,
BBINFO_BIG_ENDIAN,
};
static int
sun68k_clearboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_clearboot(params, &bbparams, NULL));
}
static int
sun68k_setboot(ib_params *params)
{
assert(params != NULL);
return (shared_bbinfo_setboot(params, &bbparams, NULL));
}

View File

@@ -0,0 +1,316 @@
/* $NetBSD: vax.c,v 1.13 2009/04/05 11:55:39 lukem Exp $ */
/*-
* Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Simon Burge.
*
* 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.
*
* 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.
*/
/*
* Copyright (c) 1999 Christopher G. Demetriou. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christopher G. Demetriou
* for the NetBSD Project.
* 4. 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 <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: vax.c,v 1.13 2009/04/05 11:55:39 lukem Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "installboot.h"
static int load_bootstrap(ib_params *, char **,
uint32_t *, uint32_t *, size_t *);
static int vax_clearboot(ib_params *);
static int vax_setboot(ib_params *);
struct ib_mach ib_mach_vax =
{ "vax", vax_setboot, vax_clearboot, no_editboot,
IB_STAGE1START | IB_APPEND | IB_SUNSUM };
static int
vax_clearboot(ib_params *params)
{
struct vax_boot_block bb;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(sizeof(struct vax_boot_block) == VAX_BOOT_BLOCK_BLOCKSIZE);
rv = pread(params->fsfd, &bb, sizeof(bb), VAX_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
return (0);
} else if (rv != sizeof(bb)) {
warnx("Reading `%s': short read", params->filesystem);
return (0);
}
if (bb.bb_id_offset * 2 != offsetof(struct vax_boot_block, bb_magic1)
|| bb.bb_magic1 != VAX_BOOT_MAGIC1) {
warnx(
"Old boot block magic number invalid; boot block invalid");
return (0);
}
bb.bb_id_offset = 1;
bb.bb_mbone = 0;
bb.bb_lbn_hi = 0;
bb.bb_lbn_low = 0;
if (params->flags & IB_SUNSUM) {
uint16_t sum;
sum = compute_sunsum((uint16_t *)&bb);
if (! set_sunsum(params, (uint16_t *)&bb, sum))
return (0);
}
if (params->flags & IB_VERBOSE)
printf("%slearing boot block\n",
(params->flags & IB_NOWRITE) ? "Not c" : "C");
if (params->flags & IB_NOWRITE)
return (1);
rv = pwrite(params->fsfd, &bb, sizeof(bb), VAX_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
return (0);
} else if (rv != sizeof(bb)) {
warnx("Writing `%s': short write", params->filesystem);
return (0);
}
return (1);
}
static int
vax_setboot(ib_params *params)
{
struct stat bootstrapsb;
struct vax_boot_block bb;
uint32_t startblock;
int retval;
char *bootstrapbuf;
size_t bootstrapsize;
uint32_t bootstrapload, bootstrapexec;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
assert(sizeof(struct vax_boot_block) == VAX_BOOT_BLOCK_BLOCKSIZE);
retval = 0;
bootstrapbuf = NULL;
if (fstat(params->s1fd, &bootstrapsb) == -1) {
warn("Examining `%s'", params->stage1);
goto done;
}
if (!S_ISREG(bootstrapsb.st_mode)) {
warnx("`%s' must be a regular file", params->stage1);
goto done;
}
if (! load_bootstrap(params, &bootstrapbuf, &bootstrapload,
&bootstrapexec, &bootstrapsize))
goto done;
rv = pread(params->fsfd, &bb, sizeof(bb), VAX_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != sizeof(bb)) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
/* fill in the updated boot block fields */
if (params->flags & IB_APPEND) {
struct stat filesyssb;
if (fstat(params->fsfd, &filesyssb) == -1) {
warn("Examining `%s'", params->filesystem);
goto done;
}
if (!S_ISREG(filesyssb.st_mode)) {
warnx(
"`%s' must be a regular file to append a bootstrap",
params->filesystem);
goto done;
}
startblock = howmany(filesyssb.st_size,
VAX_BOOT_BLOCK_BLOCKSIZE);
} else if (params->flags & IB_STAGE1START) {
startblock = params->s1start;
} else {
startblock = VAX_BOOT_BLOCK_OFFSET / VAX_BOOT_BLOCK_BLOCKSIZE
+ 1;
}
bb.bb_id_offset = offsetof(struct vax_boot_block, bb_magic1) / 2;
bb.bb_mbone = 1;
bb.bb_lbn_hi = htole16((uint16_t) (startblock >> 16));
bb.bb_lbn_low = htole16((uint16_t) (startblock >> 0));
/*
* Now the identification block
*/
bb.bb_magic1 = VAX_BOOT_MAGIC1;
bb.bb_mbz1 = 0;
bb.bb_sum1 = ~(bb.bb_magic1 + bb.bb_mbz1 + bb.bb_pad1);
bb.bb_mbz2 = 0;
bb.bb_volinfo = VAX_BOOT_VOLINFO_NONE;
bb.bb_pad2a = 0;
bb.bb_pad2b = 0;
bb.bb_size = htole32(bootstrapsize / VAX_BOOT_BLOCK_BLOCKSIZE);
bb.bb_load = htole32(VAX_BOOT_LOAD);
bb.bb_entry = htole32(VAX_BOOT_ENTRY);
bb.bb_sum3 = htole32(le32toh(bb.bb_size) + le32toh(bb.bb_load) \
+ le32toh(bb.bb_entry));
if (params->flags & IB_SUNSUM) {
uint16_t sum;
sum = compute_sunsum((uint16_t *)&bb);
if (! set_sunsum(params, (uint16_t *)&bb, sum))
goto done;
}
if (params->flags & IB_VERBOSE) {
printf("Bootstrap start sector: %u\n", startblock);
printf("Bootstrap sector count: %u\n", le32toh(bb.bb_size));
printf("%sriting bootstrap\n",
(params->flags & IB_NOWRITE) ? "Not w" : "W");
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
rv = pwrite(params->fsfd, bootstrapbuf, bootstrapsize,
startblock * VAX_BOOT_BLOCK_BLOCKSIZE);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if ((size_t)rv != bootstrapsize) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
}
if (params->flags & IB_VERBOSE)
printf("Writing boot block\n");
rv = pwrite(params->fsfd, &bb, sizeof(bb), VAX_BOOT_BLOCK_OFFSET);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != sizeof(bb)) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
} else {
retval = 1;
}
done:
if (bootstrapbuf)
free(bootstrapbuf);
return (retval);
}
static int
load_bootstrap(ib_params *params, char **data,
uint32_t *loadaddr, uint32_t *execaddr, size_t *len)
{
ssize_t cc;
size_t buflen;
buflen = 512 * (VAX_BOOT_SIZE + 1);
*data = malloc(buflen);
if (*data == NULL) {
warn("Allocating %lu bytes", (unsigned long) buflen);
return (0);
}
cc = pread(params->s1fd, *data, buflen, 0);
if (cc <= 0) {
warn("Reading `%s'", params->stage1);
return (0);
}
if (cc > 512 * VAX_BOOT_SIZE) {
warnx("`%s': too large", params->stage1);
return (0);
}
*len = roundup(cc, VAX_BOOT_BLOCK_BLOCKSIZE);
*loadaddr = VAX_BOOT_LOAD;
*execaddr = VAX_BOOT_ENTRY;
return (1);
}

View File

@@ -0,0 +1,181 @@
/* $NetBSD: x68k.c,v 1.4 2008/04/28 20:24:16 martin Exp $ */
/*-
* 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.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: x68k.c,v 1.4 2008/04/28 20:24:16 martin Exp $");
#endif /* !__lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <assert.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "installboot.h"
#define X68K_LABELOFFSET 64
#define X68K_LABELSIZE 404 /* reserve 16 partitions */
static int x68k_clearheader(ib_params *, struct bbinfo_params *, uint8_t *);
static int x68k_clearboot(ib_params *);
static int x68k_setboot(ib_params *);
struct ib_mach ib_mach_x68k =
{ "x68k", x68k_setboot, x68k_clearboot, no_editboot,
IB_STAGE1START | IB_STAGE2START };
static struct bbinfo_params bbparams = {
X68K_BBINFO_MAGIC,
X68K_BOOT_BLOCK_OFFSET,
X68K_BOOT_BLOCK_BLOCKSIZE,
X68K_BOOT_BLOCK_MAX_SIZE,
X68K_LABELOFFSET + X68K_LABELSIZE, /* XXX */
BBINFO_BIG_ENDIAN,
};
static int
x68k_clearboot(ib_params *params)
{
assert(params != NULL);
if (params->flags & IB_STAGE1START) {
warnx("`-b bno' is not supported for %s",
params->machine->name);
return 0;
}
return shared_bbinfo_clearboot(params, &bbparams, x68k_clearheader);
}
static int
x68k_clearheader(ib_params *params, struct bbinfo_params *bb_params,
uint8_t *bb)
{
assert(params != NULL);
assert(bb_params != NULL);
assert(bb != NULL);
memset(bb, 0, X68K_LABELOFFSET);
return 1;
}
static int
x68k_setboot(ib_params *params)
{
struct stat bootstrapsb;
char bb[X68K_BOOT_BLOCK_MAX_SIZE];
char label[X68K_LABELSIZE];
uint32_t s1start;
int retval;
ssize_t rv;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
assert(params->s1fd != -1);
assert(params->stage1 != NULL);
retval = 0;
if (params->flags & IB_STAGE1START)
s1start = params->s1start;
else
s1start = X68K_BOOT_BLOCK_OFFSET /
X68K_BOOT_BLOCK_BLOCKSIZE;
/* read disklabel on the target disk */
rv = pread(params->fsfd, label, sizeof label,
s1start * X68K_BOOT_BLOCK_BLOCKSIZE + X68K_LABELOFFSET);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != sizeof label) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
if (fstat(params->s1fd, &bootstrapsb) == -1) {
warn("Examining `%s'", params->stage1);
goto done;
}
if (!S_ISREG(bootstrapsb.st_mode)) {
warnx("`%s' must be a regular file", params->stage1);
goto done;
}
/* read boot loader */
memset(&bb, 0, sizeof bb);
rv = read(params->s1fd, &bb, sizeof bb);
if (rv == -1) {
warn("Reading `%s'", params->stage1);
goto done;
}
/* then, overwrite disklabel */
memcpy(&bb[X68K_LABELOFFSET], &label, sizeof label);
if (params->flags & IB_VERBOSE) {
printf("Bootstrap start sector: %#x\n", s1start);
printf("Bootstrap byte count: %#x\n", (unsigned)rv);
printf("%sriting bootstrap\n",
(params->flags & IB_NOWRITE) ? "Not w" : "W");
}
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
/* write boot loader and disklabel into the target disk */
rv = pwrite(params->fsfd, &bb, X68K_BOOT_BLOCK_MAX_SIZE,
s1start * X68K_BOOT_BLOCK_BLOCKSIZE);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != X68K_BOOT_BLOCK_MAX_SIZE) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
} else
retval = 1;
done:
return (retval);
}