Booting from ufs works now.

This commit is contained in:
gwr 1995-06-01 20:37:44 +00:00
parent 81c8755972
commit 506236d9e5
29 changed files with 880 additions and 161 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.1.1.1 1995/02/14 22:56:36 gwr Exp $
# $NetBSD: Makefile,v 1.1.1.2 1995/06/01 20:37:44 gwr Exp $
SUBDIR= libsa boot bootxx installboot

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.1.1.1 1995/02/14 22:56:36 gwr Exp $
# $NetBSD: Makefile.inc,v 1.1.1.2 1995/06/01 20:37:46 gwr Exp $
.if defined(SA_PROG)

View File

@ -1,4 +1,4 @@
/* $NetBSD: README,v 1.1.1.1 1995/02/14 22:56:36 gwr Exp $ */
/* $NetBSD: README,v 1.1.1.2 1995/06/01 20:37:47 gwr Exp $ */
The sun bootblocks are split into two parts: a small 1st-level program that
gets written right after the superblock in a partition (and is hence limited
@ -18,4 +18,25 @@ Use the following command to install the 1st-level bootblocks in the
root filesystem (on `sd0a') using the file `/boot' as the second level
boot program:
installboot /boot bootxx /dev/rsd0a
mount /dev/sd0a /mnt
installboot /mnt/boot bootxx /dev/rsd0a
The above only works with securelevel <= 0 (see init.8 manual).
Status:
bootxx, installboot are tested and working. It would be nice if
installboot would find the inumber for the 2nd stage boot program
without having the filesystem mounted so this command can work
with securelevel==1 (the default). Doing this requies adding
code to read and do a directory lookup in the root...
netboot does not work yet... (netif_sun stuff in libsa not done)
Note:
Before installation, the second stage boot programs (ufsboot, ...)
need the a.out header stripped off. For now I do this by hand
using the following command. This needs to be automated...
dd ibs=32 skip=1 if=a.out.file | dd conv=sync of=no.header.file

View File

@ -1,5 +1,6 @@
# $NetBSD: Makefile,v 1.1.1.1 1995/02/14 22:56:36 gwr Exp $
# $NetBSD: Makefile,v 1.1.1.2 1995/06/01 20:37:49 gwr Exp $
SA_PROG= bootxx
SRCS= bootxx.c conf.c
.include <bsd.prog.mk>

View File

@ -0,0 +1,10 @@
/* $NetBSD: conf.c,v 1.1.1.1 1995/06/01 20:37:51 gwr Exp $ */
#include <stand.h>
#include <dev_disk.h>
struct devsw devsw[] = {
{ "disk", disk_strategy, disk_open, disk_close, disk_ioctl },
};
int ndevs = 1;

View File

@ -1,6 +1,8 @@
# $NetBSD: Makefile,v 1.1.1.1 1995/02/14 22:56:36 gwr Exp $
# $NetBSD: Makefile,v 1.1.1.2 1995/06/01 20:37:52 gwr Exp $
PROG= installboot
MAN8=
CFLAGS=-g
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: installboot.c,v 1.1.1.1 1995/02/14 22:56:36 gwr Exp $ */
/* $NetBSD: installboot.c,v 1.1.1.2 1995/06/01 20:37:53 gwr Exp $ */
/*
* Copyright (c) 1994 Paul Kranenburg
@ -49,13 +49,18 @@
int verbose, nowrite;
char *boot, *proto, *dev;
struct nlist nl[] = {
#define X_BLOCKNUM 0
{"_blocknum"},
#define X_MAXBLOCKNUM 1
{"_maxblocknum"},
#define X_BLOCK_SIZE 0
{"_block_size"},
#define X_BLOCK_COUNT 1
{"_block_count"},
#define X_BLOCK_TABLE 2
{"_block_table"},
{NULL}
};
daddr_t *blocknums; /* block number array in prototype image */
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 */
@ -63,7 +68,7 @@ char *loadprotoblocks __P((char *, long *));
int loadblocknums __P((char *, int));
void
void
usage()
{
fprintf(stderr,
@ -71,7 +76,7 @@ usage()
exit(1);
}
int
int
main(argc, argv)
int argc;
char *argv[];
@ -125,6 +130,10 @@ main(argc, argv)
if (nowrite)
return 0;
#ifndef sparc /* XXX */
protostore += sizeof(struct exec);
#endif
/* Write patched proto bootblocks into the superblock */
if (protosize > SBSIZE - DEV_BSIZE)
errx(1, "proto bootblocks too big");
@ -141,73 +150,93 @@ main(argc, argv)
return 0;
}
char *
char *
loadprotoblocks(fname, size)
char *fname;
long *size;
{
int fd;
size_t dsize, fsize;
char *bp;
struct stat statbuf;
struct exec *hp;
struct nlist *nlp;
struct exec eh;
long off;
fd = -1;
bp = NULL;
/* Locate block number array in proto file */
if (nlist(fname, nl) != 0) {
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);
return NULL;
}
if (nl[X_MAXBLOCKNUM].n_type != N_DATA + N_EXT) {
warnx("nlist: %s: wrong type", nl[X_MAXBLOCKNUM].n_un.n_name);
return NULL;
/* Validate symbol types (global data). */
for (nlp = nl; nlp->n_un.n_name; nlp++) {
if (nlp->n_type != (N_DATA | N_EXT)) {
warnx("nlist: %s: wrong type", nlp->n_un.n_name);
return NULL;
}
}
if ((fd = open(fname, O_RDONLY)) < 0) {
warn("open: %s", fname);
return NULL;
}
if (fstat(fd, &statbuf) != 0) {
warn("fstat: %s", fname);
close(fd);
return NULL;
}
if ((bp = calloc(roundup(statbuf.st_size, DEV_BSIZE), 1)) == NULL) {
warnx("malloc: %s: no memory", fname);
close(fd);
return NULL;
}
if (read(fd, bp, statbuf.st_size) != statbuf.st_size) {
if (read(fd, &eh, sizeof(eh)) != sizeof(eh)) {
warn("read: %s", fname);
free(bp);
close(fd);
return NULL;
goto bad;
}
close(fd);
if (N_GETMAGIC(eh) != OMAGIC) {
warn("bad magic: 0x%x", eh.a_midmag);
goto bad;
}
/*
* We have to include the exec header in the beginning
* of the buffer, as well as a blank one at the end.
* Later, we will decide where to start copying from.
*/
dsize = eh.a_text + eh.a_data;
fsize = dsize + (2 * sizeof(eh));
fsize = roundup(fsize, DEV_BSIZE);
hp = (struct exec *)bp;
*size = roundup(hp->a_text + hp->a_data, DEV_BSIZE);
if ((bp = calloc(fsize, 1)) == NULL) {
warnx("malloc: %s: no memory", fname);
goto bad;
}
memcpy(bp, &eh, sizeof(eh));
if (read(fd, bp+sizeof(eh), dsize) != dsize) {
warn("read: %s", fname);
goto bad;
}
/* 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));
*size = fsize;
/* Calculate the symbols' locations within the proto file */
off = N_DATOFF(eh) - N_DATADDR(eh) - (eh.a_entry - N_TXTADDR(eh));
block_size_p = (int *) (bp + nl[X_BLOCK_SIZE ].n_value + off);
block_count_p = (int *) (bp + nl[X_BLOCK_COUNT].n_value + off);
block_table = (daddr_t *) (bp + nl[X_BLOCK_TABLE].n_value + off);
maxblocknum = *block_count_p;
if (verbose) {
printf("%s: entry point %#x\n", fname, hp->a_entry);
printf("%s: entry point %#x\n", fname, eh.a_entry);
printf("proto bootblock size %ld\n", *size);
printf("room for %d filesystem blocks at %#x\n",
maxblocknum, nl[X_BLOCKNUM].n_value);
maxblocknum, nl[X_BLOCK_TABLE].n_value);
}
close(fd);
return bp;
bad:
if (bp)
free(bp);
if (fd >= 0)
close(fd);
return NULL;
}
static void
static void
devread(fd, buf, blk, size, msg)
int fd;
char *buf;
@ -260,9 +289,15 @@ int devfd;
close(fd);
/* Read superblock */
devread(devfd, sblock, btodb(SBOFF), SBSIZE, "superblock");
devread(devfd, sblock, SBLOCK, SBSIZE, "superblock");
fs = (struct fs *)sblock;
/* Sanity-check super-block. */
if (fs->fs_magic != FS_MAGIC)
errx(1, "Bad magic number in superblock");
if (fs->fs_inopb <= 0)
err(1, "Bad inopb=%d in superblock", fs->fs_inopb);
/* Read inode */
if ((buf = malloc(fs->fs_bsize)) == NULL)
errx(1, "No memory for filesystem block");
@ -272,14 +307,26 @@ int devfd;
ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino);
/*
* Get the block numbers; we don't handle fragments
* 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 (verbose)
printf("Will load %d blocks of size %d each.\n",
ndb, fs->fs_bsize);
/*
* Get the block numbers; we don't handle fragments
*/
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);
if (verbose)
printf("%d: %d\n", i, blk);
block_table[i] = blk;
}
if (ndb == 0)
return 0;
@ -288,17 +335,16 @@ int devfd;
* Just one level of indirections; there isn't much room
* for more in the 1st-level bootblocks anyway.
*/
blk = 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 (i >= maxblocknum)
errx(1, "Too many blocks");
*blocknums++ = *ap;
blk = fsbtodb(fs, *ap);
if (verbose)
printf("%d: %d\n", i, blk);
block_table[i] = blk;
}
if (ndb)
errx(1, "Too many blocks");
return 0;
}

