diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2014-06-09 15:51:41 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2014-06-09 15:51:41 +0000 |
commit | a5de61eae9ea46dbbb04ef82cd5225da982de0eb (patch) | |
tree | 84ceee02d755049789bc77b33f071f1a4b481acc /sys/arch/amd64/stand | |
parent | 33183ad5c4c5aa9e817cb101e560f4d2187f317b (diff) |
Remove {amd64,i386}/stand/installboot - we now use usr.sbin/installboot
and these have been unhooked from the build for a while now.
Diffstat (limited to 'sys/arch/amd64/stand')
-rw-r--r-- | sys/arch/amd64/stand/installboot/Makefile | 18 | ||||
-rw-r--r-- | sys/arch/amd64/stand/installboot/installboot.8 | 127 | ||||
-rw-r--r-- | sys/arch/amd64/stand/installboot/installboot.c | 839 | ||||
-rw-r--r-- | sys/arch/amd64/stand/installboot/nlist.c | 312 |
4 files changed, 0 insertions, 1296 deletions
diff --git a/sys/arch/amd64/stand/installboot/Makefile b/sys/arch/amd64/stand/installboot/Makefile deleted file mode 100644 index 8933fdf6730..00000000000 --- a/sys/arch/amd64/stand/installboot/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $OpenBSD: Makefile,v 1.2 2012/09/25 09:01:03 pascal Exp $ - -MAN= installboot.8 - -.if ${MACHINE} == "amd64" -PROG= installboot - -LDADD= -lutil -DPADD= ${LIBUTIL} -# Need this to work in the miniroot -LDSTATIC= -static - -SADIR= ${.CURDIR}/.. -.else -NOPROG= -.endif - -.include <bsd.prog.mk> diff --git a/sys/arch/amd64/stand/installboot/installboot.8 b/sys/arch/amd64/stand/installboot/installboot.8 deleted file mode 100644 index 0bb428faf44..00000000000 --- a/sys/arch/amd64/stand/installboot/installboot.8 +++ /dev/null @@ -1,127 +0,0 @@ -.\" $OpenBSD: installboot.8,v 1.4 2010/03/06 16:16:43 jmc Exp $ -.\" -.\" Copyright (c) 1997 Michael Shalayeff -.\" 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 REGENTS 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 $Mdocdate: March 6 2010 $ -.Dt INSTALLBOOT 8 amd64 -.Os -.Sh NAME -.Nm installboot -.Nd installs a bootstrap on an FFS disk or partition -.Sh SYNOPSIS -.Nm installboot -.Op Fl nv -.Ar boot -.Ar biosboot -.Ar disk -.Sh DESCRIPTION -.Nm -is used to install a -.Dq first-stage -boot program into the boot area of an FFS disk partition. -It inserts the block number and offset of the inode of -the second-stage boot program -.Xr boot 8 -so that the -.Xr biosboot 8 -program can load it. -Various filesystem parameters are also patched into the boot block. -.Pp -The options are as follows: -.Bl -tag -width flag_opt -.It Fl n -Do not actually write anything on the disk. -.It Fl v -Be verbose, printing out the data that are stored in -.Ar biosboot -along with lots of other information. -.El -.Pp -The arguments are: -.Bl -tag -width biosboot -.It Ar boot -The name of the second-stage boot program in the mounted file system -where the first-stage boot program is to be installed. -This should be a full pathname. -.It Ar biosboot -The name of the prototype file for the first stage boot program, -usually -.Pa /usr/mdec/biosboot . -.It Ar disk -The name of the disk containing the partition in which the second-stage -boot program resides and the first-stage boot program is to be installed. -This can either be specified in short form (e.g., -.Sq sd0 -or -.Sq wd0 ) , -or as the explicit device node, such as -.Pa /dev/rsd0c -or -.Pa /dev/rwd0c . -.Pp -The -.Sq c -partition is always used to represent the -.Dq entire -disk on amd64. -.El -.Sh EXAMPLES -The typical use is -.Bd -literal -offset indent -# cp /usr/mdec/boot /boot -# /usr/mdec/installboot -n -v /boot /usr/mdec/biosboot sd0 -.Ed -.Pp -And if the information supplied looks right, run the above without the -.Fl n -flag. -If you are upgrading an old system, you may need to perform -some additional steps first. -For example: -.Bd -literal -offset indent -boot the floppy.fs filesystem floppy -# fsck /dev/rsd0a -# mount /dev/sd0a /mnt -# cp /usr/mdec/boot /mnt/boot -# /usr/mdec/installboot -v /mnt/boot /usr/mdec/biosboot sd0 -.Ed -.Sh SEE ALSO -.Xr biosboot 8 , -.Xr boot 8 , -.Xr disklabel 8 , -.Xr fdisk 8 , -.Xr init 8 -.Sh CAVEATS -The disklabel -.Va d_type -field must be set to a value other than -.Dq unknown . -.Pp -.Pa /boot -must be on the drive/partition specified by -.Pa disk ; -you cannot perform cross-device -.Nm Ns s . diff --git a/sys/arch/amd64/stand/installboot/installboot.c b/sys/arch/amd64/stand/installboot/installboot.c deleted file mode 100644 index 30ea0c80bb9..00000000000 --- a/sys/arch/amd64/stand/installboot/installboot.c +++ /dev/null @@ -1,839 +0,0 @@ -/* $OpenBSD: installboot.c,v 1.27 2013/11/13 04:11:34 krw Exp $ */ -/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ - -/* - * Copyright (c) 2011 Joel Sing <jsing@openbsd.org> - * Copyright (c) 2010 Otto Moerbeek <otto@openbsd.org> - * Copyright (c) 2003 Tom Cosgrove <tom.cosgrove@arches-consulting.com> - * Copyright (c) 1997 Michael Shalayeff - * 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. - */ - -#define ELFSIZE 32 - -#include <sys/param.h> -#include <sys/mount.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/disklabel.h> -#include <sys/dkio.h> -#include <sys/ioctl.h> -#include <ufs/ufs/dinode.h> -#include <ufs/ufs/dir.h> -#include <ufs/ffs/fs.h> -#include <sys/reboot.h> - -#include <dev/biovar.h> -#include <dev/softraidvar.h> - -#include <uvm/uvm_extern.h> -#include <sys/sysctl.h> - -#include <machine/cpu.h> -#include <machine/biosvar.h> - -#include <err.h> -#include <a.out.h> -#include <sys/exec_elf.h> -#include <fcntl.h> -#include <nlist.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <util.h> - -#include "nlist.c" - -struct sym_data { - char *sym_name; /* Must be initialised */ - int sym_size; /* And this one */ - int sym_set; /* Rest set at runtime */ - u_int32_t sym_value; -}; - -extern char *__progname; -int verbose, nowrite = 0; -char *boot, *proto, *dev, *realdev; -char *protostore; -long protosize; -struct sym_data pbr_symbols[] = { - {"_fs_bsize_p", 2}, - {"_fs_bsize_s", 2}, - {"_fsbtodb", 1}, - {"_p_offset", 4}, - {"_inodeblk", 4}, - {"_inodedbl", 4}, - {"_nblocks", 2}, - {NULL} -}; - -#define INODESEG 0x07e0 /* where we will put /boot's inode's block */ -#define BOOTSEG 0x07c0 /* biosboot loaded here */ - -#define INODEOFF ((INODESEG-BOOTSEG) << 4) - -#define SR_FS_BLOCKSIZE (16 * 1024) - -static char *loadproto(char *, long *); -static int getbootparams(char *, int, struct disklabel *); -static void devread(int, void *, daddr_t, size_t, char *); -static void sym_set_value(struct sym_data *, char *, u_int32_t); -static void pbr_set_symbols(char *, char *, struct sym_data *); -static void usage(void); -static u_int findopenbsd(int, struct disklabel *); -static void write_bootblocks(int devfd, struct disklabel *); - -static int sr_volume(int, int *, int *); -static void sr_installboot(int); -static void sr_installpbr(int, int, int); - -static void -usage(void) -{ - fprintf(stderr, "usage: %s [-nv] boot biosboot device\n", __progname); - exit(1); -} - -/* - * Read information about /boot's inode and filesystem parameters, then - * put biosboot (partition boot record) on the target drive with these - * parameters patched in. - */ -int -main(int argc, char *argv[]) -{ - int vol = -1, ndisks = 0, disk; - int c; - int devfd; - struct disklabel dl; - - while ((c = getopt(argc, argv, "vn")) != -1) { - switch (c) { - case 'n': - /* Do not actually write the bootblock to disk. */ - nowrite = 1; - break; - case 'v': - /* Give more information. */ - verbose = 1; - break; - default: - usage(); - } - } - - if (argc - optind < 3) - usage(); - - boot = argv[optind]; - proto = argv[optind + 1]; - realdev = dev = argv[optind + 2]; - - /* Open raw disk device. */ - if ((devfd = opendev(dev, (nowrite? O_RDONLY:O_RDWR), - OPENDEV_PART, &realdev)) < 0) - err(1, "open: %s", realdev); - - if (verbose) - fprintf(stderr, "boot: %s proto: %s device: %s\n", - boot, proto, realdev); - - /* Load proto blocks into core. */ - if ((protostore = loadproto(proto, &protosize)) == NULL) - exit(1); - - /* XXX - Paranoia: Make sure size is aligned! */ - if (protosize & (DEV_BSIZE - 1)) - errx(1, "proto %s bad size=%ld", proto, protosize); - - if (protosize > SBSIZE - DEV_BSIZE) - errx(1, "proto bootblocks too big"); - - if (sr_volume(devfd, &vol, &ndisks)) { - - /* Install boot loader into softraid volume. */ - sr_installboot(devfd); - - /* Install biosboot on each disk that is part of this volume. */ - for (disk = 0; disk < ndisks; disk++) - sr_installpbr(devfd, vol, disk); - - } else { - - /* Get and check disklabel. */ - if (ioctl(devfd, DIOCGDINFO, &dl) != 0) - err(1, "disklabel: %s", realdev); - if (dl.d_magic != DISKMAGIC) - err(1, "bad disklabel magic=0x%08x", dl.d_magic); - - /* Warn on unknown disklabel types. */ - if (dl.d_type == 0) - warnx("disklabel type unknown"); - - /* Get bootstrap parameters to patch into proto. */ - if (getbootparams(boot, devfd, &dl) != 0) - exit(1); - - /* Write boot blocks to device. */ - write_bootblocks(devfd, &dl); - - } - - (void)close(devfd); - - return 0; -} - -void -write_bootblocks(int devfd, struct disklabel *dl) -{ - struct stat sb; - u_int8_t *secbuf; - u_int start = 0; - - /* Write patched proto bootblock(s) into the superblock. */ - if (fstat(devfd, &sb) < 0) - err(1, "stat: %s", realdev); - - if (!S_ISCHR(sb.st_mode)) - errx(1, "%s: not a character device", realdev); - - /* Patch the parameters into the proto bootstrap sector. */ - pbr_set_symbols(proto, protostore, pbr_symbols); - - if (!nowrite) { - /* Sync filesystems (to clean in-memory superblock?). */ - sync(); sleep(1); - } - - /* - * Find OpenBSD partition. Floppies are special, getting an - * everything-in-one biosboot starting at sector 0. - */ - if (dl->d_type != DTYPE_FLOPPY) { - start = findopenbsd(devfd, dl); - if (start == (u_int)-1) - errx(1, "no OpenBSD partition"); - } - - if (verbose) - fprintf(stderr, "%s will be written at sector %u\n", proto, - start); - - if (start + (protosize / dl->d_secsize) > BOOTBIOS_MAXSEC) - warnx("%s extends beyond sector %u. OpenBSD might not boot.", - proto, BOOTBIOS_MAXSEC); - - if (!nowrite) { - if (lseek(devfd, (off_t)start * dl->d_secsize, SEEK_SET) < 0) - err(1, "seek bootstrap"); - secbuf = calloc(1, dl->d_secsize); - bcopy(protostore, secbuf, protosize); - if (write(devfd, secbuf, dl->d_secsize) != dl->d_secsize) - err(1, "write bootstrap"); - free(secbuf); - } -} - -u_int -findopenbsd(int devfd, struct disklabel *dl) -{ - struct dos_mbr mbr; - u_int mbroff = DOSBBSECTOR; - u_int mbr_eoff = DOSBBSECTOR; /* Offset of extended part. */ - struct dos_partition *dp; - u_int8_t *secbuf; - int i, maxebr = DOS_MAXEBR, nextebr; - -again: - if (!maxebr--) { - if (verbose) - fprintf(stderr, "Traversed more than %d Extended Boot " - "Records (EBRs)\n", - DOS_MAXEBR); - return ((u_int)-1); - } - - if (verbose) - fprintf(stderr, "%s boot record (%cBR) at sector %u\n", - (mbroff == DOSBBSECTOR) ? "master" : "extended", - (mbroff == DOSBBSECTOR) ? 'M' : 'E', mbroff); - - secbuf = malloc(dl->d_secsize); - if (lseek(devfd, (off_t)mbroff * dl->d_secsize, SEEK_SET) < 0 || - read(devfd, secbuf, dl->d_secsize) < sizeof(mbr)) - err(4, "can't read boot record"); - bcopy(secbuf, &mbr, sizeof(mbr)); - free(secbuf); - - if (mbr.dmbr_sign != DOSMBR_SIGNATURE) - errx(1, "invalid boot record signature (0x%04X) @ sector %u", - mbr.dmbr_sign, mbroff); - - nextebr = 0; - for (i = 0; i < NDOSPART; i++) { - dp = &mbr.dmbr_parts[i]; - if (!dp->dp_size) - continue; - - if (verbose) - fprintf(stderr, - "\tpartition %d: type 0x%02X offset %u size %u\n", - i, dp->dp_typ, dp->dp_start, dp->dp_size); - - if (dp->dp_typ == DOSPTYP_OPENBSD) { - if (dp->dp_start > (dp->dp_start + mbroff)) - continue; - return (dp->dp_start + mbroff); - } - - if (!nextebr && (dp->dp_typ == DOSPTYP_EXTEND || - dp->dp_typ == DOSPTYP_EXTENDL)) { - nextebr = dp->dp_start + mbr_eoff; - if (nextebr < dp->dp_start) - nextebr = (u_int)-1; - if (mbr_eoff == DOSBBSECTOR) - mbr_eoff = dp->dp_start; - } - } - - if (nextebr && nextebr != (u_int)-1) { - mbroff = nextebr; - goto again; - } - - return ((u_int)-1); -} - -/* - * Load the prototype boot sector (biosboot) into memory. - */ -static char * -loadproto(char *fname, long *size) -{ - int fd; - size_t tdsize; /* text+data size */ - char *bp; - Elf_Ehdr eh; - Elf_Word phsize; - Elf_Phdr *ph; - - if ((fd = open(fname, O_RDONLY)) < 0) - err(1, "%s", fname); - - if (read(fd, &eh, sizeof(eh)) != sizeof(eh)) - errx(1, "%s: read failed", fname); - - if (!IS_ELF(eh)) - errx(1, "%s: bad magic: 0x%02x%02x%02x%02x", - fname, - eh.e_ident[EI_MAG0], eh.e_ident[EI_MAG1], - eh.e_ident[EI_MAG2], eh.e_ident[EI_MAG3]); - - /* - * We have to include the exec header in the beginning of - * the buffer, and leave extra space at the end in case - * the actual write to disk wants to skip the header. - */ - - /* Program load header. */ - if (eh.e_phnum != 1) - errx(1, "%s: %u ELF load sections (only support 1)", - fname, eh.e_phnum); - - phsize = eh.e_phnum * sizeof(Elf_Phdr); - ph = malloc(phsize); - if (ph == NULL) - err(1, NULL); - - lseek(fd, eh.e_phoff, SEEK_SET); - - if (read(fd, ph, phsize) != phsize) - errx(1, "%s: can't read header", fname); - - tdsize = ph->p_filesz; - - /* - * Allocate extra space here because the caller may copy - * the boot block starting at the end of the exec header. - * This prevents reading beyond the end of the buffer. - */ - if ((bp = calloc(tdsize, 1)) == NULL) { - err(1, NULL); - } - - /* Read the rest of the file. */ - lseek(fd, ph->p_offset, SEEK_SET); - if (read(fd, bp, tdsize) != tdsize) { - errx(1, "%s: read failed", fname); - } - - *size = tdsize; /* not aligned to DEV_BSIZE */ - - close(fd); - return bp; -} - -static void -devread(int fd, void *buf, daddr_t blk, size_t size, char *msg) -{ - if (lseek(fd, dbtob((off_t)blk), SEEK_SET) != dbtob((off_t)blk)) - err(1, "%s: devread: lseek", msg); - - if (read(fd, buf, size) != size) - err(1, "%s: devread: read", msg); -} - -static char sblock[SBSIZE]; - -/* - * Read information about /boot's inode, then put this and filesystem - * parameters from the superblock into pbr_symbols. - */ -static int -getbootparams(char *boot, int devfd, struct disklabel *dl) -{ - int fd; - struct stat statbuf, sb; - struct statfs statfsbuf; - struct partition *pp; - struct fs *fs; - char *buf; - u_int blk, *ap; - struct ufs1_dinode *ip; - int ndb; - int mib[3]; - size_t size; - dev_t dev; - - /* - * Open 2nd-level boot program and record enough details about - * where it is on the filesystem represented by `devfd' - * (inode block, offset within that block, and various filesystem - * parameters essentially taken from the superblock) for biosboot - * to be able to load it later. - */ - - /* Make sure the (probably new) boot file is on disk. */ - sync(); sleep(1); - - if ((fd = open(boot, O_RDONLY)) < 0) - err(1, "open: %s", boot); - - if (fstatfs(fd, &statfsbuf) != 0) - err(1, "statfs: %s", boot); - - if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) && - strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN) ) - errx(1, "%s: not on an FFS filesystem", boot); - -#if 0 - if (read(fd, &eh, sizeof(eh)) != sizeof(eh)) - errx(1, "read: %s", boot); - - if (!IS_ELF(eh)) { - errx(1, "%s: bad magic: 0x%02x%02x%02x%02x", - boot, - eh.e_ident[EI_MAG0], eh.e_ident[EI_MAG1], - eh.e_ident[EI_MAG2], eh.e_ident[EI_MAG3]); - } -#endif - - if (fsync(fd) != 0) - err(1, "fsync: %s", boot); - - if (fstat(fd, &statbuf) != 0) - err(1, "fstat: %s", boot); - - if (fstat(devfd, &sb) != 0) - err(1, "fstat: %s", realdev); - - /* Check devices. */ - mib[0] = CTL_MACHDEP; - mib[1] = CPU_CHR2BLK; - mib[2] = sb.st_rdev; - size = sizeof(dev); - if (sysctl(mib, 3, &dev, &size, NULL, 0) >= 0) { - if (statbuf.st_dev / MAXPARTITIONS != dev / MAXPARTITIONS) - errx(1, "cross-device install"); - } - - pp = &dl->d_partitions[DISKPART(statbuf.st_dev)]; - close(fd); - - /* Read superblock. */ - devread(devfd, sblock, DL_SECTOBLK(dl, DL_GETPOFFSET(pp)) + SBLOCK, - SBSIZE, "superblock"); - fs = (struct fs *)sblock; - - /* Sanity-check super-block. */ - if (fs->fs_magic != FS_MAGIC) - errx(1, "Bad magic number in superblock"); - if (fs->fs_inopb <= 0) - err(1, "Bad inopb=%d in superblock", fs->fs_inopb); - - /* Read inode. */ - if ((buf = malloc(fs->fs_bsize)) == NULL) - err(1, NULL); - - blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino)); - - devread(devfd, buf, DL_SECTOBLK(dl, DL_GETPOFFSET(pp)) + blk, - fs->fs_bsize, "inode"); - ip = (struct ufs1_dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); - - /* - * Have the inode. Figure out how many filesystem blocks (not disk - * sectors) there are for biosboot to load. - */ - ndb = howmany(ip->di_size, fs->fs_bsize); - if (ndb <= 0) - errx(1, "No blocks to load"); - - /* - * Now set the values that will need to go into biosboot - * (the partition boot record, a.k.a. the PBR). - */ - sym_set_value(pbr_symbols, "_fs_bsize_p", (fs->fs_bsize / 16)); - sym_set_value(pbr_symbols, "_fs_bsize_s", (fs->fs_bsize / - dl->d_secsize)); - - /* - * fs_fsbtodb is the shift to convert fs_fsize to DEV_BSIZE. The - * ino_to_fsba() return value is the number of fs_fsize units. - * Calculate the shift to convert fs_fsize into physical sectors, - * which are added to p_offset to get the sector address BIOS - * will use. - * - * N.B.: ASSUMES fs_fsize is a power of 2 of d_secsize. - */ - sym_set_value(pbr_symbols, "_fsbtodb", - ffs(fs->fs_fsize / dl->d_secsize) - 1); - - if (pp->p_offseth != 0) - errx(1, "partition offset too high"); - sym_set_value(pbr_symbols, "_p_offset", pp->p_offset); - sym_set_value(pbr_symbols, "_inodeblk", - ino_to_fsba(fs, statbuf.st_ino)); - ap = ip->di_db; - sym_set_value(pbr_symbols, "_inodedbl", - ((((char *)ap) - buf) + INODEOFF)); - sym_set_value(pbr_symbols, "_nblocks", ndb); - - if (verbose) { - fprintf(stderr, "%s is %d blocks x %d bytes\n", - boot, ndb, fs->fs_bsize); - fprintf(stderr, "fs block shift %u; part offset %llu; " - "inode block %lld, offset %u\n", - ffs(fs->fs_fsize / dl->d_secsize) - 1, - DL_GETPOFFSET(pp), ino_to_fsba(fs, statbuf.st_ino), - (unsigned int)((((char *)ap) - buf) + INODEOFF)); - } - - return 0; -} - -static void -sym_set_value(struct sym_data *sym_list, char *sym, u_int32_t value) -{ - struct sym_data *p; - - for (p = sym_list; p->sym_name != NULL; p++) { - if (strcmp(p->sym_name, sym) == 0) - break; - } - - if (p->sym_name == NULL) - errx(1, "%s: no such symbol", sym); - - p->sym_value = value; - p->sym_set = 1; -} - -/* - * Write the parameters stored in sym_list into the in-memory copy of - * the prototype biosboot (proto), ready for it to be written to disk. - */ -static void -pbr_set_symbols(char *fname, char *proto, struct sym_data *sym_list) -{ - struct sym_data *sym; - struct nlist *nl; - char *vp; - u_int32_t *lp; - u_int16_t *wp; - u_int8_t *bp; - - for (sym = sym_list; sym->sym_name != NULL; sym++) { - if (!sym->sym_set) - errx(1, "%s not set", sym->sym_name); - - /* Allocate space for 2; second is null-terminator for list. */ - nl = calloc(2, sizeof(struct nlist)); - if (nl == NULL) - err(1, NULL); - - nl->n_un.n_name = sym->sym_name; - - if (nlist(fname, nl) != 0) - errx(1, "%s: symbol %s not found", - fname, sym->sym_name); - - if (nl->n_type != (N_TEXT)) - errx(1, "%s: %s: wrong type (%x)", - fname, sym->sym_name, nl->n_type); - - /* Get a pointer to where the symbol's value needs to go. */ - vp = proto + nl->n_value; - - switch (sym->sym_size) { - case 4: /* u_int32_t */ - lp = (u_int32_t *) vp; - *lp = sym->sym_value; - break; - case 2: /* u_int16_t */ - if (sym->sym_value >= 0x10000) /* out of range */ - errx(1, "%s: symbol out of range (%u)", - sym->sym_name, sym->sym_value); - wp = (u_int16_t *) vp; - *wp = (u_int16_t) sym->sym_value; - break; - case 1: /* u_int16_t */ - if (sym->sym_value >= 0x100) /* out of range */ - errx(1, "%s: symbol out of range (%u)", - sym->sym_name, sym->sym_value); - bp = (u_int8_t *) vp; - *bp = (u_int8_t) sym->sym_value; - break; - default: - errx(1, "%s: bad symbol size %d", - sym->sym_name, sym->sym_size); - /* NOTREACHED */ - } - - free(nl); - } -} - -int -sr_volume(int devfd, int *vol, int *disks) -{ - struct bioc_inq bi; - struct bioc_vol bv; - int rv, i; - - /* Get volume information. */ - memset(&bi, 0, sizeof(bi)); - rv = ioctl(devfd, BIOCINQ, &bi); - if (rv == -1) - return 0; - - /* XXX - softraid volumes will always have a "softraid0" controller. */ - if (strncmp(bi.bi_dev, "softraid0", sizeof("softraid0"))) - return 0; - - /* Locate specific softraid volume. */ - for (i = 0; i < bi.bi_novol; i++) { - - memset(&bv, 0, sizeof(bv)); - bv.bv_volid = i; - rv = ioctl(devfd, BIOCVOL, &bv); - if (rv == -1) - err(1, "BIOCVOL"); - - if (strncmp(dev, bv.bv_dev, sizeof(bv.bv_dev)) == 0) { - *vol = i; - *disks = bv.bv_nodisk; - break; - } - - } - - if (verbose) - fprintf(stderr, "%s: softraid volume with %i disk(s)\n", - dev, *disks); - - return 1; -} - -void -sr_installboot(int devfd) -{ - struct bioc_installboot bb; - struct stat sb; - struct ufs1_dinode *ino_p; - uint32_t bootsize, inodeblk, inodedbl; - uint16_t bsize = SR_FS_BLOCKSIZE; - uint16_t nblocks; - uint8_t bshift = 5; /* fragsize == blocksize */ - int fd, i, rv; - u_char *p; - - /* - * Install boot loader into softraid boot loader storage area. - * - * In order to allow us to reuse the existing biosboot we construct - * a fake FFS filesystem with a single inode, which points to the - * boot loader. - */ - - nblocks = howmany(SR_BOOT_LOADER_SIZE, SR_FS_BLOCKSIZE / DEV_BSIZE); - inodeblk = nblocks - 1; - bootsize = nblocks * SR_FS_BLOCKSIZE; - - p = malloc(bootsize); - if (p == NULL) - err(1, NULL); - - memset(p, 0, bootsize); - fd = open(boot, O_RDONLY, 0); - if (fd == -1) - err(1, NULL); - - if (fstat(fd, &sb) == -1) - err(1, NULL); - - nblocks = howmany(sb.st_blocks, SR_FS_BLOCKSIZE / DEV_BSIZE); - if (sb.st_blocks * S_BLKSIZE > bootsize - sizeof(struct ufs1_dinode)) - errx(1, "boot code will not fit"); - - /* We only need to fill the direct block array. */ - ino_p = (struct ufs1_dinode *)&p[bootsize - sizeof(struct ufs1_dinode)]; - - ino_p->di_mode = sb.st_mode; - ino_p->di_nlink = 1; - ino_p->di_inumber = 0xfeebfaab; - ino_p->di_size = read(fd, p, sb.st_blocks * S_BLKSIZE); - ino_p->di_blocks = nblocks; - for (i = 0; i < nblocks; i++) - ino_p->di_db[i] = i; - - inodedbl = ((u_char*)&ino_p->di_db[0] - - &p[bootsize - SR_FS_BLOCKSIZE]) + INODEOFF; - - bb.bb_bootldr = p; - bb.bb_bootldr_size = bootsize; - bb.bb_bootblk = "XXX"; - bb.bb_bootblk_size = sizeof("XXX"); - strncpy(bb.bb_dev, dev, sizeof(bb.bb_dev)); - if (!nowrite) { - if (verbose) - fprintf(stderr, "%s: installing boot loader on " - "softraid volume\n", dev); - rv = ioctl(devfd, BIOCINSTALLBOOT, &bb); - if (rv != 0) - errx(1, "softraid installboot failed"); - } - - /* - * Set the values that will need to go into biosboot - * (the partition boot record, a.k.a. the PBR). - */ - sym_set_value(pbr_symbols, "_fs_bsize_p", (bsize / 16)); - sym_set_value(pbr_symbols, "_fs_bsize_s", (bsize / 512)); - sym_set_value(pbr_symbols, "_fsbtodb", bshift); - sym_set_value(pbr_symbols, "_inodeblk", inodeblk); - sym_set_value(pbr_symbols, "_inodedbl", inodedbl); - sym_set_value(pbr_symbols, "_nblocks", nblocks); - - if (verbose) - fprintf(stderr, "%s is %d blocks x %d bytes\n", - boot, nblocks, bsize); - - close(fd); -} - -void -sr_installpbr(int devfd, int vol, int disk) -{ - struct bioc_disk bd; - struct disklabel dl; - struct partition *pp; - uint32_t poffset; - char *realdiskdev; - char part; - int diskfd; - int rv; - - /* Get device name for this disk/chunk. */ - memset(&bd, 0, sizeof(bd)); - bd.bd_volid = vol; - bd.bd_diskid = disk; - rv = ioctl(devfd, BIOCDISK, &bd); - if (rv == -1) - err(1, "BIOCDISK"); - - /* Check disk status. */ - if (bd.bd_status != BIOC_SDONLINE && bd.bd_status != BIOC_SDREBUILD) { - fprintf(stderr, "softraid chunk %u not online - skipping...\n", - disk); - return; - } - - if (strlen(bd.bd_vendor) < 1) - errx(1, "invalid disk name"); - part = bd.bd_vendor[strlen(bd.bd_vendor) - 1]; - if (part < 'a' || part >= 'a' + MAXPARTITIONS) - errx(1, "invalid partition %c\n", part); - bd.bd_vendor[strlen(bd.bd_vendor) - 1] = '\0'; - - /* Open this device and check its disklabel. */ - if ((diskfd = opendev(bd.bd_vendor, (nowrite? O_RDONLY:O_RDWR), - OPENDEV_PART, &realdiskdev)) < 0) - err(1, "open: %s", realdiskdev); - - /* Get and check disklabel. */ - if (ioctl(diskfd, DIOCGDINFO, &dl) != 0) - err(1, "disklabel: %s", realdev); - if (dl.d_magic != DISKMAGIC) - err(1, "bad disklabel magic=0x%08x", dl.d_magic); - - /* Warn on unknown disklabel types. */ - if (dl.d_type == 0) - warnx("disklabel type unknown"); - - /* Determine poffset and set symbol value. */ - pp = &dl.d_partitions[part - 'a']; - if (pp->p_offseth != 0) - errx(1, "partition offset too high"); - poffset = pp->p_offset; /* Offset of RAID partition. */ - poffset += SR_BOOT_LOADER_OFFSET; /* SR boot loader area. */ - sym_set_value(pbr_symbols, "_p_offset", poffset); - - if (verbose) - fprintf(stderr, "%s%c: installing boot blocks on %s, " - "part offset %u\n", bd.bd_vendor, part, realdiskdev, - poffset); - - /* Write boot blocks to device. */ - write_bootblocks(diskfd, &dl); - - close(diskfd); -} diff --git a/sys/arch/amd64/stand/installboot/nlist.c b/sys/arch/amd64/stand/installboot/nlist.c deleted file mode 100644 index 65f95a68a6f..00000000000 --- a/sys/arch/amd64/stand/installboot/nlist.c +++ /dev/null @@ -1,312 +0,0 @@ -/* $OpenBSD: nlist.c,v 1.12 2013/10/17 08:02:15 deraadt Exp $ */ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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 REGENTS 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 <sys/types.h> -#include <sys/param.h> -#include <sys/mman.h> -#include <sys/stat.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <a.out.h> /* pulls in nlist.h */ - -#ifdef _NLIST_DO_ELF -#include <elf_abi.h> -#endif - -int __fdnlist(int, struct nlist *); -int __elf_fdnlist(int, struct nlist *); -#ifdef _NLIST_DO_ELF -int __elf_is_okay__(Elf_Ehdr *ehdr); -#endif - -#define ISLAST(p) (p->n_un.n_name == 0 || p->n_un.n_name[0] == 0) - -#ifdef _NLIST_DO_ELF -/* - * __elf_is_okay__ - Determine if ehdr really - * is ELF and valid for the target platform. - * - * WARNING: This is NOT a ELF ABI function and - * as such its use should be restricted. - */ -int -__elf_is_okay__(Elf_Ehdr *ehdr) -{ - int retval = 0; - /* - * We need to check magic, class size, endianess, - * and version before we look at the rest of the - * Elf_Ehdr structure. These few elements are - * represented in a machine independent fashion. - */ - - /* - * We are constructing a 32-bit executable. So we can't - * use the libc nlist.c, which would be upset. Manually - * check for the i386 values for EI_CLASS and e_machine. - */ - - if (IS_ELF(*ehdr) && - ehdr->e_ident[EI_CLASS] == ELFCLASS32 && - ehdr->e_ident[EI_DATA] == ELF_TARG_DATA && - ehdr->e_ident[EI_VERSION] == ELF_TARG_VER) { - - /* Now check the machine dependant header */ - if (ehdr->e_machine == EM_386 && - ehdr->e_version == ELF_TARG_VER) - retval = 1; - } - - return retval; -} - -int -__elf_fdnlist(int fd, struct nlist *list) -{ - struct nlist *p; - caddr_t strtab; - Elf_Off symoff = 0, symstroff = 0; - Elf_Word symsize = 0, symstrsize = 0; - Elf_Sword nent, cc, i; - Elf_Sym sbuf[1024]; - Elf_Sym *s; - Elf_Ehdr ehdr; - Elf_Shdr *shdr = NULL; - Elf_Word shdr_size; - struct stat st; - int usemalloc = 0; - - /* Make sure obj is OK */ - if (pread(fd, &ehdr, sizeof(Elf_Ehdr), (off_t)0) != sizeof(Elf_Ehdr) || - !__elf_is_okay__(&ehdr) || fstat(fd, &st) < 0) - return (-1); - - /* calculate section header table size */ - shdr_size = ehdr.e_shentsize * ehdr.e_shnum; - - /* mmap section header table */ - shdr = (Elf_Shdr *)mmap(NULL, (size_t)shdr_size, PROT_READ, - MAP_SHARED|MAP_FILE, fd, (off_t) ehdr.e_shoff); - if (shdr == MAP_FAILED) { - usemalloc = 1; - if ((shdr = malloc(shdr_size)) == NULL) - return (-1); - - if (pread(fd, shdr, shdr_size, (off_t)ehdr.e_shoff) != shdr_size) { - free(shdr); - return (-1); - } - } - - /* - * Find the symbol table entry and its corresponding - * string table entry. Version 1.1 of the ABI states - * that there is only one symbol table but that this - * could change in the future. - */ - for (i = 0; i < ehdr.e_shnum; i++) { - if (shdr[i].sh_type == SHT_SYMTAB) { - symoff = shdr[i].sh_offset; - symsize = shdr[i].sh_size; - symstroff = shdr[shdr[i].sh_link].sh_offset; - symstrsize = shdr[shdr[i].sh_link].sh_size; - break; - } - } - - /* Flush the section header table */ - if (usemalloc) - free(shdr); - else - munmap((caddr_t)shdr, shdr_size); - - /* - * Map string table into our address space. This gives us - * an easy way to randomly access all the strings, without - * making the memory allocation permanent as with malloc/free - * (i.e., munmap will return it to the system). - */ - if (usemalloc) { - if ((strtab = malloc(symstrsize)) == NULL) - return (-1); - if (pread(fd, strtab, symstrsize, (off_t)symstroff) != symstrsize) { - free(strtab); - return (-1); - } - } else { - strtab = mmap(NULL, (size_t)symstrsize, PROT_READ, - MAP_SHARED|MAP_FILE, fd, (off_t) symstroff); - if (strtab == MAP_FAILED) - return (-1); - } - /* - * clean out any left-over information for all valid entries. - * Type and value defined to be 0 if not found; historical - * versions cleared other and desc as well. Also figure out - * the largest string length so don't read any more of the - * string table than we have to. - * - * XXX clearing anything other than n_type and n_value violates - * the semantics given in the man page. - */ - nent = 0; - for (p = list; !ISLAST(p); ++p) { - p->n_type = 0; - p->n_other = 0; - p->n_desc = 0; - p->n_value = 0; - ++nent; - } - - /* Don't process any further if object is stripped. */ - /* ELFism - dunno if stripped by looking at header */ - if (symoff == 0) - goto elf_done; - - while (symsize > 0) { - cc = MIN(symsize, sizeof(sbuf)); - if (pread(fd, sbuf, cc, (off_t)symoff) != cc) - break; - symsize -= cc; - symoff += cc; - for (s = sbuf; cc > 0; ++s, cc -= sizeof(*s)) { - int soff = s->st_name; - - if (soff == 0) - continue; - for (p = list; !ISLAST(p); p++) { - char *sym; - - /* - * First we check for the symbol as it was - * provided by the user. If that fails - * and the first char is an '_', skip over - * the '_' and try again. - * XXX - What do we do when the user really - * wants '_foo' and the are symbols - * for both 'foo' and '_foo' in the - * table and 'foo' is first? - */ - sym = p->n_un.n_name; - if (strcmp(&strtab[soff], sym) != 0 && - (sym[0] != '_' || - strcmp(&strtab[soff], sym + 1) != 0)) - continue; - - p->n_value = s->st_value; - - /* XXX - type conversion */ - /* is pretty rude. */ - switch(ELF_ST_TYPE(s->st_info)) { - case STT_NOTYPE: - switch (s->st_shndx) { - case SHN_UNDEF: - p->n_type = N_UNDF; - break; - case SHN_ABS: - p->n_type = N_ABS; - break; - case SHN_COMMON: - p->n_type = N_COMM; - break; - default: - p->n_type = N_COMM | N_EXT; - break; - } - break; - case STT_OBJECT: - p->n_type = N_DATA; - break; - case STT_FUNC: - p->n_type = N_TEXT; - break; - case STT_FILE: - p->n_type = N_FN; - break; - } - if (ELF_ST_BIND(s->st_info) == - STB_LOCAL) - p->n_type = N_EXT; - p->n_desc = 0; - p->n_other = 0; - if (--nent <= 0) - break; - } - } - } -elf_done: - if (usemalloc) - free(strtab); - else - munmap(strtab, symstrsize); - return (nent); -} -#endif /* _NLIST_DO_ELF */ - - -static struct nlist_handlers { - int (*fn)(int fd, struct nlist *list); -} nlist_fn[] = { -#ifdef _NLIST_DO_ELF - { __elf_fdnlist }, -#endif -}; - -int -__fdnlist(int fd, struct nlist *list) -{ - int n = -1, i; - - for (i = 0; i < sizeof(nlist_fn)/sizeof(nlist_fn[0]); i++) { - n = (nlist_fn[i].fn)(fd, list); - if (n != -1) - break; - } - return (n); -} - - -int -nlist(const char *name, struct nlist *list) -{ - int fd, n; - - fd = open(name, O_RDONLY, 0); - if (fd < 0) - return (-1); - n = __fdnlist(fd, list); - (void)close(fd); - return (n); -} |