diff options
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/alpha/stand/boot/Makefile | 6 | ||||
-rw-r--r-- | sys/arch/alpha/stand/boot/filesystem.c | 5 | ||||
-rw-r--r-- | sys/arch/alpha/stand/boot/version | 3 | ||||
-rw-r--r-- | sys/arch/alpha/stand/installboot.c | 175 |
4 files changed, 147 insertions, 42 deletions
diff --git a/sys/arch/alpha/stand/boot/Makefile b/sys/arch/alpha/stand/boot/Makefile index 16d551dc373..148193630bb 100644 --- a/sys/arch/alpha/stand/boot/Makefile +++ b/sys/arch/alpha/stand/boot/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.24 2019/10/29 02:55:50 deraadt Exp $ +# $OpenBSD: Makefile,v 1.25 2020/03/11 09:59:31 otto Exp $ # $NetBSD: Makefile,v 1.17 1997/04/17 07:27:46 thorpej Exp $ S= ${.CURDIR}/../../../.. @@ -19,10 +19,10 @@ CLEANFILES+= vers.c vers.o ${PROG}.sym ${PROG}.nosym .PATH: ${S}/lib/libkern/arch/alpha ${S}/lib/libkern SRCS+= __divlu.S __remqu.S __reml.S strlen.c bzero.c __divl.S __divqu.S \ - __remlu.S + __remlu.S __divq.S __remq.S .PATH: ${S}/lib/libkern/arch/alpha ${S}/lib/libsa -SRCS+= loadfile.c arc4.c +SRCS+= loadfile.c arc4.c ufs2.c DEFNS= -DCOMPAT_UFS diff --git a/sys/arch/alpha/stand/boot/filesystem.c b/sys/arch/alpha/stand/boot/filesystem.c index eeb7e1d71ef..c7f16eebfa4 100644 --- a/sys/arch/alpha/stand/boot/filesystem.c +++ b/sys/arch/alpha/stand/boot/filesystem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: filesystem.c,v 1.5 2019/08/03 15:22:19 deraadt Exp $ */ +/* $OpenBSD: filesystem.c,v 1.6 2020/03/11 09:59:31 otto Exp $ */ /* $NetBSD: filesystem.c,v 1.3 1997/04/06 08:40:35 cgd Exp $ */ /* @@ -36,11 +36,14 @@ #include <lib/libsa/stand.h> #include <lib/libsa/ufs.h> +#include <lib/libsa/ufs2.h> #include <lib/libsa/cd9660.h> struct fs_ops file_system[] = { { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat, ufs_readdir, ufs_fchmod }, + { ufs2_open, ufs2_close, ufs2_read, ufs2_write, + ufs2_seek, ufs2_stat, ufs2_readdir, ufs2_fchmod }, { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek, cd9660_stat }, }; diff --git a/sys/arch/alpha/stand/boot/version b/sys/arch/alpha/stand/boot/version index e3c0e52f366..38c842f153b 100644 --- a/sys/arch/alpha/stand/boot/version +++ b/sys/arch/alpha/stand/boot/version @@ -1,4 +1,4 @@ -$OpenBSD: version,v 1.10 2014/02/19 20:52:57 miod Exp $ +$OpenBSD: version,v 1.11 2020/03/11 09:59:31 otto Exp $ $NetBSD: version,v 1.9 1997/01/23 23:10:38 cgd Exp $ 1.1: Initial version @@ -26,3 +26,4 @@ $NetBSD: version,v 1.9 1997/01/23 23:10:38 cgd Exp $ 1.8: Use MI loadfile, warn if kernel image would overlap SRM 1.9: Better PALcode switching sequence 1.10: /etc/random.seed support +1.11: ffs2 support diff --git a/sys/arch/alpha/stand/installboot.c b/sys/arch/alpha/stand/installboot.c index 96f6f2978d4..767b96f7fcd 100644 --- a/sys/arch/alpha/stand/installboot.c +++ b/sys/arch/alpha/stand/installboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: installboot.c,v 1.19 2014/07/12 19:01:49 tedu Exp $ */ +/* $OpenBSD: installboot.c,v 1.20 2020/03/11 09:59:31 otto Exp $ */ /* $NetBSD: installboot.c,v 1.2 1997/04/06 08:41:12 cgd Exp $ */ /* @@ -68,13 +68,17 @@ int max_block_count; char *loadprotoblocks(char *, long *); int loadblocknums(char *, int, unsigned long); -static void devread(int, void *, daddr32_t, size_t, char *); +static void devread(int, void *, daddr_t, size_t, char *); static void usage(void); +static int sbchk(struct fs *, daddr_t); +static void sbread(int, daddr_t, struct fs **, char *); int main(int, char *[]); int isofsblk = 0; int isofseblk = 0; +static const daddr_t sbtry[] = SBLOCKSEARCH; + static void usage(void) { @@ -183,7 +187,7 @@ main(int argc, char *argv[]) sync(); sleep(2); - if (loadblocknums(boot, devfd, partoffset) != 0) + if (loadblocknums(boot, devfd, DL_SECTOBLK(&dl, partoffset)) != 0) exit(1); (void)close(devfd); @@ -302,13 +306,10 @@ loadprotoblocks(char *fname, long *size) } static void -devread(int fd, void *buf, daddr32_t blk, size_t size, char *msg) +devread(int fd, void *buf, daddr_t blk, size_t size, char *msg) { - if (lseek(fd, dbtob(blk), SEEK_SET) != dbtob(blk)) - err(1, "%s: devread: lseek", msg); - - if (read(fd, buf, size) != size) - err(1, "%s: devread: read", msg); + if (pread(fd, buf, size, dbtob((off_t)blk)) != (ssize_t)size) + err(1, "%s: devread: pread", msg); } static char sblock[SBSIZE]; @@ -321,8 +322,10 @@ loadblocknums(char *boot, int devfd, unsigned long partoffset) struct statfs statfsbuf; struct fs *fs; char *buf; - daddr32_t blk, *ap; - struct ufs1_dinode *ip; + daddr32_t *ap1; + daddr_t blk, *ap2; + struct ufs1_dinode *ip1; + struct ufs2_dinode *ip2; int32_t cksum; /* @@ -373,9 +376,7 @@ loadblocknums(char *boot, int devfd, unsigned long partoffset) close(fd); /* Read superblock */ - devread(devfd, sblock, btodb(SBOFF) + partoffset, SBSIZE, - "superblock"); - fs = (struct fs *)sblock; + sbread(devfd, partoffset, &fs, sblock); /* Read inode */ if ((buf = malloc(fs->fs_bsize)) == NULL) @@ -383,19 +384,25 @@ loadblocknums(char *boot, int devfd, unsigned long partoffset) blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino)); devread(devfd, buf, blk + partoffset, fs->fs_bsize, "inode"); - ip = (struct ufs1_dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); - + if (fs->fs_magic == FS_UFS1_MAGIC) { + ip1 = (struct ufs1_dinode *)(buf) + ino_to_fsbo(fs, + statbuf.st_ino); + ndb = howmany(ip1->di_size, fs->fs_bsize); + } else { + ip2 = (struct ufs2_dinode *)(buf) + ino_to_fsbo(fs, + statbuf.st_ino); + ndb = howmany(ip2->di_size, fs->fs_bsize); + } /* - * Register filesystem block size. + * Check the block numbers; we don't handle fragments */ - bbinfop->bsize = fs->fs_bsize; + if (ndb > max_block_count) + errx(1, "%s: Too many blocks", boot); /* - * Get the block numbers; we don't handle fragments + * Register filesystem block size. */ - ndb = howmany(ip->di_size, fs->fs_bsize); - if (ndb > max_block_count) - errx(1, "%s: Too many blocks", boot); + bbinfop->bsize = fs->fs_bsize; /* * Register block count. @@ -404,12 +411,22 @@ loadblocknums(char *boot, int devfd, unsigned long partoffset) if (verbose) (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 + partoffset; - if (verbose) - (void)printf("%d ", bbinfop->blocks[i]); + if (fs->fs_magic == FS_UFS1_MAGIC) { + ap1 = ip1->di_db; + for (i = 0; i < NDADDR && *ap1 && ndb; i++, ap1++, ndb--) { + blk = fsbtodb(fs, *ap1); + bbinfop->blocks[i] = blk + partoffset; + if (verbose) + (void)printf("%d ", bbinfop->blocks[i]); + } + } else { + ap2 = ip2->di_db; + for (i = 0; i < NDADDR && *ap2 && ndb; i++, ap2++, ndb--) { + blk = fsbtodb(fs, *ap2); + bbinfop->blocks[i] = blk + partoffset; + if (verbose) + (void)printf("%d ", bbinfop->blocks[i]); + } } if (verbose) (void)printf("\n"); @@ -423,15 +440,28 @@ loadblocknums(char *boot, int devfd, unsigned long partoffset) */ if (verbose) (void)printf("%s: block numbers (indirect): ", boot); - blk = ip->di_ib[0]; - devread(devfd, buf, blk + partoffset, fs->fs_bsize, - "indirect block"); - ap = (daddr32_t *)buf; - for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) { - blk = fsbtodb(fs, *ap); - bbinfop->blocks[i] = blk + partoffset; - if (verbose) - (void)printf("%d ", bbinfop->blocks[i]); + if (fs->fs_magic == FS_UFS1_MAGIC) { + blk = ip1->di_ib[0]; + devread(devfd, buf, blk + partoffset, fs->fs_bsize, + "indirect block"); + ap1 = (daddr32_t *)buf; + for (; i < NINDIR(fs) && *ap1 && ndb; i++, ap1++, ndb--) { + blk = fsbtodb(fs, *ap1); + bbinfop->blocks[i] = blk + partoffset; + if (verbose) + (void)printf("%d ", bbinfop->blocks[i]); + } + } else { + blk = ip2->di_ib[0]; + devread(devfd, buf, blk + partoffset, fs->fs_bsize, + "indirect block"); + ap2 = (daddr_t *)buf; + for (; i < NINDIR(fs) && *ap2 && ndb; i++, ap2++, ndb--) { + blk = fsbtodb(fs, *ap2); + bbinfop->blocks[i] = blk + partoffset; + if (verbose) + (void)printf("%d ", bbinfop->blocks[i]); + } } if (verbose) (void)printf("\n"); @@ -448,3 +478,74 @@ checksum: return 0; } + +static int +sbchk(struct fs *fs, daddr_t sbloc) +{ + if (verbose) + fprintf(stderr, "looking for superblock at %lld\n", sbloc); + + if (fs->fs_magic != FS_UFS2_MAGIC && fs->fs_magic != FS_UFS1_MAGIC) { + if (verbose) + fprintf(stderr, "bad superblock magic 0x%x\n", + fs->fs_magic); + return (0); + } + + /* + * Looking for an FFS1 file system at SBLOCK_UFS2 will find the + * wrong superblock for file systems with 64k block size. + */ + if (fs->fs_magic == FS_UFS1_MAGIC && sbloc == SBLOCK_UFS2) { + if (verbose) + fprintf(stderr, "skipping ffs1 superblock at %lld\n", + sbloc); + return (0); + } + + if (fs->fs_bsize <= 0 || fs->fs_bsize < sizeof(struct fs) || + fs->fs_bsize > MAXBSIZE) { + if (verbose) + fprintf(stderr, "invalid superblock block size %d\n", + fs->fs_bsize); + return (0); + } + + if (fs->fs_sbsize <= 0 || fs->fs_sbsize > SBSIZE) { + if (verbose) + fprintf(stderr, "invalid superblock size %d\n", + fs->fs_sbsize); + return (0); + } + + if (fs->fs_inopb <= 0) { + if (verbose) + fprintf(stderr, "invalid superblock inodes/block %d\n", + fs->fs_inopb); + return (0); + } + + if (verbose) + fprintf(stderr, "found valid %s superblock\n", + fs->fs_magic == FS_UFS2_MAGIC ? "ffs2" : "ffs1"); + + return (1); +} + +static void +sbread(int fd, daddr_t poffset, struct fs **fs, char *sblock) +{ + int i; + daddr_t sboff; + + for (i = 0; sbtry[i] != -1; i++) { + sboff = sbtry[i] / DEV_BSIZE; + devread(fd, sblock, poffset + sboff, SBSIZE, "superblock"); + *fs = (struct fs *)sblock; + if (sbchk(*fs, sbtry[i])) + break; + } + + if (sbtry[i] == -1) + errx(1, "couldn't find ffs superblock"); +} |