diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index c7caf9adaab8..fa46b987bd16 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -170,4 +170,7 @@ SUBDIR+=apm \ wlconfig .endif +.if ${MACHINE} == "pc98" +SUBDIR+=boot98cfg +.endif .include diff --git a/usr.sbin/boot98cfg/Makefile b/usr.sbin/boot98cfg/Makefile new file mode 100644 index 000000000000..8d9658028249 --- /dev/null +++ b/usr.sbin/boot98cfg/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= boot98cfg +MAN8= boot98cfg.8 + +.include diff --git a/usr.sbin/boot98cfg/boot98cfg.8 b/usr.sbin/boot98cfg/boot98cfg.8 new file mode 100644 index 000000000000..628f23aa06d4 --- /dev/null +++ b/usr.sbin/boot98cfg/boot98cfg.8 @@ -0,0 +1,98 @@ +.\" Copyright (c) KATO Takenori, 2000. +.\" +.\" All rights reserved. Unpublished rights reserved under the copyright +.\" laws of Japan. +.\" +.\" 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 as +.\" the first lines of this file unmodified. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd July 10, 2000 +.Dt BOOT98CFG 8 +.Os +.Sh NAME +.Nm boot98cfg +.Nd HDD boot manager installation utility +.Sh SYNOPSIS +.Op Fl B +.Op Fl i Ar boot0 +.Op Fl m Ar boot0.5 +.Op Fl s Ar secsize +.Op Fl v Ar version +.Op Fl f Ar boot0.bak +.Op Fl F Ar boot0.5.bak +.Ar disk +.Sh DESCRIPTION +On NEC PC-98s, +.Sq boot loader +consists of the +.Sq IPL +and +.Sq HDD boot menu. +The IPL occupies sector 0 of a disk and is followed by the partition +table. The IPL loads the HDD boot menu that starts from 0x400. + +The +.Nm +installs and makes backup copy of the IPL and the HDD boot menu; and +allows changing the version number field in the sector 0. + +Note that the format command in NEC's OSs replaces the HDD boot menu +with its own HDD boot menu when the version number field is smaller +than that in the format command. + +The options are: +.Bl -tag -width indent +.It Fl B +Install the IPL and HDD boot menu. This option causes the IPL and HDD +boot menu code to be replaced. +.It Fl i Ar boot0 +Specify which IPL image to use. The default is /boot/boot0. +.It Fl m Ar boot0.5 +Specify which HDD boot menu image to use. The default is +/boot/boot0.5. +.It Fl f Ar boot0.bak +Specify that a backup copy of the preexisting IPL should be written to +.Ar boot0.bak . +This file is created if it does not exist, and truncated if it does. +.It Fl F Ar boot0.5.bak +Specify that a backup copy of the preexisting HDD boot menu should be +written to +.Ar boot0.5.bak . +This file is created if it does not exist, and truncated if it does. +.It Fl v Ar version +Specify the version number. +.It Fl s Ar secsize +Specify the sector size. The default secotor size is 512 +(bytes/sector). +.El +.Sh SEE ALSO +.Xr boot 8 , +.Xr fdisk 8 . +.Sh DIAGNOSTICS +Exit status is 0 on success and >0 on error. +.Sh AUTHORS +.An NOKUBI Hirotaka , +.An KATO Takenori diff --git a/usr.sbin/boot98cfg/boot98cfg.c b/usr.sbin/boot98cfg/boot98cfg.c new file mode 100644 index 000000000000..85a817d0ac7d --- /dev/null +++ b/usr.sbin/boot98cfg/boot98cfg.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) KATO Takenori, 2000. + * + * All rights reserved. Unpublished rights reserved under the copyright + * laws of Japan. + * + * 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 as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Copyright (c) 1999 Robert Nordier + * 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 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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IPLSIZE 512 /* IPL size */ +#define BOOTMENUSIZE 7168 /* Max HDD boot menu size */ +#define BOOTMENUOFF 0x400 + +static char *mkrdev(char *); +static void usage(void); + +u_char boot0buf[0x2000]; +char ipl[IPLSIZE]; +char menu[BOOTMENUSIZE]; + +/* + * Produce a device path for a "canonical" name, where appropriate. + */ +static char * +mkrdev(char *fname) +{ + char buf[MAXPATHLEN]; + struct stat sb; + char *s; + + s = (char *)fname; + if (!strchr(fname, '/')) { + snprintf(buf, sizeof(buf), "%sr%s", _PATH_DEV, fname); + if (stat(buf, &sb)) + snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname); + if (!(s = strdup(buf))) + err(1, NULL); + } + return s; +} + +static void +usage(void) +{ + fprintf(stderr, + "boot98cfg [-B][-i boot0][-m boot0.5][-s secsize][-v version]\n" + " [-f ipl.bak][-F menu.bak] disk\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + char *endptr; + char *iplpath = "/boot/boot0", *menupath = "/boot/boot0.5"; + char *iplbakpath = NULL, *menubakpath = NULL; + char *disk; + int B_flag = 0; + int c; + int fd, fd1; + int n; + int secsize = 512; + int v_flag = 0, version; + + while ((c = getopt(argc, argv, "BF:f:i:m:s:v:")) != -1) { + switch (c) { + case 'B': + B_flag = 1; + break; + case 'F': + menubakpath = optarg; + break; + case 'f': + iplbakpath = optarg; + break; + case 'i': + iplpath = optarg; + break; + case 'm': + menupath = optarg; + break; + case 's': + secsize = strtol(optarg, &endptr, 0); + if (errno || *optarg == NULL || *endptr) + errx(1, "%s: Bad argument to -s option", + optarg); + switch (secsize) { + case 256: + case 512: + case 1024: + case 2048: + break; + default: + errx(1, "%s: unsupported sector size", optarg); + break; + } + break; + case 'v': + v_flag = 1; + version = strtol(optarg, &endptr, 0); + if (errno || *optarg == NULL || *endptr || + version < 0 || version > 255) + errx(1, "%s: Bad argument to -s option", + optarg); + break; + default: + usage(); + /* NOTREACHED */ + break; + } + } + argc -= optind; + argv += optind; + if (argc != 1) + usage(); + disk = mkrdev(*argv); + + /* Read IPL, partition table and HDD boot menu. */ + fd = open(disk, O_RDWR); + if (fd < 0) + err(1, "%s", disk); + n = read(fd, boot0buf, 0x2000); + if (n != 0x2000) + errx(1, "%s: short read", disk); + if (!B_flag && !v_flag) + close(fd); + + if (iplbakpath != NULL) { + fd1 = open(iplbakpath, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd1 < 0) + err(1, "%s", iplbakpath); + n = write(fd1, boot0buf, IPLSIZE); + if (n == -1) + err(1, "%s", iplbakpath); + if (n != IPLSIZE) + errx(1, "%s: short write", iplbakpath); + close(fd1); + } + + if (menubakpath != NULL) { + fd1 = open(menubakpath, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd1 < 0) + err(1, "%s", menubakpath); + n = write(fd1, boot0buf + BOOTMENUOFF, BOOTMENUSIZE); + if (n == -1) + err(1, "%s", menubakpath); + if (n != BOOTMENUSIZE) + errx(1, "%s: short write", menubakpath); + close(fd1); + } + + if (B_flag) { + /* Read IPL (boot0). */ + fd1 = open(iplpath, O_RDONLY); + if (fd1 < 0) + err(1, "%s", disk); + n = read(fd1, ipl, IPLSIZE); + if (n < 0) + err(1, "%s", iplpath); + if (n != IPLSIZE) + errx(1, "%s: invalid file", iplpath); + close(fd1); + + /* Read HDD boot menu (boot0.5). */ + fd1 = open(menupath, O_RDONLY); + if (fd1 < 0) + err(1, "%s", disk); + n = read(fd1, menu, BOOTMENUSIZE); + if (n < 0) + err(1, "%s", menupath); + if (n != BOOTMENUSIZE) + errx(1, "%s: invalid file", menupath); + close(fd1); + + memcpy(boot0buf, ipl, IPLSIZE); + memcpy(boot0buf + BOOTMENUOFF, menu, BOOTMENUSIZE); + } + + /* Set version number field. */ + if (v_flag) + *(boot0buf + secsize - 4) = (u_char)version; + + if (B_flag || v_flag) { + if (lseek(fd, 0, SEEK_SET) == -1 || + (n = write(fd, boot0buf, 0x2000)) < 0 || + close(fd)) + err(1, "%s", disk); + if (n != 0x2000) + errx(1, "%s: short write", disk); + } + + return 0; +}