View File

@ -1,4 +1,4 @@
| $NetBSD: SRT0.S,v 1.1.1.1 1995/02/14 22:56:37 gwr Exp $
| $NetBSD: SRT0.S,v 1.1.1.2 1995/06/01 20:37:55 gwr Exp $
| Copyright (c) 1995 Gordon W. Ross
| All rights reserved.
@ -31,6 +31,8 @@
| SRT0.S - Stand-alone Run-Time startup code, part 0
.file "SRT0.S"
.text
.globl __estack
__estack:
.globl start
start:
| Check to see if the code is located correctly.
@ -60,8 +62,9 @@ restart:
| now in the relocated code
| Set up stack (just before relocated text)
lea start:l, a0
lea __estack:l, a0
movl a0, sp
subl a6, a6
| Call the run-time startup C code, which will:
| initialize, call main, call exit

View File

@ -1,4 +1,4 @@
/* $NetBSD: SRT1.c,v 1.1.1.1 1995/02/14 22:56:37 gwr Exp $ */
/* $NetBSD: SRT1.c,v 1.1.1.2 1995/06/01 20:37:57 gwr Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross

View File

@ -0,0 +1,24 @@
#include <sys/types.h>
#include <machine/mon.h>
#include "clock.h"
int hz = 1000;
time_t getsecs()
{
register int ticks = getticks();
return ((time_t)(ticks / hz));
}
int getticks()
{
register MachMonRomVector * romvec;
register int ticks;
romvec = romVectorPtr;
ticks = *(romvec->nmiClock);
return (ticks);
}

View File

@ -0,0 +1,6 @@
extern int hz;
time_t getsecs();
int getticks();

View File

@ -0,0 +1,132 @@
/* $NetBSD: dev_disk.c,v 1.1.1.1 1995/06/01 20:38:07 gwr Exp $ */
/*
* Copyright (c) 1993 Paul Kranenburg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Paul Kranenburg.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This module implements a "raw device" interface suitable for
* use by the stand-alone I/O library UFS file-system code, and
* possibly for direct access (i.e. boot from tape).
*
* The implementation is deceptively simple because it uses the
* drivers provided by the Sun PROM monitor. Note that only the
* PROM driver used to load the boot program is available here.
*/
#include <sys/types.h>
#include <machine/mon.h>
#include <machine/saio.h>
#include "stand.h"
#include "dvma.h"
#include "promdev.h"
int
disk_open(f, devname)
struct open_file *f;
char *devname; /* Device part of file name (or NULL). */
{
struct saioreq *sip;
int error;
#ifdef DEBUG_PROM
printf("disk_open: %s\n", devname);
#endif
if ((error = prom_iopen(&sip)) != 0)
return (error);
f->f_devdata = sip;
return 0;
}
int
disk_close(f)
struct open_file *f;
{
struct saioreq *sip;
sip = f->f_devdata;
prom_iclose(sip);
f->f_devdata = NULL;
return 0;
}
int
disk_strategy(devdata, flag, dblk, size, buf, rsize)
void *devdata;
int flag;
daddr_t dblk;
u_int size;
char *buf;
u_int *rsize;
{
struct saioreq *si;
struct boottab *ops;
char *dmabuf;
int si_flag, xcnt;
si = devdata;
ops = si->si_boottab;
#ifdef DEBUG_PROM
printf("disk_strategy: size=%d dblk=%d\n", size, dblk);
#else
twiddle();
#endif
dmabuf = dvma_mapin(buf, size);
si->si_bn = dblk;
si->si_ma = dmabuf;
si->si_cc = size;
si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
xcnt = (*ops->b_strategy)(si, si_flag);
dvma_mapout(dmabuf, size);
#ifdef DEBUG_PROM
printf("disk_strategy: xcnt = %x\n", xcnt);
#endif
if (xcnt <= 0)
return (EIO);
*rsize = xcnt;
return (0);
}
int
disk_ioctl()
{
return EIO;
}

