summaryrefslogtreecommitdiff
path: root/sys/arch/aviion
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2013-09-29 17:51:35 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2013-09-29 17:51:35 +0000
commitfa6b93ed201771db8d11ef9343f985b5996de11a (patch)
tree6ee5657bcaf977df14fd0c68a586318e3df1ec69 /sys/arch/aviion
parentda42e31395d08a08b30f86a4da2a810107c5ab24 (diff)
Simple installboot(8) for aviion. Awaiting boot blocks...
Diffstat (limited to 'sys/arch/aviion')
-rw-r--r--sys/arch/aviion/stand/Makefile4
-rw-r--r--sys/arch/aviion/stand/installboot/Makefile16
-rw-r--r--sys/arch/aviion/stand/installboot/installboot.870
-rw-r--r--sys/arch/aviion/stand/installboot/installboot.c224
4 files changed, 312 insertions, 2 deletions
diff --git a/sys/arch/aviion/stand/Makefile b/sys/arch/aviion/stand/Makefile
index cd0e25b6fc5..2fc4fcacf31 100644
--- a/sys/arch/aviion/stand/Makefile
+++ b/sys/arch/aviion/stand/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.3 2013/09/28 21:59:38 miod Exp $
+# $OpenBSD: Makefile,v 1.4 2013/09/29 17:51:34 miod Exp $
-SUBDIR= a2coff
+SUBDIR= a2coff installboot
.if ${MACHINE} == "aviion"
SUBDIR+= libprom libsa libz
diff --git a/sys/arch/aviion/stand/installboot/Makefile b/sys/arch/aviion/stand/installboot/Makefile
new file mode 100644
index 00000000000..95150cfef9a
--- /dev/null
+++ b/sys/arch/aviion/stand/installboot/Makefile
@@ -0,0 +1,16 @@
+# $OpenBSD: Makefile,v 1.1 2013/09/29 17:51:34 miod Exp $
+
+MAN= installboot.8
+MANSUBDIR= aviion
+
+.if ${MACHINE} == "aviion"
+PROG= installboot
+BINDIR= /usr/mdec
+DPADD= ${LIBUTIL}
+LDADD= -lutil
+LDSTATIC= -static
+.else
+NOPROG=
+.endif
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/aviion/stand/installboot/installboot.8 b/sys/arch/aviion/stand/installboot/installboot.8
new file mode 100644
index 00000000000..90e6863b41a
--- /dev/null
+++ b/sys/arch/aviion/stand/installboot/installboot.8
@@ -0,0 +1,70 @@
+.\" $OpenBSD: installboot.8,v 1.1 2013/09/29 17:51:34 miod Exp $
+.\"
+.\" Copyright (c) 1994 Paul Kranenburg
+.\" 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 Paul Kranenburg.
+.\" 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.
+.\"
+.Dd $Mdocdate: September 29 2013 $
+.Dt INSTALLBOOT 8 aviion
+.Os
+.Sh NAME
+.Nm installboot
+.Nd install a bootstrap on a disk
+.Sh SYNOPSIS
+.Nm installboot
+.Op Fl n
+.Op Fl v
+.Ar boot
+.Ar rawdev
+.Sh DESCRIPTION
+.Nm installboot
+is used to install a boot program into the VDM boot area of a disk.
+.Pp
+The options are as follows:
+.Bl -tag -width flag
+.It Fl n
+Do not actually write anything on the disk.
+.It Fl v
+Be verbose, printing out boot area and boot file information.
+.El
+.Pp
+The arguments are:
+.Bl -tag -width boot
+.It Ar boot
+the name of the boot program to be installed.
+.It Ar rawdev
+the name of the raw disk device in which the boot program is to be installed.
+It may be abbreviated into a form recognizable by
+.Xr opendev 3 .
+.El
+.Sh EXAMPLES
+.Bd -literal -offset
+/usr/mdec/installboot /usr/mdec/boot sd0
+.Ed
+.Sh SEE ALSO
+.Xr disklabel 8 ,
+.Xr init 8
diff --git a/sys/arch/aviion/stand/installboot/installboot.c b/sys/arch/aviion/stand/installboot/installboot.c
new file mode 100644
index 00000000000..14dd06aa2c5
--- /dev/null
+++ b/sys/arch/aviion/stand/installboot/installboot.c
@@ -0,0 +1,224 @@
+/* $OpenBSD: installboot.c,v 1.1 2013/09/29 17:51:34 miod Exp $ */
+
+/*
+ * Copyright (c) 2013 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <unistd.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <util.h>
+#include <sys/disklabel.h>
+#include <sys/stat.h>
+
+int nowrite, verbose;
+char *boot, *dev;
+
+void analyze_label_sector(uint8_t *, struct vdm_label **,
+ struct vdm_boot_info **);
+void initialize_boot_area(int);
+void read_sector(int, uint32_t, void *);
+void usage(void);
+void write_sector(int, uint32_t, void *);
+
+#define VDM_BLOCK_SIZE 0x200
+
+uint8_t buf[VDM_BLOCK_SIZE];
+
+void
+usage()
+{
+ fprintf(stderr, "usage: installboot [-n] <boot> <device>\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ int bootfd, devfd;
+ size_t chunk;
+ uint32_t blkno;
+ struct stat stat;
+ struct vdm_label *dl;
+ struct vdm_boot_info *bi;
+
+ while ((c = getopt(argc, argv, "nv")) != -1) {
+ switch (c) {
+ case 'n':
+ nowrite = 1;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (argc - optind != 2)
+ usage();
+
+ boot = argv[optind];
+ dev = argv[optind + 1];
+
+ bootfd = open(boot, O_RDONLY);
+ if (bootfd < 0)
+ err(1, "open(%s)", boot);
+
+ if (fstat(bootfd, &stat) != 0)
+ err(1, "fstat(%s)", boot);
+
+ devfd = opendev(dev, nowrite ? O_RDONLY : O_RDWR, OPENDEV_PART, &dev);
+ if (devfd < 0)
+ err(1, "open(%s)", dev);
+
+ /*
+ * Figure out the boot area span.
+ * If there is no VDM boot area, set up one.
+ */
+
+ read_sector(devfd, VDM_LABEL_SECTOR, buf);
+ analyze_label_sector(buf, &dl, &bi);
+
+ if (bi == NULL) {
+ if (verbose)
+ printf("no boot area found\n");
+ if (nowrite)
+ return 0;
+ if (verbose)
+ printf("creating boot area\n");
+ initialize_boot_area(devfd);
+
+ read_sector(devfd, VDM_LABEL_SECTOR, buf);
+ analyze_label_sector(buf, &dl, &bi);
+ }
+
+ if (bi != NULL) {
+ if (verbose)
+ printf("boot area: sectors %u-%u\n",
+ bi->boot_start, bi->boot_start + bi->boot_size - 1);
+ } else {
+ /* should not happen */
+ return 1;
+ }
+
+ /*
+ * Write the file into the boot area.
+ */
+
+ if (stat.st_size > bi->boot_size * VDM_BLOCK_SIZE)
+ err(1, "boot file too large, boot area is only %u bytes",
+ bi->boot_size * VDM_BLOCK_SIZE);
+
+ if (nowrite)
+ return 0;
+
+ blkno = bi->boot_start;
+ if (verbose)
+ printf("writing %lld bytes from sector %u onwards\n",
+ stat.st_size, blkno);
+ while (stat.st_size != 0) {
+ if (stat.st_size > sizeof buf)
+ chunk = sizeof buf;
+ else {
+ chunk = stat.st_size;
+ memset(buf, 0, sizeof buf);
+ }
+ if (read(bootfd, buf, chunk) != chunk)
+ err(1, "read");
+ write_sector(devfd, blkno++, buf);
+ stat.st_size -= chunk;
+ }
+
+ close(bootfd);
+ close(devfd);
+ return 0;
+}
+
+void
+read_sector(int fd, uint32_t secno, void *buf)
+{
+ if (lseek(fd, (off_t)secno * VDM_BLOCK_SIZE, SEEK_SET) == -1)
+ err(1, "lseek");
+
+ if (read(fd, buf, VDM_BLOCK_SIZE) != VDM_BLOCK_SIZE)
+ err(1, "read(%d,%08x)", fd, secno);
+}
+
+void
+write_sector(int fd, uint32_t secno, void *buf)
+{
+ if (lseek(fd, (off_t)secno * VDM_BLOCK_SIZE, SEEK_SET) == -1)
+ err(1, "lseek");
+
+ if (write(fd, buf, VDM_BLOCK_SIZE) != VDM_BLOCK_SIZE)
+ err(1, "write(%d,%08x)", fd, secno);
+}
+
+void
+analyze_label_sector(uint8_t *sector, struct vdm_label **dl,
+ struct vdm_boot_info **dbi)
+{
+ struct vdm_label *l;
+ struct vdm_boot_info *bi;
+
+ l = (struct vdm_label *)(sector + VDM_LABEL_OFFSET);
+ if (betoh32(l->signature) != VDM_LABEL_SIGNATURE) {
+ l = (struct vdm_label *)(sector + VDM_LABEL_OFFSET_ALT);
+ if (betoh32(l->signature) != VDM_LABEL_SIGNATURE)
+ l = NULL;
+ }
+
+ if (l != NULL) {
+ bi = (struct vdm_boot_info *)
+ (sector + VDM_BLOCK_SIZE - sizeof *bi);
+ if (betoh32(bi->signature) != VDM_LABEL_SIGNATURE)
+ bi = NULL;
+ } else
+ bi = NULL;
+
+ *dl = l;
+ *dbi = bi;
+}
+
+/*
+ * Build a minimal VDM label and boot area.
+ * Allows you to shoot yourself in the foot, badly.
+ */
+void
+initialize_boot_area(int fd)
+{
+ struct vdm_label dl;
+ struct vdm_boot_info bi;
+
+ memset(buf, 0, sizeof buf);
+ memset(&dl, 0, sizeof dl);
+ memset(&bi, 0, sizeof bi);
+
+ dl.signature = htobe32(VDM_LABEL_SIGNATURE);
+ bi.signature = htobe32(VDM_LABEL_SIGNATURE);
+ bi.boot_start = htobe32(LABELSECTOR + 1);
+ bi.boot_size = htobe32(VDM_BOOT_DEFAULT_SIZE);
+ bi.version = htobe32(VDM_BOOT_INFO_VERSION);
+
+ memcpy(buf + VDM_LABEL_OFFSET_ALT, &dl, sizeof dl);
+ memcpy(buf + VDM_BLOCK_SIZE - sizeof bi, &bi, sizeof bi);
+
+ write_sector(fd, VDM_LABEL_SECTOR, buf);
+}