diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2011-07-05 17:38:55 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2011-07-05 17:38:55 +0000 |
commit | 5c445af1674ad181574daa345a1b7584e6e0a194 (patch) | |
tree | 5018a3160f744b14158821dbda75d2a4825fae99 /sys | |
parent | 4dfc91bbef932df5e9fa91333245d21bb446cfec (diff) |
More non-512-byte sector groundwork. Don't let disklabel hint that
a ffs frag size can be less than the d_secsize of the disk. Make
sure amd64 writedisklabel() puts the disklabel where readdoslabel()
will read it. Tweak i386/amd64 installboot/biosboot so sectors are
indeed used where sectors are claimed.
Lets me fdisk, newfs, mount and installboot onto 2048 and 4096
byte sector devices. Other filesystem utilites will still hold
surprises.
Note that actually booting from such devices will await BIOSen that
acknowledge such devices as bootable.
ok guenther@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/amd64/disksubr.c | 9 | ||||
-rw-r--r-- | sys/arch/amd64/stand/biosboot/biosboot.S | 6 | ||||
-rw-r--r-- | sys/arch/amd64/stand/installboot/installboot.c | 45 | ||||
-rw-r--r-- | sys/arch/i386/stand/biosboot/biosboot.S | 6 | ||||
-rw-r--r-- | sys/arch/i386/stand/installboot/installboot.c | 49 |
5 files changed, 83 insertions, 32 deletions
diff --git a/sys/arch/amd64/amd64/disksubr.c b/sys/arch/amd64/amd64/disksubr.c index 61808336522..f6988fa3d3d 100644 --- a/sys/arch/amd64/amd64/disksubr.c +++ b/sys/arch/amd64/amd64/disksubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disksubr.c,v 1.61 2011/04/16 03:21:15 krw Exp $ */ +/* $OpenBSD: disksubr.c,v 1.62 2011/07/05 17:38:54 krw Exp $ */ /* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */ /* @@ -122,6 +122,7 @@ int writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp) { int error = EIO, partoff = -1; + int offset; struct disklabel *dlp; struct buf *bp = NULL; @@ -133,15 +134,15 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp) goto done; /* Read it in, slap the new label in, and write it back out */ - bp->b_blkno = partoff + LABELSECTOR; - bp->b_bcount = lp->d_secsize; + bp->b_blkno = DL_BLKTOSEC(lp, partoff+LABELSECTOR) * DL_BLKSPERSEC(lp); + offset = DL_BLKOFFSET(lp, partoff + LABELSECTOR) + LABELOFFSET; CLR(bp->b_flags, B_READ | B_WRITE | B_DONE); SET(bp->b_flags, B_BUSY | B_READ | B_RAW); (*strat)(bp); if ((error = biowait(bp)) != 0) goto done; - dlp = (struct disklabel *)(bp->b_data + LABELOFFSET); + dlp = (struct disklabel *)(bp->b_data + offset); *dlp = *lp; CLR(bp->b_flags, B_READ | B_WRITE | B_DONE); SET(bp->b_flags, B_BUSY | B_WRITE | B_RAW); diff --git a/sys/arch/amd64/stand/biosboot/biosboot.S b/sys/arch/amd64/stand/biosboot/biosboot.S index e3dcbd147f4..0042a89ee36 100644 --- a/sys/arch/amd64/stand/biosboot/biosboot.S +++ b/sys/arch/amd64/stand/biosboot/biosboot.S @@ -1,4 +1,4 @@ -/* $OpenBSD: biosboot.S,v 1.6 2010/07/09 17:36:38 deraadt Exp $ */ +/* $OpenBSD: biosboot.S,v 1.7 2011/07/05 17:38:54 krw Exp $ */ /* * Copyright (c) 2003 Tobias Weingartner @@ -91,8 +91,8 @@ * where we load the block to.) * fs_bsize_p uint16 the filesystem block size _in paragraphs_ * (i.e. fs_bsize / 16) - * fs_bsize_s uint16 the number of 512-byte sectors in a filesystem - * block (i.e. fs_bsize / 512). Directly written + * fs_bsize_s uint16 the number of disk sectors in a filesystem + * block (i.e. fs_bsize / d_secsize). Directly written * into the LBA command block, at lba_count. * XXX LIMITED TO 127 BY PHOENIX EDD SPEC. * fsbtodb uint8 shift count to convert filesystem blocks to diff --git a/sys/arch/amd64/stand/installboot/installboot.c b/sys/arch/amd64/stand/installboot/installboot.c index 6f1dd7ee291..1877b07bbdd 100644 --- a/sys/arch/amd64/stand/installboot/installboot.c +++ b/sys/arch/amd64/stand/installboot/installboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: installboot.c,v 1.20 2011/07/03 19:21:48 krw Exp $ */ +/* $OpenBSD: installboot.c,v 1.21 2011/07/05 17:38:54 krw Exp $ */ /* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ /* @@ -215,6 +215,7 @@ 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. */ @@ -240,7 +241,7 @@ write_bootblocks(int devfd, struct disklabel *dl) errx(1, "no OpenBSD partition"); } - if (start + (protosize / DEV_BSIZE) > BOOTBIOS_MAXSEC) + if (start + (protosize / dl->d_secsize) > BOOTBIOS_MAXSEC) errx(1, "invalid location: all of /boot must be < sector %u.", BOOTBIOS_MAXSEC); @@ -248,9 +249,13 @@ write_bootblocks(int devfd, struct disklabel *dl) fprintf(stderr, "/boot will be written at sector %u\n", start); if (!nowrite) { - if (lseek(devfd, (off_t)start * dl->d_secsize, SEEK_SET) < 0 || - write(devfd, protostore, protosize) != protosize) + 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); } } @@ -261,6 +266,7 @@ findopenbsd(int devfd, struct disklabel *dl) 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: @@ -277,9 +283,12 @@ again: (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, &mbr, sizeof(mbr)) != sizeof(mbr)) + 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", @@ -477,7 +486,8 @@ getbootparams(char *boot, int devfd, struct disklabel *dl) close(fd); /* Read superblock. */ - devread(devfd, sblock, pp->p_offset + SBLOCK, SBSIZE, "superblock"); + devread(devfd, sblock, DL_SECTOBLK(dl, pp->p_offset) + SBLOCK, + SBSIZE, "superblock"); fs = (struct fs *)sblock; /* Sanity-check super-block. */ @@ -492,7 +502,8 @@ getbootparams(char *boot, int devfd, struct disklabel *dl) blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino)); - devread(devfd, buf, pp->p_offset + blk, fs->fs_bsize, "inode"); + devread(devfd, buf, DL_SECTOBLK(dl, pp->p_offset) + blk, + fs->fs_bsize, "inode"); ip = (struct ufs1_dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); /* @@ -508,8 +519,21 @@ getbootparams(char *boot, int devfd, struct disklabel *dl) * (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 / 512)); - sym_set_value(pbr_symbols, "_fsbtodb", fs->fs_fsbtodb); + 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); + sym_set_value(pbr_symbols, "_p_offset", pp->p_offset); sym_set_value(pbr_symbols, "_inodeblk", ino_to_fsba(fs, statbuf.st_ino)); @@ -523,7 +547,8 @@ getbootparams(char *boot, int devfd, struct disklabel *dl) boot, ndb, fs->fs_bsize); fprintf(stderr, "fs block shift %u; part offset %u; " "inode block %lld, offset %u\n", - fs->fs_fsbtodb, pp->p_offset, + ffs(fs->fs_fsize / dl->d_secsize) - 1, + pp->p_offset, ino_to_fsba(fs, statbuf.st_ino), (unsigned int)((((char *)ap) - buf) + INODEOFF)); } diff --git a/sys/arch/i386/stand/biosboot/biosboot.S b/sys/arch/i386/stand/biosboot/biosboot.S index cd6e7f90341..36ccd54d53f 100644 --- a/sys/arch/i386/stand/biosboot/biosboot.S +++ b/sys/arch/i386/stand/biosboot/biosboot.S @@ -1,4 +1,4 @@ -/* $OpenBSD: biosboot.S,v 1.40 2009/09/30 19:03:17 weingart Exp $ */ +/* $OpenBSD: biosboot.S,v 1.41 2011/07/05 17:38:54 krw Exp $ */ /* * Copyright (c) 2003 Tobias Weingartner @@ -91,8 +91,8 @@ * where we load the block to.) * fs_bsize_p uint16 the filesystem block size _in paragraphs_ * (i.e. fs_bsize / 16) - * fs_bsize_s uint16 the number of 512-byte sectors in a filesystem - * block (i.e. fs_bsize / 512). Directly written + * fs_bsize_s uint16 the number of disk sectors in a filesystem + * block (i.e. fs_bsize / d_secsize). Directly written * into the LBA command block, at lba_count. * XXX LIMITED TO 127 BY PHOENIX EDD SPEC. * fsbtodb uint8 shift count to convert filesystem blocks to diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c index 3d88a929471..cf43ed3a60e 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.63 2011/07/03 19:21:48 krw Exp $ */ +/* $OpenBSD: installboot.c,v 1.64 2011/07/05 17:38:54 krw Exp $ */ /* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ /* @@ -211,6 +211,7 @@ 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. */ @@ -236,7 +237,7 @@ write_bootblocks(int devfd, struct disklabel *dl) errx(1, "no OpenBSD partition"); } - if (start + (protosize / DEV_BSIZE) > BOOTBIOS_MAXSEC) + if (start + (protosize / dl->d_secsize) > BOOTBIOS_MAXSEC) errx(1, "invalid location: all of /boot must be < sector %u.", BOOTBIOS_MAXSEC); @@ -244,9 +245,13 @@ write_bootblocks(int devfd, struct disklabel *dl) fprintf(stderr, "/boot will be written at sector %u\n", start); if (!nowrite) { - if (lseek(devfd, (off_t)start * dl->d_secsize, SEEK_SET) < 0 || - write(devfd, protostore, protosize) != protosize) + 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); } } @@ -257,6 +262,7 @@ findopenbsd(int devfd, struct disklabel *dl) 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: @@ -273,9 +279,12 @@ again: (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, &mbr, sizeof(mbr)) != sizeof(mbr)) + 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", @@ -473,7 +482,8 @@ getbootparams(char *boot, int devfd, struct disklabel *dl) close(fd); /* Read superblock. */ - devread(devfd, sblock, pp->p_offset + SBLOCK, SBSIZE, "superblock"); + devread(devfd, sblock, DL_SECTOBLK(dl, pp->p_offset) + SBLOCK, + SBSIZE, "superblock"); fs = (struct fs *)sblock; /* Sanity-check super-block. */ @@ -488,7 +498,8 @@ getbootparams(char *boot, int devfd, struct disklabel *dl) blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino)); - devread(devfd, buf, pp->p_offset + blk, fs->fs_bsize, "inode"); + devread(devfd, buf, DL_SECTOBLK(dl, pp->p_offset) + blk, + fs->fs_bsize, "inode"); ip = (struct ufs1_dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); /* @@ -504,8 +515,21 @@ getbootparams(char *boot, int devfd, struct disklabel *dl) * (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 / 512)); - sym_set_value(pbr_symbols, "_fsbtodb", fs->fs_fsbtodb); + 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); + sym_set_value(pbr_symbols, "_p_offset", pp->p_offset); sym_set_value(pbr_symbols, "_inodeblk", ino_to_fsba(fs, statbuf.st_ino)); @@ -518,10 +542,11 @@ getbootparams(char *boot, int devfd, struct disklabel *dl) fprintf(stderr, "%s is %d blocks x %d bytes\n", boot, ndb, fs->fs_bsize); fprintf(stderr, "fs block shift %u; part offset %u; " - "inode block %lld, offset %ld\n", - fs->fs_fsbtodb, pp->p_offset, + "inode block %lld, offset %u\n", + ffs(fs->fs_fsize / dl->d_secsize) - 1, + pp->p_offset, ino_to_fsba(fs, statbuf.st_ino), - ((((char *)ap) - buf) + INODEOFF)); + (unsigned int)((((char *)ap) - buf) + INODEOFF)); } return 0; |