Import usr.sbin/installboot.
This commit is contained in:
451
usr.sbin/installboot/arch/alpha.c
Normal file
451
usr.sbin/installboot/arch/alpha.c
Normal 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));
|
||||
}
|
||||
173
usr.sbin/installboot/arch/amiga.c
Normal file
173
usr.sbin/installboot/arch/amiga.c
Normal 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;
|
||||
}
|
||||
145
usr.sbin/installboot/arch/emips.c
Normal file
145
usr.sbin/installboot/arch/emips.c
Normal 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);
|
||||
}
|
||||
62
usr.sbin/installboot/arch/ews4800mips.c
Normal file
62
usr.sbin/installboot/arch/ews4800mips.c
Normal 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;
|
||||
}
|
||||
214
usr.sbin/installboot/arch/hp300.c
Normal file
214
usr.sbin/installboot/arch/hp300.c
Normal 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;
|
||||
}
|
||||
220
usr.sbin/installboot/arch/hp700.c
Normal file
220
usr.sbin/installboot/arch/hp700.c
Normal 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);
|
||||
}
|
||||
552
usr.sbin/installboot/arch/i386.c
Normal file
552
usr.sbin/installboot/arch/i386.c
Normal 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;
|
||||
}
|
||||
250
usr.sbin/installboot/arch/landisk.c
Normal file
250
usr.sbin/installboot/arch/landisk.c
Normal 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;
|
||||
}
|
||||
186
usr.sbin/installboot/arch/macppc.c
Normal file
186
usr.sbin/installboot/arch/macppc.c
Normal 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);
|
||||
}
|
||||
166
usr.sbin/installboot/arch/news.c
Normal file
166
usr.sbin/installboot/arch/news.c
Normal 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);
|
||||
}
|
||||
267
usr.sbin/installboot/arch/next68k.c
Normal file
267
usr.sbin/installboot/arch/next68k.c
Normal 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;
|
||||
}
|
||||
369
usr.sbin/installboot/arch/pmax.c
Normal file
369
usr.sbin/installboot/arch/pmax.c
Normal 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);
|
||||
}
|
||||
128
usr.sbin/installboot/arch/sparc.c
Normal file
128
usr.sbin/installboot/arch/sparc.c
Normal 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);
|
||||
}
|
||||
185
usr.sbin/installboot/arch/sparc64.c
Normal file
185
usr.sbin/installboot/arch/sparc64.c
Normal 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);
|
||||
}
|
||||
85
usr.sbin/installboot/arch/sun68k.c
Normal file
85
usr.sbin/installboot/arch/sun68k.c
Normal 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));
|
||||
}
|
||||
316
usr.sbin/installboot/arch/vax.c
Normal file
316
usr.sbin/installboot/arch/vax.c
Normal 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);
|
||||
}
|
||||
181
usr.sbin/installboot/arch/x68k.c
Normal file
181
usr.sbin/installboot/arch/x68k.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user