View File

@ -0,0 +1,6 @@
int disk_open __P((struct open_file *, ...));
int disk_close __P((struct open_file *));
int disk_strategy __P((void *, int, daddr_t, u_int, char *, u_int *));
int disk_ioctl();

View File

@ -0,0 +1,33 @@
#include <sys/param.h>
#include <machine/mon.h>
#include <stand.h>
#include "promboot.h"
/*
* Open the device named by the combined device/file name
* given as the "fname" arg, something like: "sd()netbsd"
*
* However, Sun PROMs don't really let you choose which
* device you will talk to. You can only open the device
* that was used to load the boot program. Therefore, we
* do not accept a "device" part in the "fname" string.
* Pass the PROM device name to open in case it needs it.
*/
int
devopen(f, fname, file)
struct open_file *f;
const char *fname;
char **file;
{
struct devsw *dp;
char *cp, *path, *devname;
int error;
*file = (char*)fname;
dp = &devsw[0];
f->f_dev = dp;
error = (*dp->dv_open)(f, prom_bootdev);
return (error);
}

View File

@ -0,0 +1,66 @@
/*
* The easiest way to deal with the need for DVMA mappings is
* to just map the first four megabytes of RAM into DVMA space.
* That way, dvma_mapin can just compute the DVMA alias address,
* and dvma_mapout does nothing.
*/
#include <sys/param.h>
#define DVMA_BASE 0xFF000000
#define DVMA_MASK 0x00ffFFff
#define DVMA_MAPLEN 0x400000 /* 4 MB */
void
dvma_init()
{
int segva, sme;
for (segva = 0; segva < DVMA_MAPLEN; segva += NBSG) {
sme = get_segmap(segva);
set_segmap((DVMA_BASE | segva), sme);
}
}
/* Convert a local address to a DVMA address. */
char *
dvma_mapin(char *addr, int len)
{
int va = (int)addr;
va |= DVMA_BASE;
return ((char *) va);
}
/* Convert a DVMA address to a local address. */
char *
dvma_mapout(char *dmabuf, int len)
{
if (dmabuf < (char*)DVMA_BASE)
panic("dvma_mapout");
return (dmabuf - DVMA_BASE);
}
extern char *alloc(int len);
char *
dvma_alloc(int len)
{
char *mem;
mem = alloc(len);
if (!mem)
return(mem);
return(dvma_mapin(mem, len));
}
extern void free(void *ptr, int len);
void
dvma_free(char *dvma, int len)
{
char *mem;
mem = dvma_mapout(dvma, len);
if (mem)
free(mem, len);
}

