diff --git a/usr.sbin/installboot/Makefile b/usr.sbin/installboot/Makefile new file mode 100644 index 000000000000..126a3c460a9a --- /dev/null +++ b/usr.sbin/installboot/Makefile @@ -0,0 +1,28 @@ +# $NetBSD: Makefile,v 1.1 2002/04/03 05:21:16 lukem Exp $ +# + +PROG= installboot +SRCS= installboot.c sum.c machines.c +MAN= installboot.8 + +WARNS?= 3 + +# list of MACHINEs to build this version of installboot for. +# +IB_MACHINES?= vax + +SRCS+= ${IB_MACHINES:S/$/.c/} + + +# XXX: maybe build as necessary and commit, rather than build each time? +# +CPPFLAGS+= -I${.CURDIR} +CLEANFILES+= machines.c + +machines.c: mkmachines.awk Makefile + awk -f ${.CURDIR}/mkmachines.awk ${IB_MACHINES} > ${.TARGET} + + +.ifndef HOSTPROG +.include +.endif diff --git a/usr.sbin/installboot/installboot.8 b/usr.sbin/installboot/installboot.8 new file mode 100644 index 000000000000..c7f052b27052 --- /dev/null +++ b/usr.sbin/installboot/installboot.8 @@ -0,0 +1,206 @@ +.\" $NetBSD: installboot.8,v 1.1 2002/04/03 05:21:17 lukem 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. +.\" 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. +.\" +.Dd April 3, 2002 +.Dt INSTALLBOOT 8 +.Os +.Sh NAME +.Nm installboot +.Nd install disk bootstrap software +. +.Sh SYNOPSIS +.Nm "" +.Fl nv +.Bk -words +.Op Fl b Ar bno +.Ek +.ig +.Bk -words +.Oo +.Fl B +.Sm off +.Ar bno Op , Ar ... +.Sm on +.Oc +.Ek +.. +.Bk -words +.Op Fl m Ar machine +.Ek +.Bk -words +.Op Fl o Ar options +.Ek +.Bk -words +.Op Fl t Ar fstype +.Ek +.Ar filesystem +.Ar bootstrap +.Nm "" +.Fl c +.Fl nv +.Bk -words +.Op Fl m Ar machine +.Ek +.Bk -words +.Op Fl o Ar options +.Ek +.Bk -words +.Op Fl t Ar fstype +.Ek +.Ar filesystem +. +.Sh DESCRIPTION +The +.Nm +utility installs and removes disk bootstrap software. +.Nm +can install +.Ar bootstrap +into +.Ar filesystem , +or disable an existing bootstrap in +.Ar filesystem . +.Pp +(XXX: flesh out description of primary & secondary bootstrap, ...) +.Pp +The options recognized by +.Nm +are as follows: +. +.Bl -tag -width "foobar" +. +.It Fl b Ar bno +Install +.Ar bootstrap +at block number +.Ar bno +instead of the default location for the machine and file system type. +. +.It Fl c +Clear (remove) any existing bootstrap instead of installing one. +. +.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 . +.Pp +The following machines are currently supported by +.Nm "" : +.Bd -ragged -offset indent +.Sy vax +.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 append +. +.It Sy append +.Em [ pmax , +.Em vax ] +Append +.Ar bootstrap +to the end of +.Ar filesystem , +which much be a regular file in this case. +. +.It Sy sunsum +.Em [ pmax , +.Em vax ] +Recalculate and restore the Sun and +.Nx Ns Tn /sparc +compatible checksum. +.Em Note : No The existing +.Nx Ns Tn /sparc +disklabel should use no more than 4 partitions. +.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. +. +.It Fl v +Verbose operation. +.El +. +.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 +XXX +. +.Sh SEE ALSO +.Xr uname 3 , +.Xr boot 8 , +.Xr disklabel 8 , +.Xr init 8 +. +.Sh HISTORY +The +.Nm +utility first appeared the depths of time (XXX). +This version appeared in +.Nx 1.6 . +. +.Sh BUGS +XXX diff --git a/usr.sbin/installboot/installboot.c b/usr.sbin/installboot/installboot.c new file mode 100644 index 000000000000..6b01480b1c95 --- /dev/null +++ b/usr.sbin/installboot/installboot.c @@ -0,0 +1,266 @@ +/* $NetBSD: installboot.c,v 1.1 2002/04/03 05:21:17 lukem 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. + * 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. + */ + +#include +#if defined(__RCSID) && !defined(__lint) +__RCSID("$NetBSD: installboot.c,v 1.1 2002/04/03 05:21:17 lukem Exp $"); +#endif /* !__lint */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "installboot.h" + +int main(int, char *[]); +static int getmachine(ib_params *, const char *, const char *); +static void usage(void); + +static ib_params installboot_params; + +int +main(int argc, char *argv[]) +{ + struct utsname utsname; + ib_params *params; + long lval; + int ch, rv, mode; + char *p; + const char *op; + + setprogname(argv[0]); + params = &installboot_params; + memset(params, 0, sizeof(*params)); + if ((p = getenv("MACHINE")) != NULL) + if (! getmachine(params, p, "$MACHINE")) + exit(1); + + while ((ch = getopt(argc, argv, "b:cm:no:t:v")) != -1) { + switch (ch) { + + case 'b': + if (*optarg == '\0') + goto badblock; + lval = strtol(optarg, &p, 0); + if (lval < 0 || lval >= LONG_MAX || *p != '\0') { + badblock: + errx(1, "Invalid block number `%s'", optarg); + } + params->startblock = lval; + params->flags |= IB_STARTBLOCK; + break; + + case 'c': + params->flags |= IB_CLEAR; + break; + + case 'm': + if (! getmachine(params, optarg, "-m")) + exit(1); + break; + + case 'n': + params->flags |= IB_NOWRITE; + break; + + case 'o': + if (params->machine == NULL) + errx(1, + "Machine needs to be specified before -o"); + while ((p = strsep(&optarg, ",")) != NULL) { + if (*p == '\0') + errx(1, "Empty `-o' option"); + if (! params->machine->parseopt(params, p)) + exit(1); + } + break; + + case 't': + params->fstype = optarg; // XXX: validate? + break; + + case 'v': + params->flags |= IB_VERBOSE; + break; + + case '?': + default: + usage(); + /* NOTREACHED */ + + } + } + argc -= optind; + argv += optind; + + if (((params->flags & IB_CLEAR) != 0 && argc != 1) || + ((params->flags & IB_CLEAR) == 0 && argc != 2)) + usage(); + + /* set missing defaults */ + if (params->machine == NULL) { + if (uname(&utsname) == -1) + err(1, "Determine uname"); + if (! getmachine(params, utsname.machine, "uname()")) + exit(1); + } + // XXX: set default params->fstype + + params->filesystem = argv[0]; + if (params->flags & IB_NOWRITE) { + op = "only"; + mode = O_RDONLY; + } else { + op = "write"; + mode = O_RDWR; + } + if ((params->fsfd = open(params->filesystem, mode, 0600)) == -1) + err(1, "Opening file system `%s' read-%s", + params->filesystem, op); + + if (argc == 2) { + params->bootblock = argv[1]; + if ((params->bbfd = open(params->bootblock, O_RDONLY, 0600)) + == -1) + err(1, "Opening boot block `%s'", params->bootblock); + } + assert(params->machine != NULL); + + if (params->flags & IB_VERBOSE) { + printf("File system: %s\n", params->filesystem); + printf("Boot block: %s\n", + (params->flags & IB_CLEAR) ? "(to be cleared)" + : params->bootblock); + } + + if (params->flags & IB_CLEAR) { + op = "Clear"; + rv = params->machine->clearboot(params); + } else { + op = "Set"; + rv = params->machine->setboot(params); + } + if (rv == 0) + errx(1, "%s boot block operation failed", op); + + if (close(params->fsfd) == -1) + err(1, "Closing file system `%s'", params->filesystem); + if (argc == 2) + if (close(params->bbfd) == -1) + err(1, "Closing boot block `%s'", params->bootblock); + + exit(0); + /* NOTREACHED */ +} + +int +parseoptionflag(ib_params *params, const char *option, ib_flags wantflags) +{ + struct { + const char *name; + ib_flags flag; + } flags[] = { + { "alphasum", IB_ALPHASUM }, + { "append", IB_APPEND }, + { "sunsum", IB_SUNSUM }, + { NULL, 0 }, + }; + + int i; + + assert(params != NULL); + assert(option != NULL); + + for (i = 0; flags[i].name != NULL; i++) { + if ((strcmp(flags[i].name, option) == 0) && + (wantflags & flags[i].flag)) { + params->flags |= flags[i].flag; + return (1); + } + } + return (0); +} + + +static int +getmachine(ib_params *param, const char *mach, const char *provider) +{ + int i; + + assert(param != NULL); + assert(mach != NULL); + + for (i = 0; machines[i].name != NULL; i++) { + if (strcmp(machines[i].name, mach) == 0) { + param->machine = &machines[i]; + return (1); + } + } + warnx("Invalid machine `%s' from %s", mach, provider); + warnx("Supported machines are:"); +#define MACHS_PER_LINE 10 + for (i = 0; machines[i].name != NULL; i++) { + fputs((i % MACHS_PER_LINE) ? ", " : "\t", stderr); + fputs(machines[i].name, stderr); + if ((i % MACHS_PER_LINE) == (MACHS_PER_LINE - 1)) + fputs("\n", stderr); + } + if ((i % MACHS_PER_LINE) != 0) + fputs("\n", stderr); + return (0); +} + +static void +usage(void) +{ + const char *prog; + + prog = getprogname(); + fprintf(stderr, +"Usage: %s [-nv] [-m machine] [-o options] [-t fstype]\n" +"\t\t [-b block] filesystem bootstrap\n" +"Usage: %s -c [-nv] [-m machine] [-o options] [-t fstype] filesystem\n", + prog, prog); + exit(1); +} diff --git a/usr.sbin/installboot/installboot.h b/usr.sbin/installboot/installboot.h new file mode 100644 index 000000000000..6a1bc851512d --- /dev/null +++ b/usr.sbin/installboot/installboot.h @@ -0,0 +1,80 @@ +/* $NetBSD: installboot.h,v 1.1 2002/04/03 05:21:17 lukem 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _INSTALLBOOT_H +#define _INSTALLBOOT_H + +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_STARTBLOCK = 1<<3, /* start block supplied */ + + /* flags from -o options */ + IB_ALPHASUM = 1<<8, /* set Alpha checksum */ + IB_APPEND = 1<<9, /* clear boot block */ + IB_SUNSUM = 1<<10, /* set Sun checksum */ +} ib_flags; + +typedef struct { + ib_flags flags; + struct ib_mach *machine; + const char *fstype; // XXX replace with struct *? + const char *filesystem; + int fsfd; + const char *bootblock; + int bbfd; + long startblock; +} ib_params; + +struct ib_mach { + const char *name; + int (*parseopt) (ib_params *, const char *); + int (*setboot) (ib_params *); + int (*clearboot) (ib_params *); +}; + + +extern struct ib_mach machines[]; + +int parseoptionflag(ib_params *, const char *, ib_flags); +u_int16_t compute_sunsum(const u_int16_t *); +int set_sunsum(ib_params *, u_int16_t *, u_int16_t); + +#endif /* _INSTALLBOOT_H */ diff --git a/usr.sbin/installboot/mkmachines.awk b/usr.sbin/installboot/mkmachines.awk new file mode 100644 index 000000000000..d1970c166266 --- /dev/null +++ b/usr.sbin/installboot/mkmachines.awk @@ -0,0 +1,58 @@ +#!/usr/bin/awk +# +# $NetBSD: mkmachines.awk,v 1.1 2002/04/03 05:21:17 lukem 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. +# 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. +# + +BEGIN \ +{ + printf("/* \$\NetBSD\$ */\n\n"); + printf("/* DO NOT EDIT-- this file is automatically generated. */\n\n"); + printf("#include \n"); + printf("#include \"installboot.h\"\n\n"); + for (i = 1; i < ARGC; i++) { + printf("int %s_parseopt(ib_params *, const char *);\n", + ARGV[i]); + printf("int %s_setboot(ib_params *);\n", ARGV[i]); + printf("int %s_clearboot(ib_params *);\n", ARGV[i]); + } + printf("\nstruct ib_mach machines[] = {\n"); + for (i = 1; i < ARGC; i++) { + printf("\t{ \"%s\",\t%s_parseopt,\t%s_setboot,\t%s_clearboot },\n", + ARGV[i], ARGV[i], ARGV[i], ARGV[i]); + } + printf("\t{ 0, 0, 0, 0 },\n};\n"); +} diff --git a/usr.sbin/installboot/sum.c b/usr.sbin/installboot/sum.c new file mode 100644 index 000000000000..291b38486ad4 --- /dev/null +++ b/usr.sbin/installboot/sum.c @@ -0,0 +1,111 @@ +/* $NetBSD: sum.c,v 1.1 2002/04/03 05:21:17 lukem 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. + * 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. + */ + +#include +#if defined(__RCSID) && !defined(__lint) +__RCSID("$NetBSD: sum.c,v 1.1 2002/04/03 05:21:17 lukem Exp $"); +#endif /* !__lint */ + +#include + +#include +#include + +#include "installboot.h" + + +u_int16_t +compute_sunsum(const u_int16_t *bb16) +{ + u_int16_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, u_int16_t *bb16, u_int16_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); +} diff --git a/usr.sbin/installboot/vax.c b/usr.sbin/installboot/vax.c new file mode 100644 index 000000000000..4df0c55474ef --- /dev/null +++ b/usr.sbin/installboot/vax.c @@ -0,0 +1,339 @@ +/* $NetBSD: vax.c,v 1.1 2002/04/03 05:21:17 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. + * 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 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. + */ + +#include +#if defined(__RCSID) && !defined(__lint) +__RCSID("$NetBSD: vax.c,v 1.1 2002/04/03 05:21:17 lukem Exp $"); +#endif /* !__lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "installboot.h" + +int vax_parseopt(ib_params *, const char *); +int vax_setboot(ib_params *); +int vax_clearboot(ib_params *); +static int load_bootstrap(ib_params *, char **, + u_int32_t *, u_int32_t *, size_t *); + + +int +vax_parseopt(ib_params *params, const char *option) +{ + + if (parseoptionflag(params, option, IB_APPEND | IB_SUNSUM)) + return (1); + + warnx("Unknown -o option `%s'", option); + return (0); +} + +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); + + if (params->flags & (IB_STARTBLOCK | IB_APPEND)) { + warnx("Can't use `-b bno' or `-o append' with `-c'"); + return (0); + } + 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) { + u_int16_t sum; + + sum = compute_sunsum((u_int16_t *)&bb); + if (! set_sunsum(params, (u_int16_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); +} + +int +vax_setboot(ib_params *params) +{ + struct stat bootstrapsb; + struct vax_boot_block bb; + int startblock, retval; + char *bootstrapbuf; + size_t bootstrapsize; + u_int32_t bootstrapload, bootstrapexec; + ssize_t rv; + + assert(params != NULL); + assert(params->fsfd != -1); + assert(params->filesystem != NULL); + assert(params->bbfd != -1); + assert(params->bootblock != NULL); + assert(sizeof(struct vax_boot_block) == VAX_BOOT_BLOCK_BLOCKSIZE); + + retval = 0; + bootstrapbuf = NULL; + + if ((params->flags & IB_STARTBLOCK) && + (params->flags & IB_APPEND)) { + warnx("Can't use `-b bno' with `-o append'"); + goto done; + } + + if (fstat(params->bbfd, &bootstrapsb) == -1) { + warn("Examining `%s'", params->bootblock); + goto done; + } + if (!S_ISREG(bootstrapsb.st_mode)) { + warnx("`%s' must be a regular file", params->bootblock); + 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 boot block", + params->filesystem); + goto done; + } + startblock = howmany(filesyssb.st_size, + VAX_BOOT_BLOCK_BLOCKSIZE); + } else if (params->flags & IB_STARTBLOCK) { + startblock = params->startblock; + } 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((u_int16_t) (startblock >> 16)); + bb.bb_lbn_low = htole16((u_int16_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) { + u_int16_t sum; + + sum = compute_sunsum((u_int16_t *)&bb); + if (! set_sunsum(params, (u_int16_t *)&bb, sum)) + goto done; + } + + if (params->flags & IB_VERBOSE) { + printf("Bootstrap start sector: %#x\n", startblock); + printf("Bootstrap sector count: %#x\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 (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, + u_int32_t *loadaddr, u_int32_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->bbfd, *data, buflen, 0); + if (cc <= 0) { + warn("Reading `%s'", params->bootblock); + return (0); + } + if (cc > 512 * VAX_BOOT_SIZE) { + warnx("`%s': too large", params->bootblock); + return (0); + } + + *len = roundup(cc, VAX_BOOT_BLOCK_BLOCKSIZE); + *loadaddr = VAX_BOOT_LOAD; + *execaddr = VAX_BOOT_ENTRY; + return (1); +}