summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1997-07-17 22:47:02 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1997-07-17 22:47:02 +0000
commit782358f5848c44a73d9932732b56e706785ef04a (patch)
treebe48c8d4f2f719900a988e593da83df697d9d9a4
parent9994ddc59828d8c799efe18598bef2f308ef3237 (diff)
take partition in an account
add -h -s, to fake BIOS geometry
-rw-r--r--sys/arch/i386/stand/installboot/installboot.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c
index 4fcd13b620b..43c3d50ac0b 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.3 1997/03/31 23:06:24 mickey Exp $ */
+/* $OpenBSD: installboot.c,v 1.4 1997/07/17 22:47:01 mickey Exp $ */
/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
/*
@@ -50,7 +50,7 @@
#include <string.h>
#include <unistd.h>
-int verbose, nowrite;
+int verbose, nowrite, heads, nsectors;
char *boot, *proto, *dev;
struct nlist nl[] = {
#define X_BLOCK_COUNT 0
@@ -89,9 +89,17 @@ main(argc, argv)
int devfd;
char *protostore;
long protosize;
+ struct stat sb;
- while ((c = getopt(argc, argv, "vn")) != EOF) {
+ nsectors = heads = -1;
+ while ((c = getopt(argc, argv, "vnh:s:")) != EOF) {
switch (c) {
+ case 'h':
+ heads = atoi(optarg);
+ break;
+ case 's':
+ nsectors = atoi(optarg);
+ break;
case 'n':
/* Do not actually write the bootblock to disk */
nowrite = 1;
@@ -131,6 +139,12 @@ main(argc, argv)
if ((devfd = open(dev, O_RDONLY, 0)) < 0)
err(1, "open: %s", dev);
+ if (fstat(devfd, &sb) < 0)
+ err(1, "stat: %s", dev);
+
+ if (!S_ISCHR(sb.st_mode))
+ errx(1, "%s: Not a character device", dev);
+
/* Extract and load block numbers */
if (loadblocknums(boot, devfd) != 0)
exit(1);
@@ -261,13 +275,14 @@ static char sblock[SBSIZE];
int
loadblocknums(boot, devfd)
-char *boot;
-int devfd;
+ char *boot;
+ int devfd;
{
int i, fd;
struct stat statbuf;
struct statfs statfsbuf;
struct disklabel dl;
+ struct partition *pl;
struct fs *fs;
char *buf;
daddr_t blk, *ap;
@@ -291,6 +306,12 @@ int devfd;
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);
@@ -346,25 +367,31 @@ int devfd;
printf("Will load %d blocks of size %d each.\n",
ndb, fs->fs_bsize);
+ /* adjust disklabel w/ synthetic geometry */
+ if (nsectors > 0)
+ dl.d_nsectors = nsectors;
+ if (heads > 0)
+ dl.d_secpercyl = dl.d_nsectors * heads;
+
/*
* Get the block numbers; we don't handle fragments
*/
ap = ip->di_db;
bt = block_table_p;
for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--)
- bt += record_block(bt, fsbtodb(fs, *ap),
+ bt += record_block(bt, pl->p_offset + fsbtodb(fs, *ap),
fs->fs_bsize / 512, &dl);
if (ndb != 0) {
/*
* Just one level of indirections; there isn't much room
- * for more in the 1st-level bootblocks anyway.
+ * for more in the 2nd-level /boot anyway.
*/
blk = fsbtodb(fs, ip->di_ib[0]);
devread(devfd, buf, blk, fs->fs_bsize, "indirect block");
ap = (daddr_t *)buf;
for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--)
- bt += record_block(bt, fsbtodb(fs, *ap),
+ bt += record_block(bt, pl->p_offset + fsbtodb(fs, *ap),
fs->fs_bsize / 512, &dl);
}