View File

@ -0,0 +1,6 @@
char * dvma_mapin(char *pkt, int len);
void dvma_mapout(char *dmabuf, int len);
char * dvma_alloc(int len);

View File

@ -0,0 +1,128 @@
/* $NetBSD: exec_sun.c,v 1.1.1.1 1995/06/01 20:38:07 gwr Exp $ */
/*-
* Copyright (c) 1982, 1986, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)boot.c 8.1 (Berkeley) 6/10/93
*/
#include <sys/param.h>
#include <machine/mon.h>
#include <a.out.h>
#include "stand.h"
char bki_magic[8] = "NetBSD1";
/*ARGSUSED*/
exec_sun(file, addr)
char *file;
char *addr;
{
register int io;
struct exec x;
int i, strtablen;
void (*entry)() = (void (*)())addr;
char *cp;
#ifdef DEBUG
printf("exec_sun: file=%s addr=0x%x\n", file, addr);
#endif
io = open(file, 0);
if (io < 0)
return(-1);
i = read(io, (char *)&x, sizeof(x));
if (i != sizeof(x) || N_BADMAG(x)) {
close(io);
errno = EFTYPE;
return(-1);
}
printf("%d", x.a_text);
if (N_GETMAGIC(x) == ZMAGIC) {
addr += sizeof(struct exec);
entry = (void (*)())addr;
}
if (read(io, (char *)addr, x.a_text) != x.a_text)
goto shread;
addr += x.a_text;
if (N_GETMAGIC(x) == ZMAGIC || N_GETMAGIC(x) == NMAGIC)
while ((int)addr & __LDPGSZ)
*addr++ = 0;
printf("+%d", x.a_data);
if (read(io, addr, x.a_data) != x.a_data)
goto shread;
addr += x.a_data;
printf("+%d", x.a_bss);
for (i = 0; i < x.a_bss; i++)
*addr++ = 0;
/* Always set the symtab size word. */
bcopy(&x.a_syms, addr, sizeof(x.a_syms));
addr += sizeof(x.a_syms);
if (x.a_syms != 0) {
printf("+[%d+", x.a_syms);
/* Copy symbol table (nlist part). */
if (read(io, addr, x.a_syms) != x.a_syms)
goto shread;
addr += x.a_syms;
/* Copy string table length word. */
if (read(io, &strtablen, sizeof(int)) != sizeof(int))
goto shread;
/* Copy string table itself. */
bcopy(&strtablen, addr, sizeof(int));
if (i = strtablen) {
i -= sizeof(int);
addr += sizeof(int);
if (read(io, addr, i) != i)
goto shread;
addr += i;
}
printf("%d]", i);
}
printf("=0x%x\n", addr);
(*entry)(); /* XXX */
panic("exec returned");
shread:
close(io);
printf("exec: short read\n");
errno = EIO;
return(-1);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: gets.c,v 1.1.1.1 1995/02/14 22:56:37 gwr Exp $ */
/* $NetBSD: gets.c,v 1.1.1.2 1995/06/01 20:37:58 gwr Exp $ */
/*-
* Copyright (c) 1993

View File

@ -3,6 +3,7 @@
#include "stand.h"
extern volatile void abort();
extern int _estack[];
volatile void
panic(const char *fmt, ...)
@ -13,5 +14,18 @@ panic(const char *fmt, ...)
printf(fmt, ap);
printf("\n");
va_end(ap);
stackdump(0);
abort();
}
stackdump(dummy)
int dummy;
{
int *ip;
printf("stackdump:\n");
for (ip = &dummy; ip < _estack; ip += 4) {
printf("%08x: %08x %08x %08x %08x\n",
(int)ip, ip[0], ip[1], ip[2], ip[3]);
}
}

View File

@ -0,0 +1,69 @@
#include <sys/param.h>
#include <sys/reboot.h>
#include <machine/mon.h>
#include "stand.h"
#include "promboot.h"
char prom_bootdev[32];
char *prom_bootfile;
int prom_boothow;
/*
* Get useful info from the PROM bootparams struct, i.e.:
* arg[0] = sd(0,0,0)netbsd
* arg[1] = -sa
*/
void
prom_get_boot_info()
{
MachMonBootParam *bpp;
char c, *src, *dst;
#ifdef DEBUG
printf("prom_get_boot_info\n");
#endif
bpp = *romp->bootParam;
/* Get device and file names. */
src = bpp->argPtr[0];
dst = prom_bootdev;
*dst++ = *src++;
*dst++ = *src++;
if (*src == '(') {
while (*src) {
c = *src++;
*dst++ = c;
if (c == ')')
break;
}
*dst = '\0';
}
prom_bootfile = src;
/* Get boothowto flags. */
src = bpp->argPtr[1];
if (src && (*src == '-')) {
while (*src) {
switch (*src++) {
case 'a':
prom_boothow |= RB_ASKNAME;
break;
case 's':
prom_boothow |= RB_SINGLE;
break;
case 'd':
prom_boothow |= RB_KDB;
break;
}
}
}
#ifdef DEBUG
printf("promboot: device=\"%s\" file=\"%s\" how=0x%x\n",
prom_bootdev, prom_bootfile, prom_boothow);
#endif
}

View File

@ -0,0 +1,5 @@
extern char prom_bootdev[];
extern char *prom_bootfile;
extern int prom_boothow;

View File

@ -1,4 +1,4 @@
/* $NetBSD: promdev.c,v 1.1.1.1 1995/02/14 22:56:37 gwr Exp $ */
/* $NetBSD: promdev.c,v 1.1.1.2 1995/06/01 20:38:01 gwr Exp $ */
/*
* Copyright (c) 1993 Paul Kranenburg
@ -30,137 +30,163 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <machine/mon.h>
#include <machine/pte.h>
#include <machine/saio.h>
#include "stand.h"
#include <dvma.h>
#include <stand.h>
int promopen __P((struct open_file *, ...));
int promclose __P((struct open_file *));
int promioctl __P((struct open_file *, u_long, void *));
int promstrategy __P((void *, int, daddr_t, u_int, char *, u_int *));
struct saioreq prom_si;
static int promdev_inuse;
struct devsw devsw[] = {
{ "prom", promstrategy, promopen, promclose, promioctl },
};
int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
static char pathbuf[100];
static char *
prom_mapin(u_long physaddr, int length, int maptype);
int
devopen(f, fname, file)
struct open_file *f;
char *fname;
char **file;
prom_iopen(void **devdatap)
{
struct bootparam *bp;
struct boottab *ops;
struct devinfo *dip;
struct saioreq *si;
char *cp, *path, *dev;
char *p;
int error;
if (promdev_inuse)
return(EMFILE);
bp = *romp->bootParam;
ops = bp->bootDevice;
dip = ops->b_devinfo;
si = (struct saioreq *) alloc(sizeof(*si));
#ifdef DEBUG_PROM
printf("Boot device type: %s\n", ops->b_desc);
#endif
dvma_init();
si = &prom_si;
bzero((caddr_t)si, sizeof(*si));
si->si_boottab = ops;
si->si_ctlr = bp->ctlrNum;
si->si_unit = bp->unitNum;
si->si_boff = bp->partNum;
f->f_devdata = (void *) si;
f->f_dev = devsw;
#ifdef DEBUG
printf("Boot device type: %s\n", ops->b_desc);
#endif
path = pathbuf;
cp = bp->argPtr[0];
while (*cp) {
*path++ = *cp;
if (*cp++ == ')')
break;
if (si->si_ctlr > dip->d_stdcount) {
printf("Invalid controller number\n");
return(ENXIO);
}
*path = '\0';
dev = path = pathbuf;
if (dip->d_devbytes) {
si->si_devaddr = prom_mapin(dip->d_stdaddrs[si->si_ctlr],
dip->d_devbytes, dip->d_devtype);
#ifdef DEBUG_PROM
printf("prom_iopen: devaddr=0x%x pte=0x%x\n",
si->si_devaddr, get_pte(si->si_devaddr));
#endif
}
if (dip->d_dmabytes) {
si->si_dmaaddr = dvma_alloc(dip->d_dmabytes);
#ifdef DEBUG_PROM
printf("prom_iopen: dmaaddr=0x%x\n", si->si_dmaaddr);
#endif
}
/* OK, call the PROM device open routine. */
error = (*ops->b_open)(si);
if (error != 0) {
printf("Can't open device `%s'\n", dev);
return ENXIO;
printf("prom_iopen: \"%s\" error=%d\n",
ops->b_desc, error);
return (ENXIO);
}
*file = fname;
return 0;
}
int
promstrategy(devdata, flag, dblk, size, buf, rsize)
void *devdata;
int flag;
daddr_t dblk;
u_int size;
char *buf;
u_int *rsize;
{
struct saioreq *si;
struct boottab *ops;
int error = 0;
int si_flag, xcnt;
si = (struct saioreq *) devdata;
ops = si->si_boottab;
#ifdef DEBUG
printf("promstrategy: size=%d dblk=%d\n", size, dblk);
#ifdef DEBUG_PROM
printf("prom_iopen: succeeded, error=%d\n", error);
#endif
twiddle();
si->si_bn = dblk;
si->si_ma = buf;
si->si_cc = xcnt = 512; /* XXX */
si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
error = (*ops->b_strategy)(si, si_flag);
if (error)
return (EIO);
*rsize = xcnt;
#ifdef DEBUG
printf("rsize = %x\n", *rsize);
#endif
*devdatap = si;
promdev_inuse++;
return (0);
}
int
promopen(f)
struct open_file *f;
void
prom_iclose(void *devdata)
{
#ifdef DEBUG
printf("promopen:\n");
#endif
return 0;
struct boottab *ops;
struct devinfo *dip;
struct saioreq *si;
if (promdev_inuse == 0)
return;
si = devdata;
ops = si->si_boottab;
dip = ops->b_devinfo;
(*ops->b_close)(si);
if (si->si_dmaaddr) {
dvma_free(si->si_dmaaddr, dip->d_dmabytes);
si->si_dmaaddr = NULL;
}
promdev_inuse = 0;
}
int
promclose(f)
struct open_file *f;
{
return EIO;
}
struct mapinfo {
int maptype;
int pgtype;
int base;
};
int
promioctl(f, cmd, data)
struct open_file *f;
u_long cmd;
void *data;
{
return EIO;
}
static struct mapinfo
prom_mapinfo[] = {
{ MAP_MAINMEM, PGT_OBMEM, 0 },
{ MAP_OBIO, PGT_OBIO, 0 },
{ MAP_MBMEM, PGT_OBMEM, 0 }, /* XXX - Sun2 Multibus? */
{ MAP_MBIO, PGT_OBIO, 0 }, /* XXX - Sun2 Multibus? */
{ MAP_VME16A16D, PGT_VME_D16, 0xFFFF0000 },
{ MAP_VME16A32D, PGT_VME_D32, 0xFFFF0000 },
{ MAP_VME24A16D, PGT_VME_D16, 0xFF000000 },
{ MAP_VME24A32D, PGT_VME_D32, 0xFF000000 },
{ MAP_VME32A16D, PGT_VME_D16, 0 },
{ MAP_VME32A32D, PGT_VME_D32, 0 },
};
static prom_mapinfo_cnt = sizeof(prom_mapinfo) / sizeof(prom_mapinfo[0]);
/* The virtual address we will use for PROM device mappings. */
static int prom_devmap = MONSHORTSEG;
static char *
prom_mapin(physaddr, length, maptype)
u_long physaddr;
int length, maptype;
{
int i, pa, pte, va;
if (length > (4*NBPG))
panic("prom_mapin: length=%d\n", length);
for (i = 0; i < prom_mapinfo_cnt; i++)
if (prom_mapinfo[i].maptype == maptype)
goto found;
panic("prom_mapin: invalid maptype %d\n", maptype);
found:
pte = prom_mapinfo[i].pgtype;
pte |= PG_PERM;
pa = prom_mapinfo[i].base;
pa += physaddr;
pte |= PA_PGNUM(pa);
va = prom_devmap;
do {
set_pte(va, pte);
va += NBPG;
pte += 1;
length -= NBPG;
} while (length > 0);
return ((char*)prom_devmap);
}

