diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1997-05-05 06:02:04 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1997-05-05 06:02:04 +0000 |
commit | 3d10bc794d2e03421fd174136259f42a03004bca (patch) | |
tree | d1b03f69e85167322eb9804fa9e85237ce45b7f1 /sys/arch/alpha/stand/installboot.c | |
parent | 53e6b51c98a2cae3f0e7c41c03a85f76fcd17341 (diff) |
Updates from NetBSD (cgd):
- seriously clean up makefiles. use libsa/libkern/libz as appropriate,
and don't build the various sources into objs locally by specifying
them directly in the Makefiles.
- move the secondary bootstrap down (to 0x20004000), and add a HEAP_LIMIT
so that we don't exhaust our bootstrap address space (when using the new,
not yet checked in, memory allocator).
- clean up installboot, deal with secondary bootstrap programs not on
'a' partition or 'a' partition not starting at 0.
- add padding to structures in bbinfo.h for future expansion. Add a
netbbinfo structure to allow netboot information to be hard-coded in
network boot blocks, so that they can be made to work even on systems
with firmware which doesn't support the new "ethernet address in boot
device" convention.
- move the sync() calls to the correct place in installboot.c
- remove a kludge in disk.c which was breaking multiple opens/closes
of the disk
- allow netboot ethernet address to be hard-coded into binary so that
machines with old firmware which doesn't pass it in the boot device
can work. Assume that if the ethernet address isn't passed in, it
uses the old (dain-bramaged) 'read' interface works on my 3000/300LX.
- Add setnetbootinfo, a program to hard code an ethernet address into
a network boot.
- move an 'int debug;' into boot.c (it was the only diff between boot.c and
netboot.c), and nuke netboot.c (using boot.c instead for net boot blocks).
- add cd9660 file system ops to the file system ops table in filesystem.c
- if a file name is given (i.e. BOOTED_FILE) is set, boot only that file,
but if not then try to boot "bsd", "bsd.bak", "bsd.old", and
"obsd" (in that order) until one is found or until the list of names
is exhausted.
- add support for reading gzipped kernels.
- use strerror() to print errors, rather than just printing error numbers
- if no disk label exists, fake one up
- slightly relax the block size checks in bootxx.c; they were a bit to paranoid
And local changes:
- don't build a copy of libsa/libkern/libz for each boot prog,
just build a single copy and use it for everything.
Diffstat (limited to 'sys/arch/alpha/stand/installboot.c')
-rw-r--r-- | sys/arch/alpha/stand/installboot.c | 104 |
1 files changed, 74 insertions, 30 deletions
diff --git a/sys/arch/alpha/stand/installboot.c b/sys/arch/alpha/stand/installboot.c index 49eb5d85b2a..c01835023a6 100644 --- a/sys/arch/alpha/stand/installboot.c +++ b/sys/arch/alpha/stand/installboot.c @@ -1,7 +1,8 @@ -/* $OpenBSD: installboot.c,v 1.6 1997/04/09 05:09:35 deraadt Exp $ */ -/* $NetBSD: installboot.c,v 1.2 1995/12/20 00:17:49 cgd Exp $ */ +/* $OpenBSD: installboot.c,v 1.7 1997/05/05 06:01:48 millert Exp $ */ +/* $NetBSD: installboot.c,v 1.2 1997/04/06 08:41:12 cgd Exp $ */ /* + * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. * Copyright (c) 1994 Paul Kranenburg * All rights reserved. * @@ -39,12 +40,16 @@ #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> +#include <sys/disklabel.h> +#include <sys/dkio.h> #include <err.h> +#include <errno.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> +#include <util.h> #include "bbinfo.h" @@ -57,7 +62,7 @@ int max_block_count; char *loadprotoblocks __P((char *, long *)); -int loadblocknums __P((char *, int)); +int loadblocknums __P((char *, int, unsigned long)); static void devread __P((int, void *, daddr_t, size_t, char *)); static void usage __P((void)); int main __P((int, char *[])); @@ -66,7 +71,7 @@ int main __P((int, char *[])); static void usage() { - fprintf(stderr, + (void)fprintf(stderr, "usage: installboot [-n] [-v] <boot> <proto> <device>\n"); exit(1); } @@ -82,8 +87,11 @@ main(argc, argv) long protosize; int mib[2]; size_t size; + struct stat disksb, bootsb; + struct disklabel dl; + unsigned long partoffset; - while ((c = getopt(argc, argv, "vn")) != -1) { + while ((c = getopt(argc, argv, "vn")) != EOF) { switch (c) { case 'n': /* Do not actually write the bootblock to disk */ @@ -107,9 +115,9 @@ main(argc, argv) dev = argv[optind + 2]; if (verbose) { - printf("boot: %s\n", boot); - printf("proto: %s\n", proto); - printf("device: %s\n", dev); + (void)printf("boot: %s\n", boot); + (void)printf("proto: %s\n", proto); + (void)printf("device: %s\n", dev); } /* Load proto blocks into core */ @@ -119,9 +127,46 @@ main(argc, argv) /* Open and check raw disk device */ if ((devfd = open(dev, O_RDONLY, 0)) < 0) err(1, "open: %s", dev); + if (fstat(devfd, &disksb) == -1) + err(1, "fstat: %s", dev); + if (!S_ISCHR(disksb.st_mode)) + errx(1, "%s must be a character device node", dev); + if ((minor(disksb.st_rdev) % getmaxpartitions()) != getrawpartition()) + errx(1, "%s must be the raw partition", dev); /* Extract and load block numbers */ - if (loadblocknums(boot, devfd) != 0) + if (stat(boot, &bootsb) == -1) + err(1, "stat: %s", boot); + if (!S_ISREG(bootsb.st_mode)) + errx(1, "%s must be a regular file", boot); + if ((minor(disksb.st_rdev) / getmaxpartitions()) != + (minor(bootsb.st_dev) / getmaxpartitions())) + errx(1, "%s must be somewhere on %s", boot, dev); + + /* + * Find the offset of the secondary boot block's partition + * into the disk. If disklabels not supported, assume zero. + */ + if (ioctl(devfd, DIOCGDINFO, &dl) != -1) { + partoffset = dl.d_partitions[minor(bootsb.st_dev) % + getmaxpartitions()].p_offset; + } else { + if (errno != ENOTTY) + err(1, "read disklabel: %s", dev); + warnx("couldn't read label from %s, using part offset of 0", + dev); + partoffset = 0; + } + if (verbose) + (void)printf("%s partition offset = 0x%lx\n", boot, partoffset); + + /* Sync filesystems (make sure boot's block numbers are stable) */ + sync(); + sleep(2); + sync(); + sleep(2); + + if (loadblocknums(boot, devfd, partoffset) != 0) exit(1); (void)close(devfd); @@ -141,10 +186,6 @@ main(argc, argv) if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE) err(1, "lseek bootstrap"); - /* Sync filesystems (to clean in-memory superblock?) */ - sync(); - sleep(3); - if (write(devfd, protostore, protosize) != protosize) err(1, "write bootstrap"); @@ -249,11 +290,11 @@ loadprotoblocks(fname, size) ((char *)bbinfop->blocks - bp) / sizeof (bbinfop->blocks[0]); if (verbose) { - printf("boot block info locator at offset 0x%x\n", + (void)printf("boot block info locator at offset 0x%x\n", (char *)bbinfolocp - bp); - printf("boot block info at offset 0x%x\n", + (void)printf("boot block info at offset 0x%x\n", (char *)bbinfop - bp); - printf("max number of blocks: %d\n", max_block_count); + (void)printf("max number of blocks: %d\n", max_block_count); } *size = sz; @@ -278,9 +319,10 @@ devread(fd, buf, blk, size, msg) static char sblock[SBSIZE]; int -loadblocknums(boot, devfd) -char *boot; -int devfd; +loadblocknums(boot, devfd, partoffset) + char *boot; + int devfd; + unsigned long partoffset; { int i, fd; struct stat statbuf; @@ -314,7 +356,8 @@ int devfd; close(fd); /* Read superblock */ - devread(devfd, sblock, btodb(SBOFF), SBSIZE, "superblock"); + devread(devfd, sblock, btodb(SBOFF) + partoffset, SBSIZE, + "superblock"); fs = (struct fs *)sblock; /* Read inode */ @@ -322,7 +365,7 @@ int devfd; errx(1, "No memory for filesystem block"); blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino)); - devread(devfd, buf, blk, fs->fs_bsize, "inode"); + devread(devfd, buf, blk + partoffset, fs->fs_bsize, "inode"); ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); /* @@ -343,16 +386,16 @@ int devfd; bbinfop->nblocks = ndb; if (verbose) - printf("%s: block numbers: ", boot); + (void)printf("%s: block numbers: ", boot); ap = ip->di_db; for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) { blk = fsbtodb(fs, *ap); - bbinfop->blocks[i] = blk; + bbinfop->blocks[i] = blk + partoffset; if (verbose) - printf("%d ", blk); + (void)printf("%d ", bbinfop->blocks[i]); } if (verbose) - printf("\n"); + (void)printf("\n"); if (ndb == 0) goto checksum; @@ -362,18 +405,19 @@ int devfd; * for more in the 1st-level bootblocks anyway. */ if (verbose) - printf("%s: block numbers (indirect): ", boot); + (void)printf("%s: block numbers (indirect): ", boot); blk = ip->di_ib[0]; - devread(devfd, buf, blk, fs->fs_bsize, "indirect block"); + devread(devfd, buf, blk + partoffset, fs->fs_bsize, + "indirect block"); ap = (daddr_t *)buf; for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) { blk = fsbtodb(fs, *ap); - bbinfop->blocks[i] = blk; + bbinfop->blocks[i] = blk + partoffset; if (verbose) - printf("%d ", blk); + (void)printf("%d ", bbinfop->blocks[i]); } if (verbose) - printf("\n"); + (void)printf("\n"); if (ndb) errx(1, "%s: Too many blocks", boot); |