diff --git a/sys/arch/sun68k/stand/bootxx/bootxx.c b/sys/arch/sun68k/stand/bootxx/bootxx.c index 57499b221ffa..a0fc73d98fba 100644 --- a/sys/arch/sun68k/stand/bootxx/bootxx.c +++ b/sys/arch/sun68k/stand/bootxx/bootxx.c @@ -1,4 +1,4 @@ -/* $NetBSD: bootxx.c,v 1.1 2001/06/14 12:57:12 fredette Exp $ */ +/* $NetBSD: bootxx.c,v 1.2 2001/12/15 23:09:50 fredette Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -51,25 +51,25 @@ #include #include "libsa.h" +#include "bbinfo.h" /* * This is the address where we load the second-stage boot loader. */ #define LOADADDR 0x4000 -/* This determines the largest boot program we can load. */ -#define MAXBLOCKNUM 64 - /* - * These three names are known by installboot. - * The block_table contains starting block numbers, - * in terms of 512-byte blocks. Each non-zero value - * will result in a read of block_size bytes. + * The contents of the bbinfo below are set by installboot(8) + * to hold the filesystem data of the second-stage boot program + * (typically `/ufsboot'): filesystem block size, # of filesystem + * blocks and the block numbers themselves. */ -int block_size = 512; /* default */ -int block_count = MAXBLOCKNUM; /* length of table */ -daddr_t block_table[MAXBLOCKNUM] = { 0 }; - +struct bbinfo bbinfo = { + { BBINFO_MAGIC }, + 0, + MAXBLOCKNUM, + { 0 } +}; int main() @@ -111,30 +111,30 @@ copyboot(fp, addr) char *buf; /* Need to use a buffer that can be mapped into DVMA space. */ - buf = alloc(block_size); + buf = alloc(bbinfo.bbi_block_size); if (!buf) panic("bootxx: alloc failed"); - for (i = 0; i < block_count; i++) { + for (i = 0; i < bbinfo.bbi_block_count; i++) { - if ((blknum = block_table[i]) == 0) + if ((blknum = bbinfo.bbi_block_table[i]) == 0) break; #ifdef DEBUG printf("bootxx: block # %d = %d\n", i, blknum); #endif - if ((fp->f_dev->dv_strategy)(fp->f_devdata, F_READ, - blknum, block_size, buf, &n)) + if ((fp->f_dev->dv_strategy)(fp->f_devdata, F_READ, blknum, + bbinfo.bbi_block_size, buf, &n)) { printf("bootxx: read failed\n"); return -1; } - if (n != block_size) { + if (n != bbinfo.bbi_block_size) { printf("bootxx: short read\n"); return -1; } - bcopy(buf, addr, block_size); - addr += block_size; + bcopy(buf, addr, bbinfo.bbi_block_size); + addr += bbinfo.bbi_block_size; } return 0; diff --git a/sys/arch/sun68k/stand/installboot/Makefile b/sys/arch/sun68k/stand/installboot/Makefile index f5e77d02394a..1e1518cac061 100644 --- a/sys/arch/sun68k/stand/installboot/Makefile +++ b/sys/arch/sun68k/stand/installboot/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.5 2001/12/12 12:24:26 lukem Exp $ +# $NetBSD: Makefile,v 1.6 2001/12/15 23:09:51 fredette Exp $ NOMAN= # defined @@ -8,14 +8,15 @@ PROG= installboot BINDIR=/usr/mdec S= ${.CURDIR}/../../../.. LIBSA=${S}/lib/libsa -CPPFLAGS+= -I${LIBSA} -I. +CPPFLAGS+= -I${LIBSA} -I. -I${.CURDIR}/../libsa WARNS?= 1 # Need this to work in the miniroot LDSTATIC?= -static -.PATH.c: ${LIBSA} +.PATH.c: ${LIBSA} ${S}/ufs/ffs -SRCS= installboot.c byteorder.c loadfile.c loadfile_aout.c loadfile_elf32.c +SRCS= installboot.c byteorder.c ffs_bswap.c \ + loadfile.c loadfile_aout.c loadfile_elf32.c .include diff --git a/sys/arch/sun68k/stand/installboot/installboot.c b/sys/arch/sun68k/stand/installboot/installboot.c index a3e7b87ae635..43b56b5fb301 100644 --- a/sys/arch/sun68k/stand/installboot/installboot.c +++ b/sys/arch/sun68k/stand/installboot/installboot.c @@ -1,4 +1,4 @@ -/* $NetBSD: installboot.c,v 1.1 2001/06/14 12:57:13 fredette Exp $ */ +/* $NetBSD: installboot.c,v 1.2 2001/12/15 23:09:51 fredette Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -43,34 +43,25 @@ #include #include #include +#include #include #include -#include #include #include +#include #include #include #include "loadfile.h" +#include "byteorder.h" +#include "bbinfo.h" -int verbose, nowrite, hflag; +int verbose, nowrite; char *boot, *proto, *dev; -struct nlist nl[] = { -#define X_BLOCK_SIZE 0 - { "block_size" }, -#define X_BLOCK_COUNT 1 - { "block_count" }, -#define X_BLOCK_TABLE 2 - { "block_table" }, - { NULL } -}; - -int *block_size_p; /* block size var. in prototype image */ -int *block_count_p; /* block count var. in prototype image */ -daddr_t *block_table; /* block number array in prototype image */ -int maxblocknum; /* size of this array */ +struct bbinfo *bbinfop; /* bbinfo in prototype image */ +int32_t max_block_count; char *loadprotoblocks __P((char *, size_t *)); int loadblocknums __P((char *, int)); @@ -78,7 +69,6 @@ static void devread __P((int, void *, daddr_t, size_t, char *)); static void usage __P((void)); int main __P((int, char *[])); - static void usage() { @@ -101,7 +91,7 @@ main(argc, argv) switch (c) { case 'h': /* Don't strip a.out header */ - hflag = 1; + warnx("-h option is obsolete"); break; case 'n': /* Do not actually write the bootblock to disk */ @@ -154,7 +144,7 @@ main(argc, argv) if (protosize > SBSIZE - DEV_BSIZE) errx(1, "proto bootblocks too big"); - if ((devfd = open(dev, O_RDWR)) < 0) + if ((devfd = open(dev, O_RDWR, 0)) < 0) err(1, "open: %s", dev); if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE) @@ -174,47 +164,56 @@ loadprotoblocks(fname, size) char *fname; size_t *size; { - int fd; - u_long marks[MARK_MAX], offs; - char *bp; - - fd = -1; - - /* Locate block number array in proto file */ - if (nlist(fname, nl) != 0) { - warnx("nlist: %s: symbols not found", fname); - return NULL; - } + int fd, sz; + u_long ap, bp, st, en, bbi; + u_long marks[MARK_MAX]; marks[MARK_START] = 0; if ((fd = loadfile(fname, marks, COUNT_TEXT|COUNT_DATA)) == -1) return NULL; (void)close(fd); - *size = roundup(marks[MARK_END] - marks[MARK_START], DEV_BSIZE); - bp = malloc(*size); + sz = (marks[MARK_END] - marks[MARK_START]); + sz = roundup(sz, DEV_BSIZE); + st = marks[MARK_START]; + en = marks[MARK_ENTRY]; - offs = marks[MARK_START]; - marks[MARK_START] = (u_long)bp - offs; + if ((ap = (u_long)malloc(sz)) == NULL) { + warn("malloc: %s", ""); + return NULL; + } + bp = ap; + marks[MARK_START] = bp - st; if ((fd = loadfile(fname, marks, LOAD_TEXT|LOAD_DATA)) == -1) return NULL; (void)close(fd); - /* Calculate the symbols' locations within the proto file */ - block_size_p = (int *) (bp + (nl[X_BLOCK_SIZE ].n_value - offs)); - block_count_p = (int *) (bp + (nl[X_BLOCK_COUNT].n_value - offs)); - block_table = (daddr_t *) (bp + (nl[X_BLOCK_TABLE].n_value - offs)); - maxblocknum = *block_count_p; - - if (verbose) { - printf("%s: entry point %#lx\n", fname, marks[MARK_ENTRY]); - printf("proto bootblock size %d\n", *size); - printf("room for %d filesystem blocks at %#lx\n", - maxblocknum, nl[X_BLOCK_TABLE].n_value); + /* Look for the bbinfo structure. */ + for (bbi = bp; bbi < (bp + sz); bbi += sizeof(uint32_t)) { + bbinfop = (void *) bbi; + if (memcmp(bbinfop->bbi_magic, BBINFO_MAGIC, + BBINFO_MAGICSIZE) == 0) + break; + } + if (bbi >= (bp + sz)) { + warn("%s: unable to locate bbinfo structure\n", fname); + free((void *)ap); + return NULL; } - return bp; + max_block_count = sa_be32toh(bbinfop->bbi_block_count); + + if (verbose) { + printf("%s: entry point %#lx\n", fname, en); + printf("proto bootblock size %d\n", sz); + printf("room for %d filesystem blocks at %#lx\n", + max_block_count, + bbi - bp + offsetof(struct bbinfo, bbi_block_table)); + } + + *size = sz; + return (char *)ap; } static void @@ -247,6 +246,7 @@ int devfd; daddr_t blk, *ap; struct dinode *ip; int ndb; + int needswap; /* * Open 2nd-level boot program and record the block numbers @@ -263,7 +263,7 @@ int devfd; err(1, "statfs: %s", boot); if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) && - strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN) ) { + strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN)) { errx(1, "%s: must be on an FFS filesystem", boot); } @@ -278,6 +278,9 @@ int devfd; /* Read superblock */ devread(devfd, sblock, SBLOCK, SBSIZE, "superblock"); fs = (struct fs *)sblock; + needswap = (sa_be32toh(fs->fs_magic) == FS_MAGIC); + if (needswap) + ffs_sb_swap(fs, fs); /* Sanity-check super-block. */ if (fs->fs_magic != FS_MAGIC) @@ -292,15 +295,17 @@ int devfd; blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino)); devread(devfd, buf, blk, fs->fs_bsize, "inode"); ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); + if (needswap) + ffs_dinode_swap(ip, ip); /* * Have the inode. Figure out how many blocks we need. */ ndb = howmany(ip->di_size, fs->fs_bsize); - if (ndb > maxblocknum) - errx(1, "Too many blocks"); - *block_count_p = ndb; - *block_size_p = fs->fs_bsize; + if (ndb > max_block_count) + errx(1, "%s: Too many blocks", boot); + bbinfop->bbi_block_count = sa_htobe32(ndb); + bbinfop->bbi_block_size = sa_htobe32(fs->fs_bsize); if (verbose) printf("Will load %d blocks of size %d each.\n", ndb, fs->fs_bsize); @@ -310,10 +315,12 @@ int devfd; */ ap = ip->di_db; for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) { + if (needswap) + *ap = bswap32(*ap); blk = fsbtodb(fs, *ap); + bbinfop->bbi_block_table[i] = sa_htobe32(blk); if (verbose) printf("%d: %d\n", i, blk); - block_table[i] = blk; } if (ndb == 0) return 0; @@ -322,14 +329,18 @@ int devfd; * Just one level of indirections; there isn't much room * for more in the 1st-level bootblocks anyway. */ + if (needswap) + ip->di_ib[0] = bswap32(ip->di_ib[0]); 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--) { + if (needswap) + *ap = bswap32(*ap); blk = fsbtodb(fs, *ap); + bbinfop->bbi_block_table[i] = sa_htobe32(blk); if (verbose) printf("%d: %d\n", i, blk); - block_table[i] = blk; } return 0; diff --git a/sys/arch/sun68k/stand/libsa/bbinfo.h b/sys/arch/sun68k/stand/libsa/bbinfo.h new file mode 100644 index 000000000000..5f92c56c8557 --- /dev/null +++ b/sys/arch/sun68k/stand/libsa/bbinfo.h @@ -0,0 +1,41 @@ +/* $NetBSD: bbinfo.h,v 1.1 2001/12/15 23:09:51 fredette Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#define MAXBLOCKNUM 64 /* enough for a 32K boot program (bs 512) */ + +/* Magic string -- 32 bytes long (including the NUL) */ +#define BBINFO_MAGIC "NetBSD/sun68k bootxx " +#define BBINFO_MAGICSIZE sizeof(BBINFO_MAGIC) + +struct bbinfo { + uint8_t bbi_magic[BBINFO_MAGICSIZE]; + int32_t bbi_block_size; + int32_t bbi_block_count; + int32_t bbi_block_table[MAXBLOCKNUM]; +};