diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1997-08-29 20:08:37 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1997-08-29 20:08:37 +0000 |
commit | d2be13a4e52195fbd332e83a2cb6fd4806ddbea2 (patch) | |
tree | 7aed499842f99510a57c9453d600f0f5660edc2b /sys/arch | |
parent | b6f6f56147a65161b228a38652ef442ae8f0941a (diff) |
install on raw partition
accept short device names (ie sd0)
print -v output on stderr
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/stand/installboot/installboot.c | 151 |
1 files changed, 86 insertions, 65 deletions
diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c index a1a068c5bd3..3dfaa3164c9 100644 --- a/sys/arch/i386/stand/installboot/installboot.c +++ b/sys/arch/i386/stand/installboot/installboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: installboot.c,v 1.6 1997/08/23 14:31:49 mickey Exp $ */ +/* $OpenBSD: installboot.c,v 1.7 1997/08/29 20:08:36 mickey Exp $ */ /* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ /* @@ -56,9 +56,10 @@ #include <stdio.h> #include <string.h> #include <unistd.h> +#include <util.h> int verbose, nowrite, heads, nsectors; -char *boot, *proto, *dev; +char *boot, *proto, *dev, *realdev; struct nlist nl[] = { #define X_BLOCK_COUNT 0 {{"_block_count"}}, @@ -69,14 +70,14 @@ struct nlist nl[] = { u_int8_t *block_count_p; /* block count var. in prototype image */ u_int8_t *block_table_p; /* block number array in prototype image */ -int maxblocknum; /* size of this array */ +int maxblocknum; /* size of this array */ #ifdef CPU_BIOSDEV int biosdev; #endif char *loadprotoblocks __P((char *, long *)); -int loadblocknums __P((char *, int)); +int loadblocknums __P((char *, int, struct disklabel *)); static void devread __P((int, void *, daddr_t, size_t, char *)); static void usage __P((void)); static int record_block @@ -100,6 +101,9 @@ main(argc, argv) char *protostore; long protosize; struct stat sb; + struct disklabel dl; + struct dos_mbr mbr; + struct dos_partition *dp; nsectors = heads = -1; while ((c = getopt(argc, argv, "vnh:s:")) != EOF) { @@ -129,13 +133,7 @@ main(argc, argv) boot = argv[optind]; proto = argv[optind + 1]; - dev = argv[optind + 2]; - - if (verbose) { - printf("boot: %s\n", boot); - printf("proto: %s\n", proto); - printf("device: %s\n", dev); - } + realdev = dev = argv[optind + 2]; #ifdef CPU_BIOSDEV if (heads == -1 || nsectors == -1) { @@ -163,6 +161,24 @@ main(argc, argv) } #endif + /* Open and check 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\n", boot); + fprintf(stderr, "proto: %s\n", proto); + fprintf(stderr, "device: %s\n", realdev); + } + + if (ioctl(devfd, DIOCGDINFO, &dl) != 0) + err(1, "disklabel: %s", realdev); + + /* check disklabel */ + if (dl.d_magic != DISKMAGIC) + err(1, "bad disklabel magic=%0x8x", dl.d_magic); + /* Load proto blocks into core */ if ((protostore = loadprotoblocks(proto, &protosize)) == NULL) exit(1); @@ -171,38 +187,53 @@ main(argc, argv) if (protosize & (DEV_BSIZE - 1)) err(1, "proto bootblock bad size=%ld", protosize); - /* Open and check raw disk device */ - if ((devfd = open(dev, O_RDONLY, 0)) < 0) - err(1, "open: %s", dev); + /* Write patched proto bootblocks into the superblock */ + if (protosize > SBSIZE - DEV_BSIZE) + errx(1, "proto bootblocks too big"); if (fstat(devfd, &sb) < 0) - err(1, "stat: %s", dev); + err(1, "stat: %s", realdev); if (!S_ISCHR(sb.st_mode)) - errx(1, "%s: Not a character device", dev); + errx(1, "%s: Not a character device", realdev); /* Extract and load block numbers */ - if (loadblocknums(boot, devfd) != 0) + if (loadblocknums(boot, devfd, &dl) != 0) exit(1); - (void)close(devfd); - - if (nowrite) - return 0; - - /* Write patched proto bootblocks into the superblock */ - if (protosize > SBSIZE - DEV_BSIZE) - errx(1, "proto bootblocks too big"); - - if ((devfd = open(dev, (nowrite? O_RDONLY:O_RDWR), 0)) < 0) - err(1, "open: %s", dev); - /* Sync filesystems (to clean in-memory superblock?) */ - sync(); + sync(); sleep(1); + + if (lseek(devfd, (off_t)DOSBBSECTOR, SEEK_SET) < 0 || + read(devfd, &mbr, sizeof(mbr)) < sizeof(mbr)) + err(4, "can't read master boot record"); + + if (mbr.dmbr_sign != DOSMBR_SIGNATURE) + errx(1, "broken MBR"); + + /* Find OpenBSD partition. */ + for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART]; dp++) { + if (dp->dp_size && dp->dp_typ == DOSPTYP_OPENBSD) { + fprintf(stderr, "using MBR partition %d: " + "type %d (0x%02x) offset %d (0x%x)\n", + dp - mbr.dmbr_parts, + dp->dp_typ, dp->dp_typ, + dp->dp_start, dp->dp_start); + break; + } + } + /* don't check for old part number, that is ;-p */ + if (dp >= &mbr.dmbr_parts[NDOSPART]) + errx(1, "no OpenBSD partition"); + + if (!nowrite) { + if (lseek(devfd, dp->dp_start * dl.d_secsize, SEEK_SET) < 0 || + write(devfd, protostore, protosize) != protosize) + err(1, "write bootstrap"); + } - if (write(devfd, protostore, protosize) != protosize) - err(1, "write bootstrap"); (void)close(devfd); + return 0; } @@ -275,9 +306,9 @@ loadprotoblocks(fname, size) maxblocknum = *block_count_p; if (verbose) { - printf("%s: entry point %#lx\n", fname, eh.a_entry); - printf("proto bootblock size %ld\n", *size); - printf("room for %d filesystem blocks at %#lx\n", + fprintf(stderr, "%s: entry point %#lx\n", fname, eh.a_entry); + fprintf(stderr, "proto bootblock size %ld\n", *size); + fprintf(stderr, "room for %d filesystem blocks at %#lx\n", maxblocknum, nl[X_BLOCK_TABLE].n_value); } @@ -310,14 +341,14 @@ devread(fd, buf, blk, size, msg) static char sblock[SBSIZE]; int -loadblocknums(boot, devfd) +loadblocknums(boot, devfd, dl) char *boot; int devfd; + struct disklabel *dl; { int i, fd; struct stat statbuf; struct statfs statfsbuf; - struct disklabel dl; struct partition *pl; struct fs *fs; char *buf; @@ -335,19 +366,6 @@ loadblocknums(boot, devfd) /* Make sure the (probably new) boot file is on disk. */ sync(); sleep(1); - if (ioctl(devfd, DIOCGDINFO, &dl) != 0) - err(1, "disklabel: %s", dev); - - /* check disklabel */ - if (dl.d_magic != DISKMAGIC) - err(1, "bad disklabel magic=%0x8x", dl.d_magic); - - /* get partition pointer */ - if (fstat(devfd, &statbuf) < 0) - err(1, "stat: %s", dev); - - pl = &dl.d_partitions[DISKPART(statbuf.st_rdev)]; - if ((fd = open(boot, O_RDONLY)) < 0) err(1, "open: %s", boot); @@ -373,10 +391,11 @@ loadblocknums(boot, devfd) if (fstat(fd, &statbuf) != 0) err(1, "fstat: %s", boot); + pl = &dl->d_partitions[DISKPART(statbuf.st_dev)]; close(fd); /* Read superblock */ - devread(devfd, sblock, SBLOCK, SBSIZE, "superblock"); + devread(devfd, sblock, pl->p_offset + SBLOCK, SBSIZE, "superblock"); fs = (struct fs *)sblock; /* Sanity-check super-block. */ @@ -390,7 +409,7 @@ loadblocknums(boot, 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, pl->p_offset + blk, fs->fs_bsize, "inode"); ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); /* @@ -400,15 +419,15 @@ loadblocknums(boot, devfd) if (ndb > maxblocknum) errx(1, "Too many blocks"); if (verbose) - printf("Will load %d blocks of size %d each.\n", - ndb, fs->fs_bsize); + fprintf(stderr, "Will load %d blocks of size %d each.\n", + ndb, fs->fs_bsize); - if (dl.d_type != 0 && dl.d_type < DTYPE_FLOPPY) { + if (dl->d_type != 0 && dl->d_type < DTYPE_FLOPPY) { /* adjust disklabel w/ synthetic geometry */ if (nsectors > 0) - dl.d_nsectors = nsectors; + dl->d_nsectors = nsectors; if (heads > 0) - dl.d_secpercyl = dl.d_nsectors * heads; + dl->d_secpercyl = dl->d_nsectors * heads; } /* @@ -418,7 +437,7 @@ loadblocknums(boot, devfd) bt = block_table_p; for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) bt += record_block(bt, pl->p_offset + fsbtodb(fs, *ap), - fs->fs_bsize / 512, &dl); + fs->fs_bsize / 512, dl); if (ndb != 0) { /* @@ -426,21 +445,23 @@ loadblocknums(boot, devfd) * for more in the 2nd-level /boot anyway. */ blk = fsbtodb(fs, ip->di_ib[0]); - devread(devfd, buf, blk, fs->fs_bsize, "indirect block"); + devread(devfd, buf, pl->p_offset + blk, fs->fs_bsize, + "indirect block"); ap = (daddr_t *)buf; for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) bt += record_block(bt, pl->p_offset + fsbtodb(fs, *ap), - fs->fs_bsize / 512, &dl); + fs->fs_bsize / 512, dl); } /* write out remaining piece */ - bt += record_block(bt, 0, 0, &dl); + bt += record_block(bt, 0, 0, dl); /* and again */ - bt += record_block(bt, 0, 0, &dl); + bt += record_block(bt, 0, 0, dl); *block_count_p = (bt - block_table_p) / 4; if (verbose) - printf("%s: %d entries total\n", boot, *block_count_p); + fprintf(stderr, "%s: %d entries total\n", + boot, *block_count_p); return 0; } @@ -479,8 +500,8 @@ record_block(bt, blk, bs, dl) ((c & 0xff) << 8) | ((c & 0x300) >> 2); if (verbose) - printf("%2d: %2d @(%d %d %d) (%d-%d)\n", - i, bt[3], c, bt[2], s, ss, ss + bt[3] - 1); + fprintf(stderr, "%2d: %2d @(%d %d %d) (%d-%d)\n", + i, bt[3], c, bt[2], s, ss, ss + bt[3] - 1); if ((ss % dl->d_nsectors + l) >= dl->d_nsectors) { ss += bt[3]; |