View File

@ -0,0 +1,4 @@
int prom_iopen(struct saioreq **sipp);
void prom_iclose(struct saioreq *sip);

View File

@ -0,0 +1,6 @@
# $NetBSD: Makefile,v 1.1.1.1 1995/06/01 20:38:08 gwr Exp $
SA_PROG= ufsboot
SRCS= boot.c conf.c version.c
.include <bsd.prog.mk>

View File

@ -0,0 +1,83 @@
/* $NetBSD: boot.c,v 1.1.1.1 1995/06/01 20:38:08 gwr Exp $ */
/*-
* Copyright (c) 1982, 1986, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)boot.c 8.1 (Berkeley) 6/10/93
*/
#include <sys/param.h>
#include <sys/reboot.h>
#include <machine/mon.h>
#include "stand.h"
#include "promboot.h"
int debug;
int errno;
/*
* Boot device is derived from ROM provided information.
*/
#define LOADADDR 0x4000
extern char *version;
char defname[32] = "netbsd";
char line[80];
main()
{
char *cp, *file;
int io;
printf(">> NetBSD ufsboot [%s]\n", version);
prom_get_boot_info();
file = defname;
cp = prom_bootfile;
if (cp && *cp)
file = cp;
for (;;) {
if (prom_boothow & RB_ASKNAME) {
printf("boot: ");
gets(line);
if (line[0])
file = line;
}
exec_sun(file, LOADADDR);
printf("boot: %s\n", strerror(errno));
prom_boothow |= RB_ASKNAME;
}
}

View File

@ -0,0 +1,16 @@
/* $NetBSD: conf.c,v 1.1.1.1 1995/06/01 20:38:08 gwr Exp $ */
#include <stand.h>
#include <ufs.h>
#include <dev_disk.h>
struct fs_ops file_system[] = {
{ ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat },
};
int nfsys = 1;
struct devsw devsw[] = {
{ "disk", disk_strategy, disk_open, disk_close, disk_ioctl },
};
int ndevs = 1;

View File

@ -0,0 +1,3 @@
#!/bin/sh
dd ibs=32 skip=1 | dd conv=sync

Binary file not shown.

View File

@ -0,0 +1,9 @@
/* $NetBSD: version.c,v 1.1.1.1 1995/06/01 20:38:08 gwr Exp $ */
/*
* NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
*
* 1.1
*/
char *version = "$Revision: 1.1.1.1 $";