Import usr.sbin/installboot.
This commit is contained in:
parent
4c4c045f87
commit
9f8e6353e5
28 changed files with 7382 additions and 0 deletions
|
@ -33,6 +33,7 @@ usr.bin/seq src/usr.bin/seq
|
|||
usr.bin/man src/usr.bin/man
|
||||
usr.bin/apropos src/usr.bin/apropos
|
||||
usr.bin/mdocml src/external/bsd/mdocml
|
||||
usr.sbin/installboot src/usr.sbin/installboot
|
||||
usr.sbin/pwd_mkdb src/usr.sbin/pwd_mkdb
|
||||
usr.sbin/user src/usr.sbin/user
|
||||
usr.sbin/vipw src/usr.sbin/vipw
|
||||
|
|
54
usr.sbin/installboot/Makefile
Normal file
54
usr.sbin/installboot/Makefile
Normal file
|
@ -0,0 +1,54 @@
|
|||
# $NetBSD: Makefile,v 1.46 2011/08/14 17:50:16 christos Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= installboot
|
||||
MAN= installboot.8
|
||||
SRCS= installboot.c sum.c machines.c fstypes.c
|
||||
|
||||
|
||||
ARCH_XLAT= amd64-i386.c news68k-news.c newsmips-news.c
|
||||
ARCH_XLAT+= sun2-sun68k.c sun3-sun68k.c
|
||||
|
||||
.if !defined(SMALLPROG) && !defined(ARCH_FILES)
|
||||
ARCH_FILES= alpha.c amiga.c emips.c ews4800mips.c hp300.c hp700.c i386.c
|
||||
ARCH_FILES+= landisk.c macppc.c news.c next68k.c pmax.c
|
||||
ARCH_FILES+= sparc.c sparc64.c sun68k.c vax.c x68k.c
|
||||
.else
|
||||
ARCH_FILES?= ${ARCH_XLAT:M${MACHINE}-*:S/${MACHINE}-//}
|
||||
.if empty(ARCH_FILES)
|
||||
ARCH_FILES= ${MACHINE}.c
|
||||
.endif
|
||||
.endif
|
||||
|
||||
SRCS+=${ARCH_FILES}
|
||||
|
||||
.if empty(ARCH_FILES:C/(macppc|news|sparc|sun68k|x68k)/stg2/:Mstg2.c)
|
||||
CPPFLAGS += -DNO_STAGE2
|
||||
.else
|
||||
SRCS+= bbinfo.c
|
||||
|
||||
# fstypes are only needed for 'stage2' and then only from bbinfo.
|
||||
SRCS+= ffs.c
|
||||
.if SMALLPROG
|
||||
CPPFLAGS+= -DNO_FFS_SWAP
|
||||
.else
|
||||
SRCS+= ffs_bswap.c
|
||||
.endif
|
||||
#SRCS+= ext2fs.c ext2fs_bswap.c
|
||||
.endif
|
||||
|
||||
UFSSRC= ${NETBSDSRCDIR}/sys/ufs
|
||||
CPPFLAGS+= -I${.CURDIR} -I.
|
||||
.PATH: ${.CURDIR}/arch ${UFSSRC}/ffs ${UFSSRC}/ext2fs
|
||||
|
||||
.if !defined(HOSTPROGNAME)
|
||||
.if defined(HAVE_GCC) || defined(HAVE_PCC)
|
||||
.for f in i386 macppc
|
||||
COPTS.${f}.c+= -Wno-pointer-sign
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
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);
|
||||
}
|
330
usr.sbin/installboot/bbinfo.c
Normal file
330
usr.sbin/installboot/bbinfo.c
Normal file
|
@ -0,0 +1,330 @@
|
|||
/* $NetBSD: bbinfo.c,v 1.14 2009/04/05 11:55:39 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Matt Fredette, 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: bbinfo.c,v 1.14 2009/04/05 11:55:39 lukem 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 <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "installboot.h"
|
||||
|
||||
int
|
||||
shared_bbinfo_clearboot(ib_params *params, struct bbinfo_params *bbparams,
|
||||
int (*callback)(ib_params *, struct bbinfo_params *, uint8_t *))
|
||||
{
|
||||
uint8_t *bb;
|
||||
ssize_t rv;
|
||||
int retval;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fsfd != -1);
|
||||
assert(params->filesystem != NULL);
|
||||
assert(bbparams != NULL);
|
||||
assert((strlen(bbparams->magic) + 1) == 32);
|
||||
|
||||
retval = 0;
|
||||
if ((bb = malloc(bbparams->maxsize)) == NULL) {
|
||||
warn("Allocating %lu bytes for bbinfo",
|
||||
(unsigned long) bbparams->maxsize);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* First check that it _could_ exist here */
|
||||
rv = pread(params->fsfd, bb, bbparams->maxsize, bbparams->offset);
|
||||
if (rv == -1) {
|
||||
warn("Reading `%s'", params->filesystem);
|
||||
goto done;
|
||||
} else if ((uint32_t)rv != bbparams->maxsize) {
|
||||
warnx("Reading `%s': short read", params->filesystem);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Now clear out (past the header offset) */
|
||||
memset(bb + bbparams->headeroffset, 0,
|
||||
bbparams->maxsize - bbparams->headeroffset);
|
||||
if (callback != NULL && ! (*callback)(params, bbparams, bb))
|
||||
goto done;
|
||||
|
||||
if (params->flags & IB_VERBOSE)
|
||||
printf("%slearing boot block\n",
|
||||
(params->flags & IB_NOWRITE) ? "Not c" : "C");
|
||||
if (params->flags & IB_NOWRITE) {
|
||||
retval = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = pwrite(params->fsfd, bb, bbparams->maxsize, bbparams->offset);
|
||||
#ifdef DIOCWLABEL
|
||||
if (rv == -1 && errno == EROFS) {
|
||||
/*
|
||||
* The first sector 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");
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = pwrite(params->fsfd, bb, bbparams->maxsize,
|
||||
bbparams->offset);
|
||||
|
||||
/* Reset write-protect. */
|
||||
enable = 0;
|
||||
(void)ioctl(params->fsfd, DIOCWLABEL, &enable);
|
||||
}
|
||||
#endif
|
||||
if (rv == -1) {
|
||||
warn("Writing `%s'", params->filesystem);
|
||||
goto done;
|
||||
} else if ((uint32_t)rv != bbparams->maxsize) {
|
||||
warnx("Writing `%s': short write", params->filesystem);
|
||||
goto done;
|
||||
} else
|
||||
retval = 1;
|
||||
|
||||
done:
|
||||
if (bb != NULL)
|
||||
free(bb);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
shared_bbinfo_setboot(ib_params *params, struct bbinfo_params *bbparams,
|
||||
int (*callback)(ib_params *, struct bbinfo_params *, uint8_t *))
|
||||
{
|
||||
uint8_t *bb;
|
||||
int retval;
|
||||
ssize_t rv;
|
||||
size_t bbi;
|
||||
struct shared_bbinfo *bbinfop; /* bbinfo in prototype image */
|
||||
uint32_t maxblk, nblk, blk_i;
|
||||
ib_block *blocks;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fsfd != -1);
|
||||
assert(params->filesystem != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
assert(params->s1fd != -1);
|
||||
assert(params->stage1 != NULL);
|
||||
assert(bbparams != NULL);
|
||||
assert((strlen(bbparams->magic) + 1) == 32);
|
||||
|
||||
bbinfop = NULL; /* XXXGCC -Wuninitialized [sparc64] */
|
||||
retval = 0;
|
||||
blocks = NULL;
|
||||
if ((bb = malloc(bbparams->maxsize)) == NULL) {
|
||||
warn("Allocating %lu bytes for bbinfo",
|
||||
(unsigned long) bbparams->maxsize);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (params->stage2 == NULL) {
|
||||
warnx("Name of secondary bootstrap not provided");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (params->s1stat.st_size >
|
||||
bbparams->maxsize - bbparams->headeroffset) {
|
||||
warnx("`%s' cannot be larger than %lu bytes",
|
||||
params->stage1, (unsigned long)(bbparams->maxsize -
|
||||
bbparams->headeroffset));
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(bb, 0, bbparams->maxsize);
|
||||
rv = read(params->s1fd, bb + bbparams->headeroffset,
|
||||
bbparams->maxsize - bbparams->headeroffset);
|
||||
if (rv == -1) {
|
||||
warn("Reading `%s'", params->stage1);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Quick sanity check that the bootstrap given
|
||||
* is *not* an ELF executable.
|
||||
*/
|
||||
if (memcmp(bb + bbparams->headeroffset + 1, "ELF", strlen("ELF"))
|
||||
== 0) {
|
||||
warnx("`%s' is an ELF executable; need raw binary",
|
||||
params->stage1);
|
||||
goto done;
|
||||
}
|
||||
|
||||
#define HOSTTOTARGET32(x) ((bbparams->endian == BBINFO_LITTLE_ENDIAN) \
|
||||
? (uint32_t)htole32((x)) : (uint32_t)htobe32((x)))
|
||||
#define TARGET32TOHOST(x) ((bbparams->endian == BBINFO_LITTLE_ENDIAN) \
|
||||
? (uint32_t)le32toh((x)) : (uint32_t)be32toh((x)))
|
||||
|
||||
/* Look for the bbinfo structure. */
|
||||
bbinfop = NULL;
|
||||
for (bbi = 0; bbi < bbparams->maxsize; bbi += sizeof(uint32_t)) {
|
||||
bbinfop = (void *) (bb + bbparams->headeroffset + bbi);
|
||||
if (memcmp(bbinfop->bbi_magic, bbparams->magic,
|
||||
sizeof(bbinfop->bbi_magic)) == 0)
|
||||
break;
|
||||
}
|
||||
if (bbi >= bbparams->maxsize) {
|
||||
warnx("%s bbinfo structure not found in `%s'",
|
||||
params->machine->name, params->stage1);
|
||||
goto done;
|
||||
}
|
||||
maxblk = TARGET32TOHOST(bbinfop->bbi_block_count);
|
||||
if (maxblk == 0 || maxblk > (bbparams->maxsize / sizeof(uint32_t))) {
|
||||
warnx("%s bbinfo structure in `%s' has preposterous size `%u'",
|
||||
params->machine->name, params->stage1, maxblk);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Allocate space for our block list. */
|
||||
blocks = malloc(sizeof(*blocks) * maxblk);
|
||||
if (blocks == NULL) {
|
||||
warn("Allocating %lu bytes",
|
||||
(unsigned long)sizeof(*blocks) * maxblk);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (S_ISREG(params->fsstat.st_mode)) {
|
||||
if (fsync(params->fsfd) == -1)
|
||||
warn("Synchronising file system `%s'",
|
||||
params->filesystem);
|
||||
} else {
|
||||
/* Ensure the secondary bootstrap is on disk. */
|
||||
sync();
|
||||
}
|
||||
|
||||
/* Collect the blocks for the secondary bootstrap. */
|
||||
nblk = maxblk;
|
||||
if (! params->fstype->findstage2(params, &nblk, blocks))
|
||||
goto done;
|
||||
if (nblk == 0) {
|
||||
warnx("Secondary bootstrap `%s' is empty",
|
||||
params->stage2);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Save those blocks in the primary bootstrap. */
|
||||
bbinfop->bbi_block_count = HOSTTOTARGET32(nblk);
|
||||
bbinfop->bbi_block_size = HOSTTOTARGET32(blocks[0].blocksize);
|
||||
for (blk_i = 0; blk_i < nblk; blk_i++) {
|
||||
bbinfop->bbi_block_table[blk_i] =
|
||||
HOSTTOTARGET32(blocks[blk_i].block);
|
||||
if (blocks[blk_i].blocksize < blocks[0].blocksize &&
|
||||
blk_i + 1 != nblk) {
|
||||
warnx("Secondary bootstrap `%s' blocks do not have "
|
||||
"a uniform size", params->stage2);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (callback != NULL && ! (*callback)(params, bbparams, bb))
|
||||
goto done;
|
||||
|
||||
if (params->flags & IB_VERBOSE) {
|
||||
printf("Bootstrap start sector: %u\n",
|
||||
bbparams->offset / bbparams->blocksize);
|
||||
printf("Bootstrap byte count: %u\n", (unsigned)rv);
|
||||
printf("Bootstrap block table: "
|
||||
"%u entries of %u bytes available, %u used:",
|
||||
maxblk, blocks[0].blocksize, nblk);
|
||||
for (blk_i = 0; blk_i < nblk; blk_i++)
|
||||
printf(" %llu",
|
||||
(unsigned long long)blocks[blk_i].block);
|
||||
printf("\n%sriting bootstrap\n",
|
||||
(params->flags & IB_NOWRITE) ? "Not w" : "W");
|
||||
}
|
||||
if (params->flags & IB_NOWRITE) {
|
||||
retval = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = pwrite(params->fsfd, bb, bbparams->maxsize, bbparams->offset);
|
||||
#ifdef DIOCWLABEL
|
||||
if (rv == -1 && errno == EROFS) {
|
||||
/*
|
||||
* The first sector 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");
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = pwrite(params->fsfd, bb, bbparams->maxsize,
|
||||
bbparams->offset);
|
||||
|
||||
/* Reset write-protect. */
|
||||
enable = 0;
|
||||
(void)ioctl(params->fsfd, DIOCWLABEL, &enable);
|
||||
}
|
||||
#endif
|
||||
if (rv == -1) {
|
||||
warn("Writing `%s'", params->filesystem);
|
||||
goto done;
|
||||
} else if ((uint32_t)rv != bbparams->maxsize) {
|
||||
warnx("Writing `%s': short write", params->filesystem);
|
||||
goto done;
|
||||
} else {
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
done:
|
||||
if (blocks != NULL)
|
||||
free(blocks);
|
||||
if (bb != NULL)
|
||||
free(bb);
|
||||
return (retval);
|
||||
}
|
468
usr.sbin/installboot/ext2fs.c
Normal file
468
usr.sbin/installboot/ext2fs.c
Normal file
|
@ -0,0 +1,468 @@
|
|||
/* $NetBSD: ext2fs.c,v 1.6 2010/01/14 16:27:49 tsutsui Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Manuel Bouyer.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Matt Fredette.
|
||||
*
|
||||
* 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: ext2fs.c,v 1.6 2010/01/14 16:27:49 tsutsui Exp $");
|
||||
#endif /* !__lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#if !HAVE_NBTOOL_CONFIG_H
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "installboot.h"
|
||||
|
||||
#include <ufs/ext2fs/ext2fs_dinode.h>
|
||||
#include <ufs/ext2fs/ext2fs_dir.h>
|
||||
#include <ufs/ext2fs/ext2fs.h>
|
||||
|
||||
static int ext2fs_read_disk_block(ib_params *, uint64_t, int, uint8_t []);
|
||||
static int ext2fs_read_sblock(ib_params *, struct m_ext2fs *fs);
|
||||
static int ext2fs_read_gdblock(ib_params *, struct m_ext2fs *fs);
|
||||
static int ext2fs_find_disk_blocks(ib_params *, ino_t,
|
||||
int (*)(ib_params *, void *, uint64_t, uint32_t), void *);
|
||||
static int ext2fs_findstage2_ino(ib_params *, void *, uint64_t, uint32_t);
|
||||
static int ext2fs_findstage2_blocks(ib_params *, void *, uint64_t,
|
||||
uint32_t);
|
||||
|
||||
|
||||
/* This reads a disk block from the file system. */
|
||||
/* XXX: should be shared with ffs.c? */
|
||||
static int
|
||||
ext2fs_read_disk_block(ib_params *params, uint64_t blkno, int size,
|
||||
uint8_t blk[])
|
||||
{
|
||||
int rv;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->filesystem != NULL);
|
||||
assert(params->fsfd != -1);
|
||||
assert(size > 0);
|
||||
assert(blk != NULL);
|
||||
|
||||
rv = pread(params->fsfd, blk, size, blkno * params->sectorsize);
|
||||
if (rv == -1) {
|
||||
warn("Reading block %llu in `%s'",
|
||||
(unsigned long long)blkno, params->filesystem);
|
||||
return 0;
|
||||
} else if (rv != size) {
|
||||
warnx("Reading block %llu in `%s': short read",
|
||||
(unsigned long long)blkno, params->filesystem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ext2fs_read_sblock(ib_params *params, struct m_ext2fs *fs)
|
||||
{
|
||||
uint8_t sbbuf[SBSIZE];
|
||||
|
||||
if (ext2fs_read_disk_block(params, SBOFF / params->sectorsize, SBSIZE,
|
||||
sbbuf) == 0)
|
||||
|
||||
e2fs_sbload((void *)sbbuf, &fs->e2fs);
|
||||
|
||||
if (fs->e2fs.e2fs_magic != E2FS_MAGIC)
|
||||
return 0;
|
||||
|
||||
if (fs->e2fs.e2fs_rev > E2FS_REV1 ||
|
||||
(fs->e2fs.e2fs_rev == E2FS_REV1 &&
|
||||
(fs->e2fs.e2fs_first_ino != EXT2_FIRSTINO ||
|
||||
fs->e2fs.e2fs_inode_size != EXT2_DINODE_SIZE ||
|
||||
(fs->e2fs.e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) != 0)))
|
||||
return 0;
|
||||
|
||||
fs->e2fs_ncg =
|
||||
howmany(fs->e2fs.e2fs_bcount - fs->e2fs.e2fs_first_dblock,
|
||||
fs->e2fs.e2fs_bpg);
|
||||
/* XXX assume hw bsize = 512 */
|
||||
fs->e2fs_fsbtodb = fs->e2fs.e2fs_log_bsize + 1;
|
||||
fs->e2fs_bsize = MINBSIZE << fs->e2fs.e2fs_log_bsize;
|
||||
fs->e2fs_bshift = LOG_MINBSIZE + fs->e2fs.e2fs_log_bsize;
|
||||
fs->e2fs_qbmask = fs->e2fs_bsize - 1;
|
||||
fs->e2fs_bmask = ~fs->e2fs_qbmask;
|
||||
fs->e2fs_ngdb =
|
||||
howmany(fs->e2fs_ncg, fs->e2fs_bsize / sizeof(struct ext2_gd));
|
||||
fs->e2fs_ipb = fs->e2fs_bsize / EXT2_DINODE_SIZE;
|
||||
fs->e2fs_itpg = fs->e2fs.e2fs_ipg / fs->e2fs_ipb;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ext2fs_read_gdblock(ib_params *params, struct m_ext2fs *fs)
|
||||
{
|
||||
uint8_t gdbuf[MAXBSIZE];
|
||||
uint32_t gdpb;
|
||||
int i;
|
||||
|
||||
gdpb = fs->e2fs_bsize / sizeof(struct ext2_gd);
|
||||
|
||||
for (i = 0; i < fs->e2fs_ngdb; i++) {
|
||||
if (ext2fs_read_disk_block(params, fsbtodb(fs,
|
||||
fs->e2fs.e2fs_first_dblock + 1 /* superblock */ + i),
|
||||
SBSIZE, gdbuf) == 0)
|
||||
return 0;
|
||||
|
||||
e2fs_cgload((struct ext2_gd *)gdbuf, &fs->e2fs_gd[gdpb * i],
|
||||
(i == (fs->e2fs_ngdb - 1)) ?
|
||||
(fs->e2fs_ncg - gdpb * i) * sizeof(struct ext2_gd):
|
||||
fs->e2fs_bsize);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This iterates over the data blocks belonging to an inode,
|
||||
* making a callback each iteration with the disk block number
|
||||
* and the size.
|
||||
*/
|
||||
static int
|
||||
ext2fs_find_disk_blocks(ib_params *params, ino_t ino,
|
||||
int (*callback)(ib_params *, void *, uint64_t, uint32_t),
|
||||
void *state)
|
||||
{
|
||||
uint8_t sbbuf[sizeof(struct m_ext2fs)];
|
||||
struct m_ext2fs *fs;
|
||||
uint8_t inodebuf[MAXBSIZE];
|
||||
struct ext2fs_dinode inode_store, *inode;
|
||||
int level_i;
|
||||
int32_t blk, lblk, nblk;
|
||||
int rv;
|
||||
#define LEVELS 4
|
||||
struct {
|
||||
uint32_t *blknums;
|
||||
unsigned long blkcount;
|
||||
uint8_t diskbuf[MAXBSIZE];
|
||||
} level[LEVELS];
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
assert(callback != NULL);
|
||||
assert(state != NULL);
|
||||
|
||||
/* Read the superblock. */
|
||||
fs = (void *)sbbuf;
|
||||
if (ext2fs_read_sblock(params, fs) == 0)
|
||||
return 0;
|
||||
|
||||
fs->e2fs_gd = malloc(sizeof(struct ext2_gd) * fs->e2fs_ncg);
|
||||
if (fs->e2fs_gd == NULL) {
|
||||
warnx("Can't allocate memofy for group descriptors");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ext2fs_read_gdblock(params, fs) == 0) {
|
||||
warnx("Can't read group descriptors");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fs->e2fs_ipb <= 0) {
|
||||
warnx("Bad ipb %d in superblock in `%s'",
|
||||
fs->e2fs_ipb, params->filesystem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read the inode. */
|
||||
if (ext2fs_read_disk_block(params,
|
||||
fsbtodb(fs, ino_to_fsba(fs, ino)) + params->fstype->offset,
|
||||
fs->e2fs_bsize, inodebuf))
|
||||
return 0;
|
||||
inode = (void *)inodebuf;
|
||||
e2fs_iload(&inode[ino_to_fsbo(fs, ino)], &inode_store);
|
||||
inode = &inode_store;
|
||||
|
||||
/* Get the block count and initialize for our block walk. */
|
||||
nblk = howmany(inode->e2di_size, fs->e2fs_bsize);
|
||||
lblk = 0;
|
||||
level_i = 0;
|
||||
level[0].blknums = &inode->e2di_blocks[0];
|
||||
level[0].blkcount = NDADDR;
|
||||
level[1].blknums = &inode->e2di_blocks[NDADDR + 0];
|
||||
level[1].blkcount = 1;
|
||||
level[2].blknums = &inode->e2di_blocks[NDADDR + 1];
|
||||
level[2].blkcount = 1;
|
||||
level[3].blknums = &inode->e2di_blocks[NDADDR + 2];
|
||||
level[3].blkcount = 1;
|
||||
|
||||
/* Walk the data blocks. */
|
||||
while (nblk > 0) {
|
||||
|
||||
/*
|
||||
* If there are no more blocks at this indirection
|
||||
* level, move up one indirection level and loop.
|
||||
*/
|
||||
if (level[level_i].blkcount == 0) {
|
||||
if (++level_i == LEVELS)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the next block at this level. */
|
||||
blk = fs2h32(*(level[level_i].blknums++));
|
||||
level[level_i].blkcount--;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "ino %lu blk %lu level %d\n", ino, blk,
|
||||
level_i);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we're not at the direct level, descend one
|
||||
* level, read in that level's new block list,
|
||||
* and loop.
|
||||
*/
|
||||
if (level_i > 0) {
|
||||
level_i--;
|
||||
if (blk == 0)
|
||||
memset(level[level_i].diskbuf, 0, MAXBSIZE);
|
||||
else if (ext2fs_read_disk_block(params,
|
||||
fsbtodb(fs, blk) + params->fstype->offset,
|
||||
fs->e2fs_bsize, level[level_i].diskbuf) == 0)
|
||||
return 0;
|
||||
/* XXX ondisk32 */
|
||||
level[level_i].blknums =
|
||||
(uint32_t *)level[level_i].diskbuf;
|
||||
level[level_i].blkcount = NINDIR(fs);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* blk is the next direct level block. */
|
||||
#if 0
|
||||
fprintf(stderr, "ino %lu db %lu blksize %lu\n", ino,
|
||||
fsbtodb(fs, blk), sblksize(fs, inode->di_size, lblk));
|
||||
#endif
|
||||
rv = (*callback)(params, state,
|
||||
fsbtodb(fs, blk) + params->fstype->offset, fs->e2fs_bsize);
|
||||
lblk++;
|
||||
nblk--;
|
||||
if (rv != 1)
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (nblk != 0) {
|
||||
warnx("Inode %llu in `%s' ran out of blocks?",
|
||||
(unsigned long long)ino, params->filesystem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This callback reads a block of the root directory,
|
||||
* searches for an entry for the secondary bootstrap,
|
||||
* and saves the inode number if one is found.
|
||||
*/
|
||||
static int
|
||||
ext2fs_findstage2_ino(ib_params *params, void *_ino,
|
||||
uint64_t blk, uint32_t blksize)
|
||||
{
|
||||
uint8_t dirbuf[MAXBSIZE];
|
||||
struct ext2fs_direct *de, *ede;
|
||||
uint32_t ino;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
assert(params->stage2 != NULL);
|
||||
assert(_ino != NULL);
|
||||
|
||||
/* Skip directory holes. */
|
||||
if (blk == 0)
|
||||
return 1;
|
||||
|
||||
/* Read the directory block. */
|
||||
if (ext2fs_read_disk_block(params, blk, blksize, dirbuf) == 0)
|
||||
return 0;
|
||||
|
||||
/* Loop over the directory entries. */
|
||||
de = (struct ext2fs_direct *)&dirbuf[0];
|
||||
ede = (struct ext2fs_direct *)&dirbuf[blksize];
|
||||
while (de < ede) {
|
||||
ino = fs2h32(de->e2d_ino);
|
||||
if (ino != 0 && strcmp(de->e2d_name, params->stage2) == 0) {
|
||||
*((uint32_t *)_ino) = ino;
|
||||
return (2);
|
||||
}
|
||||
if (fs2h16(de->e2d_reclen) == 0)
|
||||
break;
|
||||
de = (struct ext2fs_direct *)((char *)de +
|
||||
fs2h16(de->e2d_reclen));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct findblks_state {
|
||||
uint32_t maxblk;
|
||||
uint32_t nblk;
|
||||
ib_block *blocks;
|
||||
};
|
||||
|
||||
/* This callback records the blocks of the secondary bootstrap. */
|
||||
static int
|
||||
ext2fs_findstage2_blocks(ib_params *params, void *_state,
|
||||
uint64_t blk, uint32_t blksize)
|
||||
{
|
||||
struct findblks_state *state = _state;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->stage2 != NULL);
|
||||
assert(_state != NULL);
|
||||
|
||||
if (state->nblk == state->maxblk) {
|
||||
warnx("Secondary bootstrap `%s' has too many blocks (max %d)",
|
||||
params->stage2, state->maxblk);
|
||||
return (0);
|
||||
}
|
||||
state->blocks[state->nblk].block = blk;
|
||||
state->blocks[state->nblk].blocksize = blksize;
|
||||
state->nblk++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* publicly visible functions
|
||||
*/
|
||||
|
||||
int
|
||||
ext2fs_match(ib_params *params)
|
||||
{
|
||||
uint8_t sbbuf[sizeof(struct m_ext2fs)];
|
||||
struct m_ext2fs *fs;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
|
||||
/* Read the superblock. */
|
||||
fs = (void *)sbbuf;
|
||||
if (ext2fs_read_sblock(params, fs) == 0)
|
||||
return 0;
|
||||
|
||||
params->fstype->needswap = 0;
|
||||
params->fstype->blocksize = fs->e2fs_bsize;
|
||||
params->fstype->offset = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ext2fs_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
|
||||
{
|
||||
int rv;
|
||||
uint32_t ino;
|
||||
struct findblks_state state;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->stage2 != NULL);
|
||||
assert(maxblk != NULL);
|
||||
assert(blocks != NULL);
|
||||
|
||||
if (params->flags & IB_STAGE2START)
|
||||
return hardcode_stage2(params, maxblk, blocks);
|
||||
|
||||
/* The secondary bootstrap must be clearly in /. */
|
||||
if (params->stage2[0] == '/')
|
||||
params->stage2++;
|
||||
if (strchr(params->stage2, '/') != NULL) {
|
||||
warnx("The secondary bootstrap `%s' must be in /",
|
||||
params->stage2);
|
||||
warnx("(Path must be relative to the file system in `%s')",
|
||||
params->filesystem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the inode number of the secondary bootstrap. */
|
||||
rv = ext2fs_find_disk_blocks(params, EXT2_ROOTINO,
|
||||
ext2fs_findstage2_ino, &ino);
|
||||
if (rv != 2) {
|
||||
warnx("Could not find secondary bootstrap `%s' in `%s'",
|
||||
params->stage2, params->filesystem);
|
||||
warnx("(Path must be relative to the file system in `%s')",
|
||||
params->filesystem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Record the disk blocks of the secondary bootstrap. */
|
||||
state.maxblk = *maxblk;
|
||||
state.nblk = 0;
|
||||
state.blocks = blocks;
|
||||
rv = ext2fs_find_disk_blocks(params, ino,
|
||||
ext2fs_findstage2_blocks, &state);
|
||||
if (rv == 0)
|
||||
return 0;
|
||||
|
||||
*maxblk = state.nblk;
|
||||
return 1;
|
||||
}
|
592
usr.sbin/installboot/ffs.c
Normal file
592
usr.sbin/installboot/ffs.c
Normal file
|
@ -0,0 +1,592 @@
|
|||
/* $NetBSD: ffs.c,v 1.29 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 Matt Fredette.
|
||||
*
|
||||
* 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: ffs.c,v 1.29 2010/01/14 16:27:49 tsutsui Exp $");
|
||||
#endif /* !__lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#if !HAVE_NBTOOL_CONFIG_H
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "installboot.h"
|
||||
|
||||
/* From <dev/raidframe/raidframevar.h> */
|
||||
#define RF_PROTECTED_SECTORS 64L
|
||||
|
||||
#undef DIRBLKSIZ
|
||||
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <ufs/ffs/ffs_extern.h>
|
||||
#ifndef NO_FFS_SWAP
|
||||
#include <ufs/ufs/ufs_bswap.h>
|
||||
#else
|
||||
#define ffs_sb_swap(fs_a, fs_b)
|
||||
#define ffs_dinode1_swap(inode_a, inode_b)
|
||||
#define ffs_dinode2_swap(inode_a, inode_b)
|
||||
#endif
|
||||
|
||||
static int ffs_match_common(ib_params *, off_t);
|
||||
static int ffs_read_disk_block(ib_params *, uint64_t, int, char []);
|
||||
static int ffs_find_disk_blocks_ufs1(ib_params *, ino_t,
|
||||
int (*)(ib_params *, void *, uint64_t, uint32_t), void *);
|
||||
static int ffs_find_disk_blocks_ufs2(ib_params *, ino_t,
|
||||
int (*)(ib_params *, void *, uint64_t, uint32_t), void *);
|
||||
static int ffs_findstage2_ino(ib_params *, void *, uint64_t, uint32_t);
|
||||
static int ffs_findstage2_blocks(ib_params *, void *, uint64_t, uint32_t);
|
||||
|
||||
static int is_ufs2;
|
||||
|
||||
|
||||
/* This reads a disk block from the filesystem. */
|
||||
static int
|
||||
ffs_read_disk_block(ib_params *params, uint64_t blkno, int size, char blk[])
|
||||
{
|
||||
int rv;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->filesystem != NULL);
|
||||
assert(params->fsfd != -1);
|
||||
assert(size > 0);
|
||||
assert(blk != NULL);
|
||||
|
||||
rv = pread(params->fsfd, blk, size, blkno * params->sectorsize);
|
||||
if (rv == -1) {
|
||||
warn("Reading block %llu in `%s'",
|
||||
(unsigned long long)blkno, params->filesystem);
|
||||
return (0);
|
||||
} else if (rv != size) {
|
||||
warnx("Reading block %llu in `%s': short read",
|
||||
(unsigned long long)blkno, params->filesystem);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This iterates over the data blocks belonging to an inode,
|
||||
* making a callback each iteration with the disk block number
|
||||
* and the size.
|
||||
*/
|
||||
static int
|
||||
ffs_find_disk_blocks_ufs1(ib_params *params, ino_t ino,
|
||||
int (*callback)(ib_params *, void *, uint64_t, uint32_t),
|
||||
void *state)
|
||||
{
|
||||
char sbbuf[SBLOCKSIZE];
|
||||
struct fs *fs;
|
||||
char inodebuf[MAXBSIZE];
|
||||
struct ufs1_dinode *inode;
|
||||
int level_i;
|
||||
int32_t blk, lblk, nblk;
|
||||
int rv;
|
||||
#define LEVELS 4
|
||||
struct {
|
||||
int32_t *blknums;
|
||||
unsigned long blkcount;
|
||||
char diskbuf[MAXBSIZE];
|
||||
} level[LEVELS];
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
assert(callback != NULL);
|
||||
assert(state != NULL);
|
||||
|
||||
/* Read the superblock. */
|
||||
if (!ffs_read_disk_block(params, params->fstype->sblockloc, SBLOCKSIZE,
|
||||
sbbuf))
|
||||
return (0);
|
||||
fs = (struct fs *)sbbuf;
|
||||
#ifndef NO_FFS_SWAP
|
||||
if (params->fstype->needswap)
|
||||
ffs_sb_swap(fs, fs);
|
||||
#endif
|
||||
|
||||
if (fs->fs_inopb <= 0) {
|
||||
warnx("Bad inopb %d in superblock in `%s'",
|
||||
fs->fs_inopb, params->filesystem);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Read the inode. */
|
||||
if (! ffs_read_disk_block(params,
|
||||
fsbtodb(fs, ino_to_fsba(fs, ino)) + params->fstype->offset,
|
||||
fs->fs_bsize, inodebuf))
|
||||
return (0);
|
||||
inode = (struct ufs1_dinode *)inodebuf;
|
||||
inode += ino_to_fsbo(fs, ino);
|
||||
#ifndef NO_FFS_SWAP
|
||||
if (params->fstype->needswap)
|
||||
ffs_dinode1_swap(inode, inode);
|
||||
#endif
|
||||
|
||||
/* Get the block count and initialize for our block walk. */
|
||||
nblk = howmany(inode->di_size, fs->fs_bsize);
|
||||
lblk = 0;
|
||||
level_i = 0;
|
||||
level[0].blknums = &inode->di_db[0];
|
||||
level[0].blkcount = NDADDR;
|
||||
level[1].blknums = &inode->di_ib[0];
|
||||
level[1].blkcount = 1;
|
||||
level[2].blknums = &inode->di_ib[1];
|
||||
level[2].blkcount = 1;
|
||||
level[3].blknums = &inode->di_ib[2];
|
||||
level[3].blkcount = 1;
|
||||
|
||||
/* Walk the data blocks. */
|
||||
while (nblk > 0) {
|
||||
|
||||
/*
|
||||
* If there are no more blocks at this indirection
|
||||
* level, move up one indirection level and loop.
|
||||
*/
|
||||
if (level[level_i].blkcount == 0) {
|
||||
if (++level_i == LEVELS)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the next block at this level. */
|
||||
blk = *(level[level_i].blknums++);
|
||||
level[level_i].blkcount--;
|
||||
if (params->fstype->needswap)
|
||||
blk = bswap32(blk);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "ino %lu blk %lu level %d\n", ino, blk,
|
||||
level_i);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we're not at the direct level, descend one
|
||||
* level, read in that level's new block list,
|
||||
* and loop.
|
||||
*/
|
||||
if (level_i > 0) {
|
||||
level_i--;
|
||||
if (blk == 0)
|
||||
memset(level[level_i].diskbuf, 0, MAXBSIZE);
|
||||
else if (! ffs_read_disk_block(params,
|
||||
fsbtodb(fs, blk) + params->fstype->offset,
|
||||
fs->fs_bsize, level[level_i].diskbuf))
|
||||
return (0);
|
||||
/* XXX ondisk32 */
|
||||
level[level_i].blknums =
|
||||
(int32_t *)level[level_i].diskbuf;
|
||||
level[level_i].blkcount = NINDIR(fs);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* blk is the next direct level block. */
|
||||
#if 0
|
||||
fprintf(stderr, "ino %lu db %lu blksize %lu\n", ino,
|
||||
fsbtodb(fs, blk), sblksize(fs, inode->di_size, lblk));
|
||||
#endif
|
||||
rv = (*callback)(params, state,
|
||||
fsbtodb(fs, blk) + params->fstype->offset,
|
||||
sblksize(fs, (int64_t)inode->di_size, lblk));
|
||||
lblk++;
|
||||
nblk--;
|
||||
if (rv != 1)
|
||||
return (rv);
|
||||
}
|
||||
|
||||
if (nblk != 0) {
|
||||
warnx("Inode %llu in `%s' ran out of blocks?",
|
||||
(unsigned long long)ino, params->filesystem);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This iterates over the data blocks belonging to an inode,
|
||||
* making a callback each iteration with the disk block number
|
||||
* and the size.
|
||||
*/
|
||||
static int
|
||||
ffs_find_disk_blocks_ufs2(ib_params *params, ino_t ino,
|
||||
int (*callback)(ib_params *, void *, uint64_t, uint32_t),
|
||||
void *state)
|
||||
{
|
||||
char sbbuf[SBLOCKSIZE];
|
||||
struct fs *fs;
|
||||
char inodebuf[MAXBSIZE];
|
||||
struct ufs2_dinode *inode;
|
||||
int level_i;
|
||||
int64_t blk, lblk, nblk;
|
||||
int rv;
|
||||
#define LEVELS 4
|
||||
struct {
|
||||
int64_t *blknums;
|
||||
unsigned long blkcount;
|
||||
char diskbuf[MAXBSIZE];
|
||||
} level[LEVELS];
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
assert(callback != NULL);
|
||||
assert(state != NULL);
|
||||
|
||||
/* Read the superblock. */
|
||||
if (!ffs_read_disk_block(params, params->fstype->sblockloc, SBLOCKSIZE,
|
||||
sbbuf))
|
||||
return (0);
|
||||
fs = (struct fs *)sbbuf;
|
||||
#ifndef NO_FFS_SWAP
|
||||
if (params->fstype->needswap)
|
||||
ffs_sb_swap(fs, fs);
|
||||
#endif
|
||||
|
||||
if (fs->fs_inopb <= 0) {
|
||||
warnx("Bad inopb %d in superblock in `%s'",
|
||||
fs->fs_inopb, params->filesystem);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Read the inode. */
|
||||
if (! ffs_read_disk_block(params,
|
||||
fsbtodb(fs, ino_to_fsba(fs, ino)) + params->fstype->offset,
|
||||
fs->fs_bsize, inodebuf))
|
||||
return (0);
|
||||
inode = (struct ufs2_dinode *)inodebuf;
|
||||
inode += ino_to_fsbo(fs, ino);
|
||||
#ifndef NO_FFS_SWAP
|
||||
if (params->fstype->needswap)
|
||||
ffs_dinode2_swap(inode, inode);
|
||||
#endif
|
||||
|
||||
/* Get the block count and initialize for our block walk. */
|
||||
nblk = howmany(inode->di_size, fs->fs_bsize);
|
||||
lblk = 0;
|
||||
level_i = 0;
|
||||
level[0].blknums = &inode->di_db[0];
|
||||
level[0].blkcount = NDADDR;
|
||||
level[1].blknums = &inode->di_ib[0];
|
||||
level[1].blkcount = 1;
|
||||
level[2].blknums = &inode->di_ib[1];
|
||||
level[2].blkcount = 1;
|
||||
level[3].blknums = &inode->di_ib[2];
|
||||
level[3].blkcount = 1;
|
||||
|
||||
/* Walk the data blocks. */
|
||||
while (nblk > 0) {
|
||||
|
||||
/*
|
||||
* If there are no more blocks at this indirection
|
||||
* level, move up one indirection level and loop.
|
||||
*/
|
||||
if (level[level_i].blkcount == 0) {
|
||||
if (++level_i == LEVELS)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the next block at this level. */
|
||||
blk = *(level[level_i].blknums++);
|
||||
level[level_i].blkcount--;
|
||||
if (params->fstype->needswap)
|
||||
blk = bswap64(blk);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "ino %lu blk %llu level %d\n", ino,
|
||||
(unsigned long long)blk, level_i);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we're not at the direct level, descend one
|
||||
* level, read in that level's new block list,
|
||||
* and loop.
|
||||
*/
|
||||
if (level_i > 0) {
|
||||
level_i--;
|
||||
if (blk == 0)
|
||||
memset(level[level_i].diskbuf, 0, MAXBSIZE);
|
||||
else if (! ffs_read_disk_block(params,
|
||||
fsbtodb(fs, blk) + params->fstype->offset,
|
||||
fs->fs_bsize, level[level_i].diskbuf))
|
||||
return (0);
|
||||
level[level_i].blknums =
|
||||
(int64_t *)level[level_i].diskbuf;
|
||||
level[level_i].blkcount = NINDIR(fs);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* blk is the next direct level block. */
|
||||
#if 0
|
||||
fprintf(stderr, "ino %lu db %llu blksize %lu\n", ino,
|
||||
fsbtodb(fs, blk), sblksize(fs, inode->di_size, lblk));
|
||||
#endif
|
||||
rv = (*callback)(params, state,
|
||||
fsbtodb(fs, blk) + params->fstype->offset,
|
||||
sblksize(fs, (int64_t)inode->di_size, lblk));
|
||||
lblk++;
|
||||
nblk--;
|
||||
if (rv != 1)
|
||||
return (rv);
|
||||
}
|
||||
|
||||
if (nblk != 0) {
|
||||
warnx("Inode %llu in `%s' ran out of blocks?",
|
||||
(unsigned long long)ino, params->filesystem);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This callback reads a block of the root directory,
|
||||
* searches for an entry for the secondary bootstrap,
|
||||
* and saves the inode number if one is found.
|
||||
*/
|
||||
static int
|
||||
ffs_findstage2_ino(ib_params *params, void *_ino,
|
||||
uint64_t blk, uint32_t blksize)
|
||||
{
|
||||
char dirbuf[MAXBSIZE];
|
||||
struct direct *de, *ede;
|
||||
uint32_t ino;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
assert(params->stage2 != NULL);
|
||||
assert(_ino != NULL);
|
||||
|
||||
/* Skip directory holes. */
|
||||
if (blk == 0)
|
||||
return (1);
|
||||
|
||||
/* Read the directory block. */
|
||||
if (! ffs_read_disk_block(params, blk, blksize, dirbuf))
|
||||
return (0);
|
||||
|
||||
/* Loop over the directory entries. */
|
||||
de = (struct direct *)&dirbuf[0];
|
||||
ede = (struct direct *)&dirbuf[blksize];
|
||||
while (de < ede) {
|
||||
ino = de->d_fileno;
|
||||
if (params->fstype->needswap) {
|
||||
ino = bswap32(ino);
|
||||
de->d_reclen = bswap16(de->d_reclen);
|
||||
}
|
||||
if (ino != 0 && strcmp(de->d_name, params->stage2) == 0) {
|
||||
*((uint32_t *)_ino) = ino;
|
||||
return (2);
|
||||
}
|
||||
if (de->d_reclen == 0)
|
||||
break;
|
||||
de = (struct direct *)((char *)de + de->d_reclen);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
struct findblks_state {
|
||||
uint32_t maxblk;
|
||||
uint32_t nblk;
|
||||
ib_block *blocks;
|
||||
};
|
||||
|
||||
/* This callback records the blocks of the secondary bootstrap. */
|
||||
static int
|
||||
ffs_findstage2_blocks(ib_params *params, void *_state,
|
||||
uint64_t blk, uint32_t blksize)
|
||||
{
|
||||
struct findblks_state *state = _state;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->stage2 != NULL);
|
||||
assert(_state != NULL);
|
||||
|
||||
if (state->nblk == state->maxblk) {
|
||||
warnx("Secondary bootstrap `%s' has too many blocks (max %d)",
|
||||
params->stage2, state->maxblk);
|
||||
return (0);
|
||||
}
|
||||
state->blocks[state->nblk].block = blk;
|
||||
state->blocks[state->nblk].blocksize = blksize;
|
||||
state->nblk++;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* publicly visible functions
|
||||
*/
|
||||
|
||||
static off_t sblock_try[] = SBLOCKSEARCH;
|
||||
|
||||
int
|
||||
ffs_match(ib_params *params)
|
||||
{
|
||||
return ffs_match_common(params, (off_t) 0);
|
||||
}
|
||||
|
||||
int
|
||||
raid_match(ib_params *params)
|
||||
{
|
||||
/* XXX Assumes 512 bytes / sector */
|
||||
if (params->sectorsize != 512) {
|
||||
warnx("Media is %d bytes/sector."
|
||||
" RAID is only supported on 512 bytes/sector media.",
|
||||
params->sectorsize);
|
||||
return 0;
|
||||
}
|
||||
return ffs_match_common(params, (off_t) RF_PROTECTED_SECTORS);
|
||||
}
|
||||
|
||||
int
|
||||
ffs_match_common(ib_params *params, off_t offset)
|
||||
{
|
||||
char sbbuf[SBLOCKSIZE];
|
||||
struct fs *fs;
|
||||
int i;
|
||||
off_t loc;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
|
||||
fs = (struct fs *)sbbuf;
|
||||
for (i = 0; sblock_try[i] != -1; i++) {
|
||||
loc = sblock_try[i] / params->sectorsize + offset;
|
||||
if (!ffs_read_disk_block(params, loc, SBLOCKSIZE, sbbuf))
|
||||
continue;
|
||||
switch (fs->fs_magic) {
|
||||
case FS_UFS2_MAGIC:
|
||||
is_ufs2 = 1;
|
||||
/* FALLTHROUGH */
|
||||
case FS_UFS1_MAGIC:
|
||||
params->fstype->needswap = 0;
|
||||
params->fstype->blocksize = fs->fs_bsize;
|
||||
params->fstype->sblockloc = loc;
|
||||
params->fstype->offset = offset;
|
||||
break;
|
||||
#ifndef FFS_NO_SWAP
|
||||
case FS_UFS2_MAGIC_SWAPPED:
|
||||
is_ufs2 = 1;
|
||||
/* FALLTHROUGH */
|
||||
case FS_UFS1_MAGIC_SWAPPED:
|
||||
params->fstype->needswap = 1;
|
||||
params->fstype->blocksize = bswap32(fs->fs_bsize);
|
||||
params->fstype->sblockloc = loc;
|
||||
params->fstype->offset = offset;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if (!is_ufs2 && sblock_try[i] == SBLOCK_UFS2)
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ffs_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
|
||||
{
|
||||
int rv;
|
||||
uint32_t ino;
|
||||
struct findblks_state state;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->stage2 != NULL);
|
||||
assert(maxblk != NULL);
|
||||
assert(blocks != NULL);
|
||||
|
||||
if (params->flags & IB_STAGE2START)
|
||||
return (hardcode_stage2(params, maxblk, blocks));
|
||||
|
||||
/* The secondary bootstrap must be clearly in /. */
|
||||
if (params->stage2[0] == '/')
|
||||
params->stage2++;
|
||||
if (strchr(params->stage2, '/') != NULL) {
|
||||
warnx("The secondary bootstrap `%s' must be in /",
|
||||
params->stage2);
|
||||
warnx("(Path must be relative to the file system in `%s')",
|
||||
params->filesystem);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Get the inode number of the secondary bootstrap. */
|
||||
if (is_ufs2)
|
||||
rv = ffs_find_disk_blocks_ufs2(params, ROOTINO,
|
||||
ffs_findstage2_ino, &ino);
|
||||
else
|
||||
rv = ffs_find_disk_blocks_ufs1(params, ROOTINO,
|
||||
ffs_findstage2_ino, &ino);
|
||||
if (rv != 2) {
|
||||
warnx("Could not find secondary bootstrap `%s' in `%s'",
|
||||
params->stage2, params->filesystem);
|
||||
warnx("(Path must be relative to the file system in `%s')",
|
||||
params->filesystem);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Record the disk blocks of the secondary bootstrap. */
|
||||
state.maxblk = *maxblk;
|
||||
state.nblk = 0;
|
||||
state.blocks = blocks;
|
||||
if (is_ufs2)
|
||||
rv = ffs_find_disk_blocks_ufs2(params, ino,
|
||||
ffs_findstage2_blocks, &state);
|
||||
else
|
||||
rv = ffs_find_disk_blocks_ufs1(params, ino,
|
||||
ffs_findstage2_blocks, &state);
|
||||
if (! rv) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
*maxblk = state.nblk;
|
||||
return (1);
|
||||
}
|
133
usr.sbin/installboot/fstypes.c
Normal file
133
usr.sbin/installboot/fstypes.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* $NetBSD: fstypes.c,v 1.13 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 Matt Fredette 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: fstypes.c,v 1.13 2010/01/14 16:27:49 tsutsui Exp $");
|
||||
#endif /* !__lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "installboot.h"
|
||||
|
||||
struct ib_fs fstypes[] = {
|
||||
#ifndef NO_STAGE2
|
||||
{ .name = "ffs", .match = ffs_match, .findstage2 = ffs_findstage2 },
|
||||
{ .name = "raid", .match = raid_match, .findstage2 = ffs_findstage2 },
|
||||
{ .name = "raw", .match = raw_match, .findstage2 = raw_findstage2 },
|
||||
#endif
|
||||
{ .name = NULL, }
|
||||
};
|
||||
|
||||
#ifndef NO_STAGE2
|
||||
int
|
||||
hardcode_stage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
|
||||
{
|
||||
struct stat s2sb;
|
||||
uint32_t nblk, i;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->stage2 != NULL);
|
||||
assert(maxblk != NULL);
|
||||
assert(blocks != NULL);
|
||||
assert((params->flags & IB_STAGE2START) != 0);
|
||||
assert(params->fstype != NULL);
|
||||
assert(params->fstype->blocksize != 0);
|
||||
|
||||
if (stat(params->stage2, &s2sb) == -1) {
|
||||
warn("Examining `%s'", params->stage2);
|
||||
return (0);
|
||||
}
|
||||
if (!S_ISREG(s2sb.st_mode)) {
|
||||
warnx("`%s' must be a regular file", params->stage2);
|
||||
return (0);
|
||||
}
|
||||
|
||||
nblk = s2sb.st_size / params->fstype->blocksize;
|
||||
if (s2sb.st_size % params->fstype->blocksize != 0)
|
||||
nblk++;
|
||||
#if 0
|
||||
fprintf(stderr, "for %s got size %lld blksize %u blocks %u\n",
|
||||
params->stage2, s2sb.st_size, params->fstype->blocksize, nblk);
|
||||
#endif
|
||||
if (nblk > *maxblk) {
|
||||
warnx("Secondary bootstrap `%s' has too many blocks "
|
||||
"(calculated %u, maximum %u)",
|
||||
params->stage2, nblk, *maxblk);
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (i = 0; i < nblk; i++) {
|
||||
blocks[i].block = params->s2start +
|
||||
i * (params->fstype->blocksize / params->sectorsize);
|
||||
blocks[i].blocksize = params->fstype->blocksize;
|
||||
}
|
||||
*maxblk = nblk;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
raw_match(ib_params *params)
|
||||
{
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->fstype != NULL);
|
||||
|
||||
params->fstype->blocksize = 8192; // XXX: hardcode
|
||||
return (1); /* can always write to a "raw" file system */
|
||||
}
|
||||
|
||||
int
|
||||
raw_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
|
||||
{
|
||||
|
||||
assert(params != NULL);
|
||||
assert(params->stage2 != NULL);
|
||||
assert(maxblk != NULL);
|
||||
assert(blocks != NULL);
|
||||
|
||||
if ((params->flags & IB_STAGE2START) == 0) {
|
||||
warnx("Need `-B bno' for raw file systems");
|
||||
return (0);
|
||||
}
|
||||
return (hardcode_stage2(params, maxblk, blocks));
|
||||
}
|
||||
#endif
|
895
usr.sbin/installboot/installboot.8
Normal file
895
usr.sbin/installboot/installboot.8
Normal file
|
@ -0,0 +1,895 @@
|
|||
.\" $NetBSD: installboot.8,v 1.79 2011/11/03 20:09:18 martin Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002-2009 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.
|
||||
.\"
|
||||
.Dd August 3, 2011
|
||||
.Dt INSTALLBOOT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm installboot
|
||||
.Nd install disk bootstrap software
|
||||
.
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl fnv
|
||||
.Op Fl B Ar s2bno
|
||||
.Op Fl b Ar s1bno
|
||||
.Op Fl m Ar machine
|
||||
.Op Fl o Ar options
|
||||
.Op Fl t Ar fstype
|
||||
.Ar filesystem
|
||||
.Ar primary
|
||||
.Op Ar secondary
|
||||
.Nm
|
||||
.Fl c
|
||||
.Op Fl fnv
|
||||
.Op Fl m Ar machine
|
||||
.Op Fl o Ar options
|
||||
.Op Fl t Ar fstype
|
||||
.Ar filesystem
|
||||
.Nm
|
||||
.Fl e
|
||||
.Op Fl fnv
|
||||
.Op Fl m Ar machine
|
||||
.Op Fl o Ar options
|
||||
.Ar bootstrap
|
||||
.
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility installs and removes
|
||||
.Nx
|
||||
disk bootstrap software into a file system.
|
||||
.Nm
|
||||
can install
|
||||
.Ar primary
|
||||
into
|
||||
.Ar filesystem ,
|
||||
or disable an existing bootstrap in
|
||||
.Ar filesystem .
|
||||
.Pp
|
||||
On some architectures the options of an existing installed bootstrap,
|
||||
or those of a bootstrap file can be changed.
|
||||
Installing a new primary bootstrap will reset those options to default
|
||||
values.
|
||||
.Pp
|
||||
Generally,
|
||||
.Nx
|
||||
disk bootstrap software consists of two parts: a
|
||||
.Dq primary
|
||||
bootstrap program usually written into the disklabel area of the
|
||||
file system by
|
||||
.Nm ,
|
||||
and a
|
||||
.Dq secondary
|
||||
bootstrap program that usually resides as an ordinary file in the file system.
|
||||
.Pp
|
||||
When booting, the primary bootstrap program is loaded and invoked by
|
||||
the machine's PROM or BIOS.
|
||||
After receiving control of the system it loads and runs the secondary
|
||||
bootstrap program, which in turn loads and runs the kernel.
|
||||
The secondary bootstrap may allow control over various boot parameters
|
||||
passed to the kernel.
|
||||
.Pp
|
||||
Perform the following steps to make a file system bootable:
|
||||
.Bl -enum
|
||||
.It
|
||||
Copy the secondary bootstrap (usually
|
||||
.Pa /usr/mdec/boot. Ns Sy MACHINE
|
||||
or
|
||||
.Pa /usr/mdec/boot )
|
||||
to the root directory of the target file system.
|
||||
.Pp
|
||||
.
|
||||
.It
|
||||
Use
|
||||
.Nm
|
||||
to install the primary bootstrap program
|
||||
(usually
|
||||
.Pa /usr/mdec/bootxx_ Ns Sy FSTYPE )
|
||||
into
|
||||
.Ar filesystem .
|
||||
.Pp
|
||||
The following platforms do not require this step if the primary bootstrap
|
||||
already exists and the secondary bootstrap file is just being updated:
|
||||
.Sy alpha ,
|
||||
.Sy amd64 ,
|
||||
.Sy amiga ,
|
||||
.Sy i386 ,
|
||||
.Sy pmax ,
|
||||
.Sy sparc64 ,
|
||||
and
|
||||
.Sy vax .
|
||||
.Pp
|
||||
The following platform does not require the first step since a
|
||||
single bootstrap file is used.
|
||||
The single bootstrap is installed like the primary bootstrap on
|
||||
other platforms:
|
||||
.Sy next68k .
|
||||
.Pp
|
||||
.El
|
||||
.Pp
|
||||
The options and arguments recognized by
|
||||
.Nm
|
||||
are as follows:
|
||||
.
|
||||
.Bl -tag -width "optionsxxx"
|
||||
.
|
||||
.It Fl B Ar s2bno
|
||||
When hard-coding the blocks of
|
||||
.Ar secondary
|
||||
into
|
||||
.Ar primary ,
|
||||
start from block
|
||||
.Ar s2bno
|
||||
instead of trying to determine the block numbers occupied by
|
||||
.Ar secondary
|
||||
by examining
|
||||
.Ar filesystem .
|
||||
If this option is supplied,
|
||||
.Ar secondary
|
||||
should refer to an actual secondary bootstrap (rather than the
|
||||
file name of the one present in
|
||||
.Ar filesystem )
|
||||
so that its size can be determined.
|
||||
.
|
||||
.It Fl b Ar s1bno
|
||||
Install
|
||||
.Ar primary
|
||||
at block number
|
||||
.Ar s1bno
|
||||
instead of the default location for the machine and file system type.
|
||||
.Sy [ alpha ,
|
||||
.Sy pmax ,
|
||||
.Sy vax ]
|
||||
.
|
||||
.It Fl c
|
||||
Clear (remove) any existing bootstrap instead of installing one.
|
||||
.
|
||||
.It Fl e
|
||||
Edit the options of an existing bootstrap.
|
||||
This can be use to change the options in bootxx_xxxfs files,
|
||||
raw disk partitions, and the
|
||||
.Pa pxeboot_ia32.bin
|
||||
file.
|
||||
With
|
||||
.Fl v
|
||||
and without
|
||||
.Fl o ,
|
||||
show the current options.
|
||||
.Sy [ amd64 , i386 ]
|
||||
.
|
||||
.It Fl f
|
||||
Forces
|
||||
.Nm
|
||||
to ignore some errors.
|
||||
.
|
||||
.It Fl m Ar machine
|
||||
Use
|
||||
.Ar machine
|
||||
as the target machine type.
|
||||
The default machine is determined from
|
||||
.Xr uname 3
|
||||
and then
|
||||
.Ev MACHINE .
|
||||
The following machines are currently supported by
|
||||
.Nm :
|
||||
.Bd -ragged -offset indent
|
||||
.Sy alpha ,
|
||||
.Sy amd64 ,
|
||||
.Sy amiga ,
|
||||
.Sy ews4800mips ,
|
||||
.Sy hp300 ,
|
||||
.Sy hp700 ,
|
||||
.Sy i386 ,
|
||||
.Sy landisk ,
|
||||
.Sy macppc ,
|
||||
.Sy news68k ,
|
||||
.Sy newsmips ,
|
||||
.Sy next68k ,
|
||||
.Sy pmax ,
|
||||
.Sy sparc ,
|
||||
.Sy sparc64 ,
|
||||
.Sy sun2 ,
|
||||
.Sy sun3 ,
|
||||
.Sy vax ,
|
||||
.Sy x68k
|
||||
.Ed
|
||||
.
|
||||
.
|
||||
.It Fl n
|
||||
Do not write to
|
||||
.Ar filesystem .
|
||||
.
|
||||
.It Fl o Ar options
|
||||
Machine specific
|
||||
.Nm
|
||||
options, comma separated.
|
||||
.Pp
|
||||
Supported options are (with the machines for they are valid in brackets):
|
||||
.
|
||||
.Bl -tag -offset indent -width alphasum
|
||||
.
|
||||
.It Sy alphasum
|
||||
.Sy [ alpha ]
|
||||
Recalculate and restore the Alpha checksum.
|
||||
This is the default for
|
||||
.Nx Ns Tn /alpha .
|
||||
.
|
||||
.It Sy append
|
||||
.Sy [ alpha ,
|
||||
.Sy pmax ,
|
||||
.Sy vax ]
|
||||
Append
|
||||
.Ar primary
|
||||
to the end of
|
||||
.Ar filesystem ,
|
||||
which must be a regular file in this case.
|
||||
.
|
||||
.It Sy bootconf
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
(Don't) read a
|
||||
.Dq boot.cfg
|
||||
file.
|
||||
.
|
||||
.It Sy command=\*[Lt]boot command\*[Gt]
|
||||
.Sy [ amiga ]
|
||||
Modify the default boot command line.
|
||||
.
|
||||
.It Sy console=\*[Lt]console name\*[Gt]
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
Set the console device, \*[Lt]console name\*[Gt] must be one of:
|
||||
pc, com0, com1, com2, com3, com0kbd, com1kbd, com2kbd or com3kbd.
|
||||
.
|
||||
.It Sy ioaddr=\*[Lt]ioaddr\*[Gt]
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
Set the IO address to be used for the console serial port.
|
||||
Defaults to the IO address used by the system BIOS for the specified port.
|
||||
.
|
||||
.It Sy keymap=\*[Lt]keymap\*[Gt]
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
Set a boot time keyboard translation map.
|
||||
Each character in \*[Lt]keymap\*[Gt] will be replaced by the one following it.
|
||||
For example, an argument of
|
||||
.Dq zyz
|
||||
would swap the lowercase letters
|
||||
.Sq y
|
||||
and
|
||||
.Sq z .
|
||||
.
|
||||
.It Sy modules
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
(Don't) load kernel modules.
|
||||
.
|
||||
.It Sy password=\*[Lt]password\*[Gt]
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
Set the password which must be entered before the boot menu can be accessed.
|
||||
.
|
||||
.It Sy resetvideo
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
Reset the video before booting.
|
||||
.
|
||||
.It Sy speed=\*[Lt]baud rate\*[Gt]
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
Set the baud rate for the serial console.
|
||||
If a value of zero is specified, then the current baud rate (set by the
|
||||
BIOS) will be used.
|
||||
.
|
||||
.It Sy sunsum
|
||||
.Sy [ alpha ,
|
||||
.Sy pmax ,
|
||||
.Sy vax ]
|
||||
Recalculate and restore the Sun and
|
||||
.Nx Ns Tn /sparc
|
||||
compatible checksum.
|
||||
.Em Note :
|
||||
The existing
|
||||
.Nx Ns Tn /sparc
|
||||
disklabel should use no more than 4 partitions.
|
||||
.
|
||||
.It Sy timeout=\*[Lt]seconds\*[Gt]
|
||||
.Sy [ amd64 ,
|
||||
.Sy i386 ]
|
||||
Set the timeout before the automatic boot begins to the given number of seconds.
|
||||
.El
|
||||
.
|
||||
.It Fl t Ar fstype
|
||||
Use
|
||||
.Ar fstype
|
||||
as the type of
|
||||
.Ar filesystem .
|
||||
The default operation is to attempt to auto-detect this setting.
|
||||
The following file system types are currently supported by
|
||||
.Nm :
|
||||
.
|
||||
.Bl -tag -offset indent -width raid
|
||||
.
|
||||
.It Sy ffs
|
||||
.Bx
|
||||
Fast File System.
|
||||
.
|
||||
.It Sy raid
|
||||
Mirrored RAIDframe File System.
|
||||
.
|
||||
.It Sy raw
|
||||
.Sq Raw
|
||||
image.
|
||||
Note: if a platform needs to hard-code the block offset of the secondary
|
||||
bootstrap, it cannot be searched for on this file system type, and must
|
||||
be provided with
|
||||
.Fl B Ar s2bno .
|
||||
.El
|
||||
.
|
||||
.It Fl v
|
||||
Verbose operation.
|
||||
.
|
||||
.It Ar filesystem
|
||||
The path name of the device or file system image that
|
||||
.Nm
|
||||
is to operate on.
|
||||
It is not necessary for
|
||||
.Ar filesystem
|
||||
to be a currently mounted file system.
|
||||
.
|
||||
.It Ar primary
|
||||
The path name of the
|
||||
.Dq primary
|
||||
boot block to install.
|
||||
The path name must refer to a file in a file system that is currently
|
||||
mounted.
|
||||
.
|
||||
.It Ar secondary
|
||||
The path name of the
|
||||
.Dq secondary
|
||||
boot block, relative to the root of
|
||||
the file system in the device or image specified by the
|
||||
.Ar filesystem
|
||||
argument.
|
||||
Note that this may refer to a file in a file system that is not mounted.
|
||||
Most systems require
|
||||
.Ar secondary
|
||||
to be in the
|
||||
.Dq root
|
||||
directory of the file system, so the leading
|
||||
.Dq Pa /
|
||||
is not necessary on
|
||||
.Ar secondary .
|
||||
.Pp
|
||||
Only certain combinations of
|
||||
platform
|
||||
.Pq Fl m Ar machine
|
||||
and file system type
|
||||
.Pq Fl t Ar fstype
|
||||
require that the name of the secondary bootstrap is
|
||||
supplied as
|
||||
.Ar secondary ,
|
||||
so that information such as the disk block numbers occupied
|
||||
by the secondary bootstrap can be stored in the primary bootstrap.
|
||||
These are:
|
||||
.Bl -column "Platform" "File systems" -offset indent
|
||||
.It Sy "Platform" Ta Sy "File systems"
|
||||
.It macppc Ta ffs, raw
|
||||
.It news68k Ta ffs, raw
|
||||
.It newsmips Ta ffs, raw
|
||||
.It sparc Ta ffs, raid, raw
|
||||
.It sun2 Ta ffs, raw
|
||||
.It sun3 Ta ffs, raw
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
.Nm
|
||||
exits 0 on success, and \*[Gt]0 if an error occurs.
|
||||
.
|
||||
.Sh ENVIRONMENT
|
||||
.Nm
|
||||
uses the following environment variables:
|
||||
.
|
||||
.Bl -tag -width "MACHINE"
|
||||
.
|
||||
.It Ev MACHINE
|
||||
Default value for
|
||||
.Ar machine ,
|
||||
overriding the result from
|
||||
.Xr uname 3 .
|
||||
.
|
||||
.El
|
||||
.
|
||||
.Sh FILES
|
||||
Most
|
||||
.Nx
|
||||
ports will contain variations of the following files:
|
||||
.Pp
|
||||
.Bl -tag -width /usr/mdec/bootxx_ustarfs
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx_ Ns Sy FSTYPE
|
||||
Primary bootstrap for file system type
|
||||
.Sy FSTYPE .
|
||||
Installed into the bootstrap area of the file system by
|
||||
.Nm .
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx_fat16
|
||||
Primary bootstrap for
|
||||
.Tn MS-DOS
|
||||
.Sy FAT16
|
||||
file systems.
|
||||
This differs from
|
||||
.Nm bootxx_msdos
|
||||
in that it doesn't require the filesystem to have been initialised with
|
||||
any
|
||||
.Ql reserved sectors .
|
||||
It also uses the information in the
|
||||
.Ql Boot Parameter Block
|
||||
to get the media and filesytem properties.
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx_ffsv1
|
||||
Primary bootstrap for
|
||||
.Sy FFSv1
|
||||
file systems
|
||||
(the "traditional"
|
||||
.Nx
|
||||
file system).
|
||||
Use
|
||||
.Xr dumpfs 8
|
||||
to confirm the file system format is
|
||||
.Sy FFSv1 .
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx_ffsv2
|
||||
Primary bootstrap for
|
||||
.Sy FFSv2
|
||||
file systems.
|
||||
Use
|
||||
.Xr dumpfs 8
|
||||
to confirm the file system format is
|
||||
.Sy FFSv2 .
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx_lfsv1
|
||||
Primary bootstrap for
|
||||
.Sy LFSv1
|
||||
file systems.
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx_lfsv2
|
||||
Primary bootstrap for
|
||||
.Sy LFSv2
|
||||
file systems
|
||||
(the default LFS version).
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx_msdos
|
||||
Primary bootstrap for
|
||||
.Tn MS-DOS
|
||||
.Sy FAT
|
||||
file systems.
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx_ustarfs
|
||||
Primary bootstrap for
|
||||
.Sy TARFS
|
||||
boot images.
|
||||
This is used by various install media.
|
||||
.
|
||||
.It Pa /usr/mdec/boot. Ns Sy MACHINE
|
||||
Secondary bootstrap for machine type
|
||||
.Sy MACHINE .
|
||||
This should be installed into the file system before
|
||||
.Nm
|
||||
is run.
|
||||
.
|
||||
.It Pa /usr/mdec/boot
|
||||
Synonym for
|
||||
.Pa /usr/mdec/boot. Ns Sy MACHINE
|
||||
.
|
||||
.It Pa /boot. Ns Sy MACHINE
|
||||
Installed copy of secondary bootstrap for machine type
|
||||
.Sy MACHINE .
|
||||
.
|
||||
.It Pa /boot
|
||||
Installed copy of secondary bootstrap.
|
||||
Searched for by the primary bootstrap if
|
||||
.Pa /boot. Ns Sy MACHINE
|
||||
is not found.
|
||||
.
|
||||
.El
|
||||
.
|
||||
.Ss Nx Ns Tn /macppc files
|
||||
.
|
||||
.Bl -tag -width /usr/mdec/bootxx_ustarfs
|
||||
.
|
||||
.It Pa /usr/mdec/bootxx
|
||||
.Nx Ns Tn /macppc
|
||||
primary bootstrap.
|
||||
.
|
||||
.It Pa /usr/mdec/ofwboot
|
||||
.Nx Ns Tn /macppc
|
||||
secondary bootstrap.
|
||||
.
|
||||
.It Pa /ofwboot
|
||||
Installed copy of
|
||||
.Nx Ns Tn /macppc
|
||||
secondary bootstrap.
|
||||
.
|
||||
.El
|
||||
.
|
||||
.Ss Nx Ns Tn /next68k files
|
||||
.
|
||||
.Bl -tag -width /usr/mdec/bootxx_ustarfs
|
||||
.
|
||||
.It Pa /usr/mdec/boot
|
||||
.Nx Ns Tn /next68k
|
||||
bootstrap.
|
||||
.
|
||||
.El
|
||||
.
|
||||
.Ss Nx Ns Tn /sparc64 files
|
||||
.
|
||||
.Bl -tag -width /usr/mdec/bootxx_ustarfs
|
||||
.
|
||||
.It Pa /usr/mdec/bootblk
|
||||
.Nx Ns Tn /sparc64
|
||||
primary bootstrap.
|
||||
.
|
||||
.It Pa /usr/mdec/ofwboot
|
||||
.Nx Ns Tn /sparc64
|
||||
secondary bootstrap.
|
||||
.
|
||||
.It Pa /ofwboot
|
||||
Installed copy of
|
||||
.Nx Ns Tn /sparc64
|
||||
secondary bootstrap.
|
||||
.
|
||||
.El
|
||||
.
|
||||
.Sh EXAMPLES
|
||||
.
|
||||
.Ss common
|
||||
Verbosely install the Berkeley Fast File System primary bootstrap on to disk
|
||||
.Sq sd0 :
|
||||
.Dl Ic installboot -v /dev/rsd0c /usr/mdec/bootxx_ffs
|
||||
Note: the
|
||||
.Dq whole disk
|
||||
partition (c on some ports, d on others) is used here, since the a partition
|
||||
probably is already opened (mounted as
|
||||
.Pa / ) ,
|
||||
so
|
||||
.Nm
|
||||
would not be able to access it.
|
||||
.Pp
|
||||
Remove the primary bootstrap from disk
|
||||
.Sq sd1 :
|
||||
.Dl Ic installboot -c /dev/rsd1c
|
||||
.
|
||||
.Ss Nx Ns Tn /amiga
|
||||
Modify the command line to change the default from "netbsd -ASn2" to
|
||||
"netbsd -S":
|
||||
.Dl Ic installboot -m amiga -o command="netbsd -S" /dev/rsd0a /usr/mdec/bootxx_ffs
|
||||
.
|
||||
.Ss Nx Ns Tn /ews4800mips
|
||||
Install the System V Boot File System primary bootstrap on to disk
|
||||
.Sq sd0 ,
|
||||
with the secondary bootstrap
|
||||
.Sq Pa /boot
|
||||
already present in the SysVBFS partition on the disk:
|
||||
.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx_bfs
|
||||
.
|
||||
.Ss Nx Ns Tn /i386 and Nx Ns Tn /amd64
|
||||
Install new boot blocks on an existing mounted root file system on
|
||||
.Sq wd0 ,
|
||||
setting the timeout to five seconds, after copying a new secondary
|
||||
bootstrap:
|
||||
.Dl Ic cp /usr/mdec/boot /boot
|
||||
.Dl Ic installboot -v -o timeout=5 /dev/rwd0a /usr/mdec/bootxx_ffsv1
|
||||
.
|
||||
.Pp
|
||||
Create a bootable CD-ROM with an ISO9660
|
||||
file system for an i386 system with a serial console:
|
||||
.Dl Ic mkdir cdrom
|
||||
.Dl Ic cp sys/arch/i386/compile/mykernel/netbsd cdrom/netbsd
|
||||
.Dl Ic cp /usr/mdec/boot cdrom/boot
|
||||
.Dl Ic cp /usr/mdec/bootxx_cd9660 bootxx
|
||||
.Dl Ic installboot -o console=com0,speed=19200 -m i386 -e bootxx
|
||||
.Dl Ic makefs -t cd9660 -o 'bootimage=i386;bootxx,no-emul-boot' boot.iso \
|
||||
cdrom
|
||||
.
|
||||
.Pp
|
||||
Create a bootable floppy disk with an FFSv1
|
||||
file system for a small custom kernel (note: bigger kernels needing
|
||||
multiple disks are handled with the ustarfs file system):
|
||||
.Dl Ic newfs -s 1440k /dev/rfd0a
|
||||
.Bd -ragged -offset indent-two -compact
|
||||
.Em Note :
|
||||
Ignore the warnings that
|
||||
.Xr newfs 8
|
||||
displays; it can not write a disklabel,
|
||||
which is not a problem for a floppy disk.
|
||||
.Ed
|
||||
.Dl Ic mount /dev/fd0a /mnt
|
||||
.Dl Ic cp /usr/mdec/boot /mnt/boot
|
||||
.Dl Ic gzip -9 \*[Lt] sys/arch/i386/compile/mykernel/netbsd \*[Gt] /mnt/netbsd.gz
|
||||
.Dl Ic umount /mnt
|
||||
.Dl Ic installboot -v /dev/rfd0a /usr/mdec/bootxx_ffsv1
|
||||
.
|
||||
.Pp
|
||||
Create a bootable FAT file system on
|
||||
.Sq wd1a ,
|
||||
which should have the same offset and size as a FAT primary partition
|
||||
in the Master Boot Record (MBR):
|
||||
.Dl Ic newfs_msdos -r 16 /dev/rwd1a
|
||||
.Bd -ragged -offset indent-two -compact
|
||||
.Em Notes :
|
||||
The
|
||||
.Fl r Ar 16
|
||||
is to reserve space for the primary bootstrap.
|
||||
.Xr newfs_msdos 8
|
||||
will display an
|
||||
.Dq MBR type
|
||||
such as
|
||||
.Ql 1 ,
|
||||
.Ql 4 ,
|
||||
or
|
||||
.Ql 6 ;
|
||||
the MBR partition type of the appropriate primary partition should be
|
||||
changed to this value.
|
||||
.Ed
|
||||
.Dl Ic mount -t msdos /dev/wd1a /mnt
|
||||
.Dl Ic cp /usr/mdec/boot /mnt/boot
|
||||
.Dl Ic cp path/to/kernel /mnt/netbsd
|
||||
.Dl Ic umount /mnt
|
||||
.Dl Ic installboot -t raw /dev/rwd1a /usr/mdec/bootxx_msdos
|
||||
.Pp
|
||||
Make the existing FAT16 filesystem on
|
||||
.Sq sd0e
|
||||
bootable.
|
||||
This can be used to make USB memory bootable provided it has 512 byte
|
||||
sectors and that the manufacturer correctly initialised the file system.
|
||||
.Dl Ic mount -t msdos /dev/sd0e /mnt
|
||||
.Dl Ic cp /usr/mdec/boot /mnt/boot
|
||||
.Dl Ic cp path/to/kernel /mnt/netbsd
|
||||
.Dl Ic umount /mnt
|
||||
.Dl Ic installboot /dev/rsd0e /usr/mdec/bootxx_fat16
|
||||
It may also be necessary to use
|
||||
.Nm fdisk
|
||||
to make the device itself bootable.
|
||||
.
|
||||
.Pp
|
||||
Switch the existing installed bootstrap to use a serial console without
|
||||
reinstalling or altering other options such as timeout.
|
||||
.Dl Ic installboot -e -o console=com0 /dev/rwd0a
|
||||
.Ss Nx Ns Tn /macppc
|
||||
Note the
|
||||
.Nm
|
||||
utility is only required for macppc machines with OpenFirmware version 2
|
||||
to boot.
|
||||
OpenFirmware 3 cannot load bootblocks specified in the Apple partition
|
||||
map.
|
||||
.Pp
|
||||
Install the Berkeley Fast File System primary bootstrap on to disk
|
||||
.Sq wd0 :
|
||||
.Dl Ic installboot /dev/rwd0c /usr/mdec/bootxx /ofwboot
|
||||
.Pp
|
||||
The secondary
|
||||
.Nx Ns Tn /macppc
|
||||
bootstrap is located in
|
||||
.Pa /usr/mdec/ofwboot .
|
||||
.Pp
|
||||
The primary bootstrap requires the raw
|
||||
.Pa ofwboot
|
||||
for the secondary bootstrap, not
|
||||
.Pa ofwboot.xcf ,
|
||||
which is used for the OpenFirmware to load kernels.
|
||||
.Ss Nx Ns Tn /next68k
|
||||
Install the bootstrap on to disk
|
||||
.Sq sd0 :
|
||||
.Dl Ic installboot /dev/rsd0c /usr/mdec/boot
|
||||
.Pp
|
||||
.
|
||||
.Ss Nx Ns Tn /pmax
|
||||
Install the Berkeley Fast File System primary bootstrap on to disk
|
||||
.Sq sd0 :
|
||||
.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx_ffs
|
||||
.Pp
|
||||
.Nx Ns Tn /pmax
|
||||
requires that this file system starts at block 0 of the disk.
|
||||
.Pp
|
||||
Install the ISO 9660 primary bootstrap in the file
|
||||
.Pa /tmp/cd-image :
|
||||
.Dl Ic installboot -m pmax /tmp/cd-image /usr/mdec/bootxx_cd9660
|
||||
.Pp
|
||||
Make an ISO 9660 filesystem in the file
|
||||
.Pa /tmp/cd-image
|
||||
and install the ISO 9660 primary bootstrap in the filesystem, where the
|
||||
source directory for the ISO 9660 filesystem contains a kernel, the
|
||||
primary bootstrap
|
||||
.Pa bootxx_cd9660
|
||||
and the secondary bootstrap
|
||||
.Pa boot.pmax :
|
||||
.Dl Ic mkisofs -o /tmp/cd-image -a -l -v iso-source-dir
|
||||
.Dl ...
|
||||
.Dl 48 51 iso-source-dir/bootxx_cd9660
|
||||
.Dl ...
|
||||
.Dl Ic installboot -b `expr 48 \e* 4` /tmp/cd-image /usr/mdec/bootxx_cd9660
|
||||
.
|
||||
.Ss Nx Ns Tn /sparc
|
||||
Install the Berkeley Fast File System primary bootstrap on to disk
|
||||
.Sq sd0 ,
|
||||
with the secondary bootstrap
|
||||
.Sq Pa /boot
|
||||
already present:
|
||||
.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx /boot
|
||||
.
|
||||
.Ss Nx Ns Tn /sparc64
|
||||
Install the primary bootstrap on to disk
|
||||
.Sq sd0 :
|
||||
.Dl Ic installboot /dev/rsd0c /usr/mdec/bootblk
|
||||
.Pp
|
||||
The secondary
|
||||
.Nx Ns Tn /sparc64
|
||||
bootstrap is located in
|
||||
.Pa /usr/mdec/ofwboot .
|
||||
.
|
||||
.Ss Nx Ns Tn /sun2 and Nx Ns Tn /sun3
|
||||
Install the Berkeley Fast File System primary bootstrap on to disk
|
||||
.Sq sd0 ,
|
||||
with the secondary bootstrap
|
||||
.Sq Pa /boot
|
||||
already present:
|
||||
.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx /boot
|
||||
.
|
||||
.Sh SEE ALSO
|
||||
.Xr uname 3 ,
|
||||
.Xr boot 8 ,
|
||||
.Xr disklabel 8 ,
|
||||
.Xr dumpfs 8 ,
|
||||
.Xr fdisk 8 ,
|
||||
.Xr pxeboot 8
|
||||
.
|
||||
.Sh HISTORY
|
||||
This implementation of
|
||||
.Nm
|
||||
appeared in
|
||||
.Nx 1.6 .
|
||||
.
|
||||
.Sh AUTHORS
|
||||
The machine independent portion of this implementation of
|
||||
.Nm
|
||||
was written by Luke Mewburn.
|
||||
The following people contributed to the various machine dependent
|
||||
back-ends:
|
||||
Simon Burge (pmax),
|
||||
Chris Demetriou (alpha),
|
||||
Matthew Fredette (sun2, sun3),
|
||||
Matthew Green (sparc64),
|
||||
Ross Harvey (alpha),
|
||||
Michael Hitch (amiga),
|
||||
Paul Kranenburg (sparc),
|
||||
David Laight (i386),
|
||||
Christian Limpach (next68k),
|
||||
Luke Mewburn (macppc),
|
||||
Matt Thomas (vax),
|
||||
Izumi Tsutsui (news68k, newsmips),
|
||||
and
|
||||
UCHIYAMA Yasushi (ews4800mips).
|
||||
.
|
||||
.Sh BUGS
|
||||
There are not currently primary bootstraps to support all file systems
|
||||
types which are capable of being the root file system.
|
||||
.Pp
|
||||
If a disk has been converted from
|
||||
.Sy FFS
|
||||
to
|
||||
.Sy RAID
|
||||
without the contents of the disk erased, then the original
|
||||
.Sy FFS
|
||||
installation may be auto-detected instead of the
|
||||
.Sy RAID
|
||||
installation.
|
||||
In this case, the
|
||||
.Fl t Ar raid
|
||||
option must be provided.
|
||||
.
|
||||
.Ss Nx Ns Tn /alpha
|
||||
The
|
||||
.Nx Ns Tn /alpha
|
||||
primary bootstrap program can only load the secondary bootstrap program
|
||||
from file systems starting at the beginning (block 0) of disks.
|
||||
Similarly, the secondary bootstrap program can only load kernels from
|
||||
file systems starting at the beginning of disks.
|
||||
.Pp
|
||||
The size of primary bootstrap programs is restricted to 7.5KB, even
|
||||
though some file systems (e.g., ISO 9660) are able to accommodate larger
|
||||
ones.
|
||||
.
|
||||
.Ss Nx Ns Tn /hp300
|
||||
The disk must have a boot partition large enough to hold the bootstrap code.
|
||||
Currently the primary bootstrap must be a LIF format file.
|
||||
.
|
||||
.Ss Nx Ns Tn /i386 and Nx Ns Tn /amd64
|
||||
The bootstrap must be installed in the
|
||||
.Nx
|
||||
partition that starts at the beginning of the mbr partition.
|
||||
If that is a valid filesystem and contains the
|
||||
.Pa /boot
|
||||
program then it will be used as the root filesystem, otherwise the
|
||||
.Sq a
|
||||
partition will be booted.
|
||||
.Pp
|
||||
The size of primary bootstrap programs is restricted to 8KB, even
|
||||
though some file systems (e.g., ISO 9660) are able to accommodate larger
|
||||
ones.
|
||||
.
|
||||
.Ss Nx Ns Tn /macppc
|
||||
Due to restrictions in
|
||||
.Nm
|
||||
and the secondary bootstrap implementation, file systems where kernels exist
|
||||
must start at the beginning of disks.
|
||||
.Pp
|
||||
Currently,
|
||||
.Nm
|
||||
doesn't recognize an existing Apple partition map on the disk
|
||||
and always writes a faked map to make disks bootable.
|
||||
.Pp
|
||||
The
|
||||
.Nx Ns Tn /macppc
|
||||
bootstrap program can't load kernels from
|
||||
.Sy FFSv2
|
||||
partitions.
|
||||
.Ss Nx Ns Tn /next68k
|
||||
The size of bootstrap programs is restricted to the free space before
|
||||
the file system at the beginning of the disk minus 8KB.
|
||||
.
|
||||
.Ss Nx Ns Tn /pmax
|
||||
The
|
||||
.Nx Ns Tn /pmax
|
||||
secondary bootstrap program can only load kernels from file
|
||||
systems starting at the beginning of disks.
|
||||
.Pp
|
||||
The size of primary bootstrap programs is restricted to 7.5KB, even
|
||||
though some file systems (e.g., ISO 9660) are able to accommodate larger
|
||||
ones.
|
||||
.
|
||||
.Ss Nx Ns Tn /sun2 and Nx Ns Tn /sun3
|
||||
The
|
||||
.Nx Ns Tn /sun2
|
||||
and
|
||||
.Nx Ns Tn /sun3
|
||||
secondary bootstrap program can only load kernels from file
|
||||
systems starting at the beginning of disks.
|
||||
.
|
||||
.Ss Nx Ns Tn /vax
|
||||
The
|
||||
.Nx Ns Tn /vax
|
||||
secondary bootstrap program can only load kernels from file systems
|
||||
starting at the beginning of disks.
|
||||
.Pp
|
||||
The size of primary bootstrap programs is restricted to 7.5KB, even
|
||||
though some file systems (e.g., ISO 9660) are able to accommodate larger
|
||||
ones.
|
569
usr.sbin/installboot/installboot.c
Normal file
569
usr.sbin/installboot/installboot.c
Normal file
|
@ -0,0 +1,569 @@
|
|||
/* $NetBSD: installboot.c,v 1.36 2011/11/03 20:46:41 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: installboot.c,v 1.36 2011/11/03 20:46:41 martin Exp $");
|
||||
#endif /* !__lint */
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "installboot.h"
|
||||
|
||||
static void getmachine(ib_params *, const char *, const char *);
|
||||
static void getfstype(ib_params *, const char *, const char *);
|
||||
static void parseoptions(ib_params *, const char *);
|
||||
__dead static void usage(void);
|
||||
static void options_usage(void);
|
||||
static void machine_usage(void);
|
||||
static void fstype_usage(void);
|
||||
|
||||
static ib_params installboot_params;
|
||||
|
||||
#define OFFSET(field) offsetof(ib_params, field)
|
||||
const struct option {
|
||||
const char *name; /* Name of option */
|
||||
ib_flags flag; /* Corresponding IB_xxx flag */
|
||||
enum { /* Type of option value... */
|
||||
OPT_BOOL, /* no value */
|
||||
OPT_INT, /* numeric value */
|
||||
OPT_WORD, /* space/tab/, terminated */
|
||||
OPT_STRING /* null terminated */
|
||||
} type;
|
||||
int offset; /* of field in ib_params */
|
||||
} options[] = {
|
||||
{ "alphasum", IB_ALPHASUM, OPT_BOOL, 0 },
|
||||
{ "append", IB_APPEND, OPT_BOOL, 0 },
|
||||
{ "command", IB_COMMAND, OPT_STRING, OFFSET(command) },
|
||||
{ "console", IB_CONSOLE, OPT_WORD, OFFSET(console) },
|
||||
{ "ioaddr", IB_CONSADDR, OPT_INT, OFFSET(consaddr) },
|
||||
{ "keymap", IB_KEYMAP, OPT_WORD, OFFSET(keymap) },
|
||||
{ "password", IB_PASSWORD, OPT_WORD, OFFSET(password) },
|
||||
{ "resetvideo", IB_RESETVIDEO, OPT_BOOL, 0 },
|
||||
{ "speed", IB_CONSPEED, OPT_INT, OFFSET(conspeed) },
|
||||
{ "sunsum", IB_SUNSUM, OPT_BOOL, 0 },
|
||||
{ "timeout", IB_TIMEOUT, OPT_INT, OFFSET(timeout) },
|
||||
{ "modules", IB_MODULES, OPT_BOOL, 0 },
|
||||
{ "bootconf", IB_BOOTCONF, OPT_BOOL, 0 },
|
||||
{ .name = NULL },
|
||||
};
|
||||
#undef OFFSET
|
||||
#define OPTION(params, type, opt) (*(type *)((char *)(params) + (opt)->offset))
|
||||
|
||||
#define DFL_SECSIZE 512 /* Don't use DEV_BSIZE. It's host's value. */
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct utsname utsname;
|
||||
ib_params *params;
|
||||
unsigned long lval;
|
||||
int ch, rv, mode;
|
||||
char *p;
|
||||
const char *op;
|
||||
ib_flags unsupported_flags;
|
||||
|
||||
setprogname(argv[0]);
|
||||
params = &installboot_params;
|
||||
memset(params, 0, sizeof(*params));
|
||||
params->fsfd = -1;
|
||||
params->s1fd = -1;
|
||||
if ((p = getenv("MACHINE")) != NULL)
|
||||
getmachine(params, p, "$MACHINE");
|
||||
|
||||
while ((ch = getopt(argc, argv, "b:B:cefm:no:t:v")) != -1) {
|
||||
switch (ch) {
|
||||
|
||||
case 'b':
|
||||
case 'B':
|
||||
if (*optarg == '\0')
|
||||
goto badblock;
|
||||
lval = strtoul(optarg, &p, 0);
|
||||
if (lval > UINT32_MAX || *p != '\0') {
|
||||
badblock:
|
||||
errx(1, "Invalid block number `%s'", optarg);
|
||||
}
|
||||
if (ch == 'b') {
|
||||
params->s1start = (uint32_t)lval;
|
||||
params->flags |= IB_STAGE1START;
|
||||
} else {
|
||||
params->s2start = (uint32_t)lval;
|
||||
params->flags |= IB_STAGE2START;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
params->flags |= IB_CLEAR;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
params->flags |= IB_EDIT;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
params->flags |= IB_FORCE;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
getmachine(params, optarg, "-m");
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
params->flags |= IB_NOWRITE;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
parseoptions(params, optarg);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
getfstype(params, optarg, "-t");
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
params->flags |= IB_VERBOSE;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (params->flags & IB_CLEAR && params->flags & IB_EDIT)
|
||||
usage();
|
||||
if (argc < 1 || argc + 2 * !!(params->flags & (IB_CLEAR | IB_EDIT)) > 3)
|
||||
usage();
|
||||
|
||||
/* set missing defaults */
|
||||
if (params->machine == NULL) {
|
||||
if (uname(&utsname) == -1)
|
||||
err(1, "Determine uname");
|
||||
getmachine(params, utsname.machine, "uname()");
|
||||
}
|
||||
|
||||
/* Check that options are supported by this system */
|
||||
unsupported_flags = params->flags & ~params->machine->valid_flags;
|
||||
unsupported_flags &= ~(IB_VERBOSE | IB_NOWRITE | IB_CLEAR | IB_EDIT
|
||||
| IB_FORCE);
|
||||
if (unsupported_flags != 0) {
|
||||
int ndx;
|
||||
for (ndx = 0; options[ndx].name != NULL; ndx++) {
|
||||
if (unsupported_flags & options[ndx].flag) {
|
||||
unsupported_flags &= ~options[ndx].flag;
|
||||
warnx("`-o %s' is not supported for %s",
|
||||
options[ndx].name, params->machine->name);
|
||||
}
|
||||
}
|
||||
if (unsupported_flags & IB_STAGE1START)
|
||||
warnx("`-b bno' is not supported for %s",
|
||||
params->machine->name);
|
||||
if (unsupported_flags & IB_STAGE2START)
|
||||
warnx("`-B bno' is not supported for %s",
|
||||
params->machine->name);
|
||||
unsupported_flags &= ~(IB_STAGE1START | IB_STAGE2START);
|
||||
if (unsupported_flags != 0)
|
||||
warnx("Unknown unsupported flag %#x (coding error!)",
|
||||
unsupported_flags);
|
||||
exit(1);
|
||||
}
|
||||
/* and some illegal combinations */
|
||||
if (params->flags & IB_STAGE1START && params->flags & IB_APPEND) {
|
||||
warnx("Can't use `-b bno' with `-o append'");
|
||||
exit(1);
|
||||
}
|
||||
if (params->flags & IB_CLEAR &&
|
||||
params->flags & (IB_STAGE1START | IB_STAGE2START | IB_APPEND)) {
|
||||
warnx("Can't use `-b bno', `-B bno' or `-o append' with `-c'");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc >= 3) {
|
||||
params->stage2 = argv[2];
|
||||
}
|
||||
|
||||
params->filesystem = argv[0];
|
||||
if (params->flags & IB_NOWRITE) {
|
||||
op = "only";
|
||||
mode = O_RDONLY;
|
||||
} else {
|
||||
op = "write";
|
||||
mode = O_RDWR;
|
||||
}
|
||||
/* XXX should be specified via option */
|
||||
params->sectorsize = DFL_SECSIZE;
|
||||
if ((params->fsfd = open(params->filesystem, mode, 0600)) == -1)
|
||||
err(1, "Opening file system `%s' read-%s",
|
||||
params->filesystem, op);
|
||||
if (fstat(params->fsfd, ¶ms->fsstat) == -1)
|
||||
err(1, "Examining file system `%s'", params->filesystem);
|
||||
if (params->fstype != NULL) {
|
||||
if (! params->fstype->match(params))
|
||||
errx(1, "File system `%s' is not of type %s",
|
||||
params->filesystem, params->fstype->name);
|
||||
} else {
|
||||
if (params->stage2 != NULL) {
|
||||
params->fstype = &fstypes[0];
|
||||
while (params->fstype->name != NULL &&
|
||||
!params->fstype->match(params))
|
||||
params->fstype++;
|
||||
if (params->fstype->name == NULL)
|
||||
errx(1, "File system `%s' is of an unknown type",
|
||||
params->filesystem);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc >= 2) {
|
||||
if ((params->s1fd = open(argv[1], O_RDONLY, 0600)) == -1)
|
||||
err(1, "Opening primary bootstrap `%s'", argv[1]);
|
||||
if (fstat(params->s1fd, ¶ms->s1stat) == -1)
|
||||
err(1, "Examining primary bootstrap `%s'", argv[1]);
|
||||
if (!S_ISREG(params->s1stat.st_mode))
|
||||
errx(1, "`%s' must be a regular file", argv[1]);
|
||||
params->stage1 = argv[1];
|
||||
}
|
||||
assert(params->machine != NULL);
|
||||
|
||||
if (params->flags & IB_VERBOSE) {
|
||||
printf("File system: %s\n", params->filesystem);
|
||||
if (params->fstype)
|
||||
printf("File system type: %s (blocksize %u, "
|
||||
"needswap %d)\n",
|
||||
params->fstype->name, params->fstype->blocksize,
|
||||
params->fstype->needswap);
|
||||
if (!(params->flags & IB_EDIT))
|
||||
printf("Primary bootstrap: %s\n",
|
||||
(params->flags & IB_CLEAR) ? "(to be cleared)"
|
||||
: params->stage1 ? params->stage1 : "(none)" );
|
||||
if (params->stage2 != NULL)
|
||||
printf("Secondary bootstrap: %s\n", params->stage2);
|
||||
}
|
||||
|
||||
if (params->flags & IB_EDIT) {
|
||||
op = "Edit";
|
||||
rv = params->machine->editboot(params);
|
||||
} else if (params->flags & IB_CLEAR) {
|
||||
op = "Clear";
|
||||
rv = params->machine->clearboot(params);
|
||||
} else {
|
||||
if (argc < 2)
|
||||
errx(EXIT_FAILURE, "Please specify the primary "
|
||||
"bootstrap file");
|
||||
op = "Set";
|
||||
rv = params->machine->setboot(params);
|
||||
}
|
||||
if (rv == 0)
|
||||
errx(1, "%s bootstrap operation failed", op);
|
||||
|
||||
if (S_ISREG(params->fsstat.st_mode)) {
|
||||
if (fsync(params->fsfd) == -1)
|
||||
err(1, "Synchronising file system `%s'",
|
||||
params->filesystem);
|
||||
} else {
|
||||
/* Sync filesystems (to clean in-memory superblock?) */
|
||||
sync();
|
||||
}
|
||||
if (close(params->fsfd) == -1)
|
||||
err(1, "Closing file system `%s'", params->filesystem);
|
||||
if (argc == 2)
|
||||
if (close(params->s1fd) == -1)
|
||||
err(1, "Closing primary bootstrap `%s'",
|
||||
params->stage1);
|
||||
|
||||
exit(0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
parseoptions(ib_params *params, const char *option)
|
||||
{
|
||||
char *cp;
|
||||
const struct option *opt;
|
||||
int len;
|
||||
unsigned long val;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(option != NULL);
|
||||
|
||||
for (;; option += len) {
|
||||
option += strspn(option, ", \t");
|
||||
if (*option == 0)
|
||||
return;
|
||||
len = strcspn(option, "=,");
|
||||
for (opt = options; opt->name != NULL; opt++) {
|
||||
if (memcmp(option, opt->name, len) == 0
|
||||
&& opt->name[len] == 0)
|
||||
break;
|
||||
}
|
||||
if (opt->name == NULL) {
|
||||
len = strcspn(option, ",");
|
||||
warnx("Unknown option `-o %.*s'", len, option);
|
||||
break;
|
||||
}
|
||||
params->flags |= opt->flag;
|
||||
if (opt->type == OPT_BOOL) {
|
||||
if (option[len] != '=')
|
||||
continue;
|
||||
warnx("Option `%s' must not have a value", opt->name);
|
||||
break;
|
||||
}
|
||||
if (option[len] != '=') {
|
||||
warnx("Option `%s' must have a value", opt->name);
|
||||
break;
|
||||
}
|
||||
option += len + 1;
|
||||
len = strcspn(option, ",");
|
||||
switch (opt->type) {
|
||||
case OPT_STRING:
|
||||
len = strlen(option);
|
||||
/* FALLTHROUGH */
|
||||
case OPT_WORD:
|
||||
cp = strdup(option);
|
||||
if (cp == NULL)
|
||||
err(1, "strdup");
|
||||
cp[len] = 0;
|
||||
OPTION(params, char *, opt) = cp;
|
||||
continue;
|
||||
case OPT_INT:
|
||||
val = strtoul(option, &cp, 0);
|
||||
if (cp > option + len || (*cp != 0 && *cp != ','))
|
||||
break;
|
||||
if (val > INT_MAX)
|
||||
break;
|
||||
OPTION(params, int, opt) = (int)val;
|
||||
continue;
|
||||
default:
|
||||
errx(1, "Internal error: option `%s' has invalid type %d",
|
||||
opt->name, opt->type);
|
||||
}
|
||||
warnx("Invalid option value `%s=%.*s'", opt->name, len, option);
|
||||
break;
|
||||
}
|
||||
options_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
options_usage(void)
|
||||
{
|
||||
int ndx;
|
||||
const char *pfx;
|
||||
|
||||
warnx("Valid options are:");
|
||||
pfx = "\t";
|
||||
for (ndx = 0; options[ndx].name != 0; ndx++) {
|
||||
fprintf(stderr, "%s%s", pfx, options[ndx].name);
|
||||
switch (options[ndx].type) {
|
||||
case OPT_INT:
|
||||
fprintf(stderr, "=number");
|
||||
break;
|
||||
case OPT_WORD:
|
||||
fprintf(stderr, "=word");
|
||||
break;
|
||||
case OPT_STRING:
|
||||
fprintf(stderr, "=string");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((ndx % 5) == 4)
|
||||
pfx = ",\n\t";
|
||||
else
|
||||
pfx = ", ";
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
no_setboot(ib_params *params)
|
||||
{
|
||||
|
||||
assert(params != NULL);
|
||||
|
||||
warnx("%s: bootstrap installation is not supported",
|
||||
params->machine->name);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
no_clearboot(ib_params *params)
|
||||
{
|
||||
|
||||
assert(params != NULL);
|
||||
|
||||
warnx("%s: bootstrap removal is not supported",
|
||||
params->machine->name);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
no_editboot(ib_params *params)
|
||||
{
|
||||
|
||||
assert(params != NULL);
|
||||
|
||||
warnx("%s: bootstrap editing is not supported",
|
||||
params->machine->name);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
getmachine(ib_params *param, const char *mach, const char *provider)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(param != NULL);
|
||||
assert(mach != NULL);
|
||||
assert(provider != NULL);
|
||||
|
||||
for (i = 0; machines[i] != NULL; i++) {
|
||||
if (machines[i]->name == NULL)
|
||||
continue;
|
||||
if (strcmp(machines[i]->name, mach) == 0) {
|
||||
param->machine = machines[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
warnx("Invalid machine `%s' from %s", mach, provider);
|
||||
machine_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
machine_usage(void)
|
||||
{
|
||||
const char *prefix;
|
||||
int i;
|
||||
int col, len;
|
||||
const char *name;
|
||||
int wincol=80;
|
||||
#ifdef TIOCGWINSZ
|
||||
struct winsize win;
|
||||
|
||||
if (ioctl(fileno(stderr), TIOCGWINSZ, &win) == 0 && win.ws_col > 0)
|
||||
wincol = win.ws_col;
|
||||
#endif
|
||||
|
||||
warnx("Supported machines are:");
|
||||
prefix="\t";
|
||||
col = 8 + 3;
|
||||
for (i = 0; machines[i] != NULL; i++) {
|
||||
name = machines[i]->name;
|
||||
if (name == NULL)
|
||||
continue;
|
||||
len = strlen(name);
|
||||
if (col + len > wincol) {
|
||||
prefix=",\n\t";
|
||||
col = -2 + 8 + 3;
|
||||
}
|
||||
col += fprintf(stderr, "%s%s", prefix, name);
|
||||
prefix=", ";
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
|
||||
static void
|
||||
getfstype(ib_params *param, const char *fstype, const char *provider)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(param != NULL);
|
||||
assert(fstype != NULL);
|
||||
assert(provider != NULL);
|
||||
|
||||
for (i = 0; fstypes[i].name != NULL; i++) {
|
||||
if (strcmp(fstypes[i].name, fstype) == 0) {
|
||||
param->fstype = &fstypes[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
warnx("Invalid file system type `%s' from %s", fstype, provider);
|
||||
fstype_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
fstype_usage(void)
|
||||
{
|
||||
#ifndef NO_STAGE2
|
||||
const char *prefix;
|
||||
int i;
|
||||
|
||||
warnx("Supported file system types are:");
|
||||
#define FSTYPES_PER_LINE 9
|
||||
prefix="\t";
|
||||
for (i = 0; fstypes[i].name != NULL; i++) {
|
||||
if (i && (i % FSTYPES_PER_LINE) == 0)
|
||||
prefix=",\n\t";
|
||||
fprintf(stderr, "%s%s", prefix, fstypes[i].name);
|
||||
prefix=", ";
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
const char *prog;
|
||||
|
||||
prog = getprogname();
|
||||
fprintf(stderr,
|
||||
"usage: %s [-fnv] [-B s2bno] [-b s1bno] [-m machine] [-o options]\n"
|
||||
"\t\t [-t fstype] filesystem primary [secondary]\n"
|
||||
"usage: %s -c [-fnv] [-m machine] [-o options] [-t fstype] filesystem\n"
|
||||
"usage: %s -e [-fnv] [-m machine] [-o options] bootstrap\n",
|
||||
prog, prog, prog);
|
||||
machine_usage();
|
||||
fstype_usage();
|
||||
options_usage();
|
||||
exit(1);
|
||||
}
|
185
usr.sbin/installboot/installboot.h
Normal file
185
usr.sbin/installboot/installboot.h
Normal file
|
@ -0,0 +1,185 @@
|
|||
/* $NetBSD: installboot.h,v 1.38 2011/06/14 05:35:08 matt 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.
|
||||
*/
|
||||
|
||||
#ifndef _INSTALLBOOT_H
|
||||
#define _INSTALLBOOT_H
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#include "../../sys/sys/bootblock.h"
|
||||
#else
|
||||
#include <sys/bootblock.h>
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
/* flags from global options */
|
||||
IB_VERBOSE = 1<<0, /* verbose operation */
|
||||
IB_NOWRITE = 1<<1, /* don't write */
|
||||
IB_CLEAR = 1<<2, /* clear boot block */
|
||||
IB_EDIT = 1<<3, /* edit boot parameters */
|
||||
IB_FORCE = 1<<4, /* Ignore some consistency checks */
|
||||
|
||||
/* flags from -o options */
|
||||
IB_ALPHASUM = 1<<8, /* set Alpha checksum */
|
||||
IB_APPEND = 1<<9, /* append stage 1 to EO(regular)F */
|
||||
IB_SUNSUM = 1<<10, /* set Sun checksum */
|
||||
IB_STAGE1START= 1<<11, /* start block for stage 1 provided */
|
||||
IB_STAGE2START= 1<<12, /* start block for stage 2 provided */
|
||||
IB_COMMAND = 1<<13, /* Amiga commandline option */
|
||||
IB_RESETVIDEO = 1<<14, /* i386 reset video */
|
||||
IB_CONSOLE = 1<<15, /* i386 console */
|
||||
IB_CONSPEED = 1<<16, /* i386 console baud rate */
|
||||
IB_TIMEOUT = 1<<17, /* i386 boot timeout */
|
||||
IB_PASSWORD = 1<<18, /* i386 boot password */
|
||||
IB_KEYMAP = 1<<19, /* i386 console keymap */
|
||||
IB_CONSADDR = 1<<20, /* i386 console io address */
|
||||
IB_MODULES = 1<<21, /* i386: load modules */
|
||||
IB_BOOTCONF = 1<<22, /* i386: read boot.conf */
|
||||
} ib_flags;
|
||||
|
||||
typedef struct {
|
||||
ib_flags flags; /* flags (see above) */
|
||||
struct ib_mach *machine; /* machine details (see below) */
|
||||
struct ib_fs *fstype; /* file system details (see below) */
|
||||
const char *filesystem; /* name of target file system */
|
||||
int fsfd; /* open fd to filesystem */
|
||||
struct stat fsstat; /* fstat(2) of fsfd */
|
||||
const char *stage1; /* name of stage1 bootstrap */
|
||||
int s1fd; /* open fd to stage1 */
|
||||
struct stat s1stat; /* fstat(2) of s1fd */
|
||||
uint64_t s1start; /* start block of stage1 */
|
||||
const char *stage2; /* name of stage2 bootstrap */
|
||||
uint64_t s2start; /* start block of stage2 */
|
||||
uint32_t sectorsize; /* sector size of target fs */
|
||||
/* parsed -o option=value data */
|
||||
const char *command; /* name of command string */
|
||||
const char *console; /* name of console */
|
||||
int conspeed; /* console baud rate */
|
||||
int consaddr; /* console io address */
|
||||
const char *password; /* boot password */
|
||||
int timeout; /* interactive boot timeout */
|
||||
const char *keymap; /* keyboard translations */
|
||||
} ib_params;
|
||||
|
||||
typedef struct {
|
||||
uint64_t block;
|
||||
uint32_t blocksize;
|
||||
} ib_block;
|
||||
|
||||
struct ib_mach {
|
||||
const char *name;
|
||||
int (*setboot) (ib_params *);
|
||||
int (*clearboot) (ib_params *);
|
||||
int (*editboot) (ib_params *);
|
||||
ib_flags valid_flags;
|
||||
};
|
||||
|
||||
struct ib_fs {
|
||||
/* compile time parameters */
|
||||
const char *name;
|
||||
int (*match) (ib_params *);
|
||||
int (*findstage2) (ib_params *, uint32_t *, ib_block *);
|
||||
/* run time fs specific parameters */
|
||||
uint32_t blocksize;
|
||||
uint32_t needswap;
|
||||
off_t sblockloc; /* location of superblock */
|
||||
off_t offset; /* file system offset (e.g. RAID) */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
BBINFO_BIG_ENDIAN = 0,
|
||||
BBINFO_LITTLE_ENDIAN = 1,
|
||||
} bbinfo_endian;
|
||||
|
||||
struct bbinfo_params {
|
||||
const char *magic; /* magic string to look for */
|
||||
uint32_t offset; /* offset to write start of stage1 */
|
||||
uint32_t blocksize; /* blocksize of stage1 */
|
||||
uint32_t maxsize; /* max size of stage1 */
|
||||
uint32_t headeroffset; /*
|
||||
* header offset (relative to offset)
|
||||
* to read stage1 into
|
||||
*/
|
||||
bbinfo_endian endian;
|
||||
};
|
||||
|
||||
extern struct ib_mach * const machines[];
|
||||
extern struct ib_fs fstypes[];
|
||||
|
||||
/* installboot.c */
|
||||
uint16_t compute_sunsum(const uint16_t *);
|
||||
int set_sunsum(ib_params *, uint16_t *, uint16_t);
|
||||
int no_setboot(ib_params *);
|
||||
int no_clearboot(ib_params *);
|
||||
int no_editboot(ib_params *);
|
||||
|
||||
/* bbinfo.c */
|
||||
int shared_bbinfo_clearboot(ib_params *, struct bbinfo_params *,
|
||||
int (*)(ib_params *, struct bbinfo_params *, uint8_t *));
|
||||
int shared_bbinfo_setboot(ib_params *, struct bbinfo_params *,
|
||||
int (*)(ib_params *, struct bbinfo_params *, uint8_t *));
|
||||
|
||||
/* fstypes.c */
|
||||
int hardcode_stage2(ib_params *, uint32_t *, ib_block *);
|
||||
int ffs_match(ib_params *);
|
||||
int ffs_findstage2(ib_params *, uint32_t *, ib_block *);
|
||||
int raid_match(ib_params *);
|
||||
int raw_match(ib_params *);
|
||||
int raw_findstage2(ib_params *, uint32_t *, ib_block *);
|
||||
int ext2fs_match(ib_params *);
|
||||
int ext2fs_findstage2(ib_params *, uint32_t *, ib_block *);
|
||||
|
||||
/* machines.c */
|
||||
extern struct ib_mach ib_mach_alpha;
|
||||
extern struct ib_mach ib_mach_amd64;
|
||||
extern struct ib_mach ib_mach_amiga;
|
||||
extern struct ib_mach ib_mach_ews4800mips;
|
||||
extern struct ib_mach ib_mach_hp300;
|
||||
extern struct ib_mach ib_mach_hp700;
|
||||
extern struct ib_mach ib_mach_i386;
|
||||
extern struct ib_mach ib_mach_landisk;
|
||||
extern struct ib_mach ib_mach_macppc;
|
||||
extern struct ib_mach ib_mach_news68k;
|
||||
extern struct ib_mach ib_mach_newsmips;
|
||||
extern struct ib_mach ib_mach_next68k;
|
||||
extern struct ib_mach ib_mach_pmax;
|
||||
extern struct ib_mach ib_mach_sparc;
|
||||
extern struct ib_mach ib_mach_sparc64;
|
||||
extern struct ib_mach ib_mach_sun2;
|
||||
extern struct ib_mach ib_mach_sun3;
|
||||
extern struct ib_mach ib_mach_vax;
|
||||
extern struct ib_mach ib_mach_x68k;
|
||||
|
||||
#endif /* _INSTALLBOOT_H */
|
97
usr.sbin/installboot/machines.c
Normal file
97
usr.sbin/installboot/machines.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* $NetBSD: machines.c,v 1.38 2011/06/14 05:35:08 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2005 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: machines.c,v 1.38 2011/06/14 05:35:08 matt Exp $");
|
||||
#endif /* !__lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "installboot.h"
|
||||
|
||||
/*
|
||||
* Define these here so they end up as zero-filled bss if installboot
|
||||
* isn't built with all the architectures defined.
|
||||
* A lot simpler that conditionally including the definitions themselves.
|
||||
*/
|
||||
struct ib_mach
|
||||
ib_mach_alpha,
|
||||
ib_mach_amd64,
|
||||
ib_mach_amiga,
|
||||
ib_mach_emips,
|
||||
ib_mach_ews4800mips,
|
||||
ib_mach_hp300,
|
||||
ib_mach_hp700,
|
||||
ib_mach_i386,
|
||||
ib_mach_landisk,
|
||||
ib_mach_macppc,
|
||||
ib_mach_news68k,
|
||||
ib_mach_newsmips,
|
||||
ib_mach_next68k,
|
||||
ib_mach_pmax,
|
||||
ib_mach_sparc,
|
||||
ib_mach_sparc64,
|
||||
ib_mach_sun2,
|
||||
ib_mach_sun3,
|
||||
ib_mach_vax,
|
||||
ib_mach_x68k;
|
||||
|
||||
struct ib_mach * const machines[] = {
|
||||
&ib_mach_alpha,
|
||||
&ib_mach_amd64,
|
||||
&ib_mach_amiga,
|
||||
&ib_mach_emips,
|
||||
&ib_mach_ews4800mips,
|
||||
&ib_mach_hp300,
|
||||
&ib_mach_hp700,
|
||||
&ib_mach_i386,
|
||||
&ib_mach_landisk,
|
||||
&ib_mach_macppc,
|
||||
&ib_mach_news68k,
|
||||
&ib_mach_newsmips,
|
||||
&ib_mach_next68k,
|
||||
&ib_mach_pmax,
|
||||
&ib_mach_sparc,
|
||||
&ib_mach_sparc64,
|
||||
&ib_mach_sun2,
|
||||
&ib_mach_sun3,
|
||||
&ib_mach_vax,
|
||||
&ib_mach_x68k,
|
||||
NULL
|
||||
};
|
||||
|
||||
#if 0
|
||||
{ "shark", no_setboot, no_clearboot, no_editboot, 0 },
|
||||
#endif
|
108
usr.sbin/installboot/sum.c
Normal file
108
usr.sbin/installboot/sum.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/* $NetBSD: sum.c,v 1.5 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) 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.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if !defined(__lint)
|
||||
__RCSID("$NetBSD: sum.c,v 1.5 2010/01/14 16:27:49 tsutsui Exp $");
|
||||
#endif /* !__lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "installboot.h"
|
||||
|
||||
|
||||
uint16_t
|
||||
compute_sunsum(const uint16_t *bb16)
|
||||
{
|
||||
uint16_t i, s;
|
||||
|
||||
assert(bb16 != NULL);
|
||||
|
||||
s = 0;
|
||||
for (i = 0; i < 255; ++i)
|
||||
s ^= bb16[i];
|
||||
return (s);
|
||||
}
|
||||
|
||||
int
|
||||
set_sunsum(ib_params *params, uint16_t *bb16, uint16_t sum)
|
||||
{
|
||||
|
||||
assert(params != NULL);
|
||||
assert(bb16 != NULL);
|
||||
|
||||
#define SUNSUM_OFFSET 255
|
||||
if (params->flags & IB_VERBOSE) {
|
||||
printf("Old Sun checksum: 0x%04x\n",
|
||||
be16toh(bb16[SUNSUM_OFFSET]));
|
||||
printf("Recalculated Sun checksum: 0x%04x\n", be16toh(sum));
|
||||
}
|
||||
// XXX: does this need to be big endian?
|
||||
bb16[SUNSUM_OFFSET] = sum;
|
||||
return (1);
|
||||
}
|
Loading…
Reference in a new issue