Avoid reading the filesystem superblock in bootxx; all info now prepared
by installboot (per Gordon Ross).
This commit is contained in:
parent
fe622df251
commit
691b9f2bfa
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bootxx.c,v 1.6 1995/09/18 21:31:44 pk Exp $ */
|
||||
/* $NetBSD: bootxx.c,v 1.7 1995/09/27 09:03:13 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Paul Kranenburg
|
||||
@ -33,8 +33,6 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <a.out.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#include <stand.h>
|
||||
#include "promdev.h"
|
||||
@ -45,18 +43,20 @@ int netif_debug;
|
||||
/*
|
||||
* Boot device is derived from ROM provided information.
|
||||
*/
|
||||
struct open_file io;
|
||||
char sblock[SBSIZE];
|
||||
struct fs *fs;
|
||||
|
||||
#if 0
|
||||
#define MAXBLOCKNUM MINBSIZE / sizeof(daddr_t)
|
||||
#else
|
||||
#define MAXBLOCKNUM 256
|
||||
#endif
|
||||
int maxblocknum = MAXBLOCKNUM;
|
||||
daddr_t blocknum[MAXBLOCKNUM] = { 0 };
|
||||
const char progname[] = "bootxx";
|
||||
struct open_file io;
|
||||
|
||||
/*
|
||||
* The contents of the block_* variables below is set by installboot(8)
|
||||
* to hold the the filesystem data of the second-stage boot program
|
||||
* (typically `/boot'): filesystem block size, # of filesystem blocks and
|
||||
* the block numbers themselves.
|
||||
*/
|
||||
#define MAXBLOCKNUM 256 /* enough for a 2MB boot program (bs 8K) */
|
||||
int32_t block_size = 0;
|
||||
int32_t block_count = MAXBLOCKNUM;
|
||||
daddr_t block_table[MAXBLOCKNUM] = { 0 };
|
||||
|
||||
|
||||
void loadboot __P((struct open_file *, caddr_t));
|
||||
|
||||
@ -73,16 +73,6 @@ main()
|
||||
panic("%s: can't open device", progname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read superblock.
|
||||
*/
|
||||
if ((io.f_dev->dv_strategy)(io.f_devdata, F_READ,
|
||||
btodb(SBOFF), SBSIZE,
|
||||
(char *)&sblock, &n) || n != SBSIZE) {
|
||||
panic("%s: can't read superblock", progname);
|
||||
}
|
||||
fs = (struct fs *)sblock;
|
||||
|
||||
(void)loadboot(&io, LOADADDR);
|
||||
(*entry)(cputyp == CPU_SUN4 ? LOADADDR : (caddr_t)promvec);
|
||||
_rtt();
|
||||
@ -103,23 +93,23 @@ loadboot(f, addr)
|
||||
* needed for sun4 architecture, but use it for all machines
|
||||
* to keep code size down as much as possible.
|
||||
*/
|
||||
buf = alloc(fs->fs_bsize);
|
||||
buf = alloc(block_size);
|
||||
if (buf == NULL)
|
||||
panic("%s: alloc failed", progname);
|
||||
|
||||
for (i = 0; i < MAXBLOCKNUM; i++) {
|
||||
if ((blk = blocknum[i]) == 0)
|
||||
break;
|
||||
for (i = 0; i < block_count; i++) {
|
||||
if ((blk = block_table[i]) == 0)
|
||||
panic("%s: block table corrupt", progname);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("%s: block # %d = %d\n", i, blk);
|
||||
printf("%s: block # %d = %d\n", progname, i, blk);
|
||||
#endif
|
||||
if ((f->f_dev->dv_strategy)(f->f_devdata, F_READ,
|
||||
fsbtodb(fs, blk), fs->fs_bsize,
|
||||
buf, &n)) {
|
||||
blk, block_size, buf, &n)) {
|
||||
panic("%s: read failure", progname);
|
||||
}
|
||||
bcopy(buf, addr, fs->fs_bsize); /* copy over */
|
||||
if (n != fs->fs_bsize)
|
||||
bcopy(buf, addr, block_size);
|
||||
if (n != block_size)
|
||||
panic("%s: short read", progname);
|
||||
if (i == 0) {
|
||||
register int m = N_GETMAGIC(*(struct exec *)addr);
|
||||
@ -131,10 +121,5 @@ loadboot(f, addr)
|
||||
}
|
||||
addr += n;
|
||||
}
|
||||
if (blk != 0)
|
||||
panic("%s: file too long", progname);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("%s: start 0x%x\n", (int)entry);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: installboot.c,v 1.8 1995/09/18 22:36:19 pk Exp $ */
|
||||
/* $NetBSD: installboot.c,v 1.9 1995/09/27 09:03:15 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Paul Kranenburg
|
||||
@ -34,6 +34,7 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
@ -48,15 +49,22 @@
|
||||
|
||||
int verbose, nowrite, hflag;
|
||||
char *boot, *proto, *dev;
|
||||
|
||||
struct nlist nl[] = {
|
||||
#define X_BLOCKNUM 0
|
||||
{"_blocknum"},
|
||||
#define X_MAXBLOCKNUM 1
|
||||
{"_maxblocknum"},
|
||||
#define X_BLOCKTABLE 0
|
||||
{"_block_table"},
|
||||
#define X_BLOCKCOUNT 1
|
||||
{"_block_count"},
|
||||
#define X_BLOCKSIZE 2
|
||||
{"_block_size"},
|
||||
{NULL}
|
||||
};
|
||||
daddr_t *blocknums; /* block number array in prototype image */
|
||||
int maxblocknum; /* size of this array */
|
||||
daddr_t *block_table; /* block number array in prototype image */
|
||||
int32_t *block_count_p; /* size of this array */
|
||||
int32_t *block_size_p; /* filesystem block size */
|
||||
int32_t max_block_count;
|
||||
|
||||
char cpumodel[100];
|
||||
|
||||
|
||||
char *loadprotoblocks __P((char *, long *));
|
||||
@ -83,6 +91,8 @@ main(argc, argv)
|
||||
int devfd;
|
||||
char *protostore;
|
||||
long protosize;
|
||||
int mib[2];
|
||||
size_t size;
|
||||
|
||||
while ((c = getopt(argc, argv, "vnh")) != EOF) {
|
||||
switch (c) {
|
||||
@ -117,6 +127,16 @@ main(argc, argv)
|
||||
printf("device: %s\n", dev);
|
||||
}
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_MODEL;
|
||||
size = sizeof(cpumodel);
|
||||
if (sysctl(mib, 2, cpumodel, &size, NULL, 0) == -1)
|
||||
err(1, "sysctl");
|
||||
|
||||
if (size < 5 || strncmp(cpumodel, "SUN/4", 5) != 0) /*XXX*/
|
||||
/* Assume a sun4c/sun4m */
|
||||
hflag = 1;
|
||||
|
||||
/* Load proto blocks into core */
|
||||
if ((protostore = loadprotoblocks(proto, &protosize)) == NULL)
|
||||
exit(1);
|
||||
@ -169,12 +189,16 @@ loadprotoblocks(fname, size)
|
||||
warnx("nlist: %s: symbols not found", fname);
|
||||
return NULL;
|
||||
}
|
||||
if (nl[X_BLOCKNUM].n_type != N_DATA + N_EXT) {
|
||||
warnx("nlist: %s: wrong type", nl[X_BLOCKNUM].n_un.n_name);
|
||||
if (nl[X_BLOCKTABLE].n_type != N_DATA + N_EXT) {
|
||||
warnx("nlist: %s: wrong type", nl[X_BLOCKTABLE].n_un.n_name);
|
||||
return NULL;
|
||||
}
|
||||
if (nl[X_MAXBLOCKNUM].n_type != N_DATA + N_EXT) {
|
||||
warnx("nlist: %s: wrong type", nl[X_MAXBLOCKNUM].n_un.n_name);
|
||||
if (nl[X_BLOCKCOUNT].n_type != N_DATA + N_EXT) {
|
||||
warnx("nlist: %s: wrong type", nl[X_BLOCKCOUNT].n_un.n_name);
|
||||
return NULL;
|
||||
}
|
||||
if (nl[X_BLOCKSIZE].n_type != N_DATA + N_EXT) {
|
||||
warnx("nlist: %s: wrong type", nl[X_BLOCKSIZE].n_un.n_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -206,15 +230,39 @@ loadprotoblocks(fname, size)
|
||||
|
||||
/* Calculate the symbols' location within the proto file */
|
||||
off = N_DATOFF(*hp) - N_DATADDR(*hp) - (hp->a_entry - N_TXTADDR(*hp));
|
||||
blocknums = (daddr_t *) (bp + nl[X_BLOCKNUM].n_value + off);
|
||||
bcopy(bp + nl[X_MAXBLOCKNUM].n_value + off,
|
||||
&maxblocknum, sizeof(maxblocknum));
|
||||
block_table = (daddr_t *) (bp + nl[X_BLOCKTABLE].n_value + off);
|
||||
block_count_p = (int32_t *)(bp + nl[X_BLOCKCOUNT].n_value + off);
|
||||
block_size_p = (int32_t *) (bp + nl[X_BLOCKSIZE].n_value + off);
|
||||
if ((int)block_table & 3) {
|
||||
warn("%s: invalid address: block_table = %x",
|
||||
fname, block_table);
|
||||
free(bp);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if ((int)block_count_p & 3) {
|
||||
warn("%s: invalid address: block_count_p = %x",
|
||||
fname, block_count_p);
|
||||
free(bp);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if ((int)block_size_p & 3) {
|
||||
warn("%s: invalid address: block_size_p = %x",
|
||||
fname, block_size_p);
|
||||
free(bp);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
max_block_count = *block_count_p;
|
||||
|
||||
if (verbose) {
|
||||
printf("%s: entry point %#x\n", fname, hp->a_entry);
|
||||
printf("%s: a.out header %s\n", fname,
|
||||
hflag?"left on":"stripped off");
|
||||
printf("proto bootblock size %ld\n", sz);
|
||||
printf("room for %d filesystem blocks at %#x\n",
|
||||
maxblocknum, nl[X_BLOCKNUM].n_value);
|
||||
max_block_count, nl[X_BLOCKTABLE].n_value);
|
||||
}
|
||||
|
||||
*size = sz;
|
||||
@ -285,16 +333,35 @@ int devfd;
|
||||
devread(devfd, buf, blk, fs->fs_bsize, "inode");
|
||||
ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino);
|
||||
|
||||
/*
|
||||
* Register filesystem block size.
|
||||
*/
|
||||
*block_size_p = fs->fs_bsize;
|
||||
|
||||
/*
|
||||
* Get the block numbers; we don't handle fragments
|
||||
*/
|
||||
ndb = howmany(ip->di_size, fs->fs_bsize);
|
||||
if (ndb > max_block_count)
|
||||
errx(1, "%s: Too many blocks", boot);
|
||||
|
||||
/*
|
||||
* Register block count.
|
||||
*/
|
||||
*block_count_p = ndb;
|
||||
|
||||
if (verbose)
|
||||
printf("%s: block numbers: ", boot);
|
||||
ap = ip->di_db;
|
||||
for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) {
|
||||
if (i >= maxblocknum)
|
||||
errx(1, "Too many blocks");
|
||||
*blocknums++ = *ap;
|
||||
blk = fsbtodb(fs, *ap);
|
||||
block_table[i] = blk;
|
||||
if (verbose)
|
||||
printf("%d ", blk);
|
||||
}
|
||||
if (verbose)
|
||||
printf("\n");
|
||||
|
||||
if (ndb == 0)
|
||||
return 0;
|
||||
|
||||
@ -302,16 +369,21 @@ int devfd;
|
||||
* Just one level of indirections; there isn't much room
|
||||
* for more in the 1st-level bootblocks anyway.
|
||||
*/
|
||||
if (verbose)
|
||||
printf("%s: block numbers (indirect): ", boot);
|
||||
blk = 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 (i >= maxblocknum)
|
||||
errx(1, "Too many blocks");
|
||||
*blocknums++ = *ap;
|
||||
blk = fsbtodb(fs, *ap);
|
||||
block_table[i] = blk;
|
||||
if (verbose)
|
||||
printf("%d ", blk);
|
||||
}
|
||||
if (verbose)
|
||||
printf("\n");
|
||||
|
||||
if (ndb)
|
||||
errx(1, "Too many blocks");
|
||||
errx(1, "%s: Too many blocks", boot);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user