summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/alpha/stand/boot/Makefile6
-rw-r--r--sys/arch/alpha/stand/boot/filesystem.c5
-rw-r--r--sys/arch/alpha/stand/boot/version3
-rw-r--r--sys/arch/alpha/stand/installboot.c175
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");
+}