Import the sun3 version of this on the "vendor branch".

This commit is contained in:
gwr 1997-03-13 16:27:27 +00:00
parent 1720f66539
commit 24120736d8
45 changed files with 3168 additions and 0 deletions

View File

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $
SUBDIR= installboot libsa bootxx ufsboot netboot tapeboot
.include <bsd.subdir.mk>

View File

@ -0,0 +1,50 @@
# $NetBSD: Makefile.inc,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $
.if defined(SA_PROG)
# Must have S=/usr/src/sys (or equivalent)
# But note: this is w.r.t. a subdirectory
S= ${.CURDIR}/../../../..
RELOC?= 240000
DEFS?= -Dsun3 -DSTANDALONE
INCL?= -I${.CURDIR} -I${.CURDIR}/../libsa -I${S}/lib/libsa -I${S}
COPTS?= -msoft-float ${DEFS} ${DBG} ${INCL}
LIBSA?= ../libsa
SRTOBJ?= ${LIBSA}/SRT0.o ${LIBSA}/SRT1.o
SRTLIB?= ${LIBSA}/libsa.a
MDEC_DIR?=/usr/mdec
SRCS?= ${SA_PROG}.c
OBJS?= ${SRCS:S/.c/.o/g}
CLEANFILES+= ${SA_PROG} ${SA_PROG}.bin
# Make a copy of the executable with its exec header removed,
# and with its length padded to a multiple of 1k bytes.
# (The padding is for convenience when making tapes.)
${SA_PROG}.bin : ${SA_PROG}
cp ${SA_PROG} a.out ; strip a.out
dd if=a.out ibs=32 skip=1 of=$@ obs=1k conv=osync
-rm -f a.out
${SA_PROG} : ${OBJS} ${DPADD}
${LD} -N -Ttext ${RELOC} -e start -o $@ \
${SRTOBJ} ${OBJS} ${LDADD} ${SRTLIB}
@size $@
.if !target(clean)
clean:
-rm -f a.out [Ee]rrs mklog core *.core
-rm -f ${CLEANFILES} *.o
.endif
.if !target(install)
install: ${SA_PROG}.bin
install ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
${SA_PROG}.bin ${DESTDIR}${MDEC_DIR}/${SA_PROG}
.endif
.endif

View File

@ -0,0 +1,38 @@
/* $NetBSD: README,v 1.1.1.1 1997/03/13 16:27:27 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
in size to SBSIZE - DEV_BSIZE bytes), and a 2nd-level program that resides
in the filesystem proper.
The 1st-level program is loaded into memory by the PROM. It loads the second
stage program from a set of filesystem block numbers that are hard-coded
into it by the `installboot' program. The prototype code for the 1st-level
bootblocks are in `bootxx'.
The 2nd-level program (`ufsboot') is normally installed in the root FS
as `/ufsboot'. It uses the device drivers in the PROM and the stand-alone
filesystem code in `libsa.a' to locate and load the kernel.
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:
mount /dev/sd0a /mnt
cd /usr/mdec
cp -p ufsboot /mnt/ufsboot
sync ; sleep 1 ; sync
./installboot -v /mnt/ufsboot bootxx /dev/rsd0a
The above only works with securelevel <= 0 (see init.8 manual).
Status:
netboot works.
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...

View File

@ -0,0 +1,14 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $
SA_PROG= bootxx
SRCS= bootxx.c conf.c
all: ${SA_PROG}
# Do not strip or remove a.out header for this one.
install: ${SA_PROG}
${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
${SA_PROG} ${DESTDIR}${MDEC_DIR}/${SA_PROG}
.include <bsd.prog.mk>

View File

@ -0,0 +1,147 @@
/* $NetBSD: bootxx.c,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $ */
/*
* Copyright (c) 1994 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 is a generic "first-stage" boot program.
*
* Note that this program has absolutely no filesystem knowledge!
*
* Instead, this uses a table of disk block numbers that are
* filled in by the installboot program such that this program
* can load the "second-stage" boot program.
*/
#include <sys/param.h>
#include <sys/time.h>
#include <sys/exec.h>
#include <machine/mon.h>
#include "stand.h"
/*
* Boot device is derived from ROM provided information.
*/
#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.
*/
int block_size = 512; /* default */
int block_count = MAXBLOCKNUM; /* length of table */
daddr_t block_table[MAXBLOCKNUM] = { 0 };
main()
{
struct open_file f;
void (*entry)();
char *addr;
int n, error;
#ifdef DEBUG
printf("bootxx: open...\n");
#endif
f.f_flags = F_RAW;
if (devopen(&f, 0, &addr)) {
printf("bootxx: open failed\n");
exit();
}
addr = (char*)LOADADDR;
error = copyboot(&f, addr);
f.f_dev->dv_close(&f);
if (!error) {
#ifdef DEBUG
printf("bootxx: start 0x%x\n", (long)addr);
#endif
entry = (void (*)())addr;
(*entry)();
}
/* copyboot had a problem... */
exit();
}
int
copyboot(fp, addr)
struct open_file *fp;
char *addr;
{
int n, i, blknum;
char *buf;
#ifdef sparc
/*
* On the sparc, the 2nd stage boot has an a.out header.
* On the sun3, (by tradition) the 2nd stage boot programs
* have the a.out header stripped off. (1st stage boot
* programs have the header stripped by installboot.)
*/
/* XXX - This assumes OMAGIC format! */
addr -= sizeof(struct exec); /* XXX */
#endif
/* Need to use a buffer that can be mapped into DVMA space. */
buf = alloc(block_size);
if (!buf)
panic("bootxx: alloc failed");
for (i = 0; i < block_count; i++) {
if ((blknum = 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))
{
printf("bootxx: read failed\n");
return -1;
}
if (n != block_size) {
printf("bootxx: short read\n");
return -1;
}
bcopy(buf, addr, block_size);
addr += block_size;
}
return 0;
}

View File

@ -0,0 +1,11 @@
/* $NetBSD: conf.c,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $ */
#include <stand.h>
#include <dev_disk.h>
struct devsw devsw[] = {
{ "disk", disk_strategy, disk_open, disk_close, disk_ioctl },
};
int ndevs = 1;
int debug;

View File

@ -0,0 +1,10 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $
PROG= installboot
MAN= installboot.8
BINDIR=/usr/mdec
# Need this to work in the miniroot
LDSTATIC= -static
.include <bsd.prog.mk>

View File

@ -0,0 +1,58 @@
.\" $Id: installboot.8,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $
.\"
.Dd 31 May 1995
.Dt INSTALLBOOT 8
.Os
.Sh NAME
.Nm installboot
.Nd install a bootstrap on a UFS disk
.Sh SYNOPSIS
.Nm installboot
.Fl n | Fl v
.Ar ufsboot
.Ar bootxx
.Ar rawdev
.Sh DESCRIPTION
.Nm installboot
is used to install a "first-stage" boot program into the boot area
of a UFS disk partition, and initialize the table of block numbers the
.Ar bootxx
program uses to load the second-stage boot program.
.Pp
The options are as follows:
.Bl -tag -width flag
.It Fl n
Do not actually write anything on the disk.
.It Fl v
Be verbose, printing out the block numbers that
.Ar bootxx
will use to load
.Ar ufsboot .
.El
.Pp
The arguments are:
.Bl -tag -width ufsboot
.It Ar ufsboot
the name of the second-stage boot program in the file system
where the first-stage boot program is to be installed.
.It Ar bootxx
the name of the prototype file for the first stage boot program.
.It Ar rawdev
the name of the raw device in which the first-stage boot program
is to be installed. This should correspond to the block device
on which the file system containing
.Ar ufsboot
is mounted.
.El
.Sh BUGS
.Nm installboot
requires simultaneous access to the mounted file system and
the raw device, but that is not allowed with the kernel
.Nm securelevel
variable set to a value greater than zero (the default), so
.Nm installboot
only works in single-user mode (or insecure mode - see
.Xr init 8 ).
.Sh "SEE ALSO"
.Xr disklabel 8 ,
.Xr init 8

View File

@ -0,0 +1,377 @@
/* $NetBSD: installboot.c,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $ */
/*
* Copyright (c) 1994 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.
*/
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
#include <err.h>
#include <a.out.h>
#include <fcntl.h>
#include <nlist.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int verbose, nowrite, hflag;
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 */
char *loadprotoblocks __P((char *, long *));
int loadblocknums __P((char *, int));
static void devread __P((int, void *, daddr_t, size_t, char *));
static void usage __P((void));
int main __P((int, char *[]));
static void
usage()
{
fprintf(stderr,
"usage: installboot [-n] [-v] [-h] <boot> <proto> <device>\n");
exit(1);
}
int
main(argc, argv)
int argc;
char *argv[];
{
int c;
int devfd;
char *protostore;
long protosize;
while ((c = getopt(argc, argv, "vnh")) != EOF) {
switch (c) {
case 'h':
/* Don't strip a.out header */
hflag = 1;
break;
case 'n':
/* Do not actually write the bootblock to disk */
nowrite = 1;
break;
case 'v':
/* Chat */
verbose = 1;
break;
default:
usage();
}
}
if (argc - optind < 3) {
usage();
}
boot = argv[optind];
proto = argv[optind + 1];
dev = argv[optind + 2];
if (verbose) {
printf("boot: %s\n", boot);
printf("proto: %s\n", proto);
printf("device: %s\n", dev);
}
/* Load proto blocks into core */
if ((protostore = loadprotoblocks(proto, &protosize)) == NULL)
exit(1);
/* XXX - Paranoia: Make sure size is aligned! */
if (protosize & (DEV_BSIZE - 1))
err(1, "proto bootblock bad size=%d", protosize);
/* Open and check raw disk device */
if ((devfd = open(dev, O_RDONLY, 0)) < 0)
err(1, "open: %s", dev);
/* Extract and load block numbers */
if (loadblocknums(boot, devfd) != 0)
exit(1);
(void)close(devfd);
if (nowrite)
return 0;
/* Write patched proto bootblocks into the superblock */
if (protosize > SBSIZE - DEV_BSIZE)
errx(1, "proto bootblocks too big");
if ((devfd = open(dev, O_RDWR, 0)) < 0)
err(1, "open: %s", dev);
if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE)
err(1, "lseek bootstrap");
/* Sync filesystems (to clean in-memory superblock?) */
sync();
if (write(devfd, protostore, protosize) != protosize)
err(1, "write bootstrap");
(void)close(devfd);
return 0;
}
char *
loadprotoblocks(fname, size)
char *fname;
long *size;
{
int fd;
size_t tdsize; /* text+data size */
size_t bbsize; /* boot block size (block aligned) */
char *bp;
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;
}
/* 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 (read(fd, &eh, sizeof(eh)) != sizeof(eh)) {
warn("read: %s", fname);
goto bad;
}
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, and leave extra space at the end in case
* the actual write to disk wants to skip the header.
*/
tdsize = eh.a_text + eh.a_data;
bbsize = tdsize + sizeof(eh);
bbsize = roundup(bbsize, DEV_BSIZE);
/*
* Allocate extra space here because the caller may copy
* the boot block starting at the end of the exec header.
* This prevents reading beyond the end of the buffer.
*/
if ((bp = calloc(bbsize + sizeof(eh), 1)) == NULL) {
warnx("malloc: %s: no memory", fname);
goto bad;
}
/* Copy the exec header and read the rest of the file. */
memcpy(bp, &eh, sizeof(eh));
if (read(fd, bp+sizeof(eh), tdsize) != tdsize) {
warn("read: %s", fname);
goto bad;
}
*size = bbsize; /* aligned to DEV_BSIZE */
/* 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, eh.a_entry);
printf("proto bootblock size %ld\n", *size);
printf("room for %d filesystem blocks at %#x\n",
maxblocknum, nl[X_BLOCK_TABLE].n_value);
}
close(fd);
if (!hflag)
bp += sizeof(struct exec);
return bp;
bad:
if (bp)
free(bp);
if (fd >= 0)
close(fd);
return NULL;
}
static void
devread(fd, buf, blk, size, msg)
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);
}
static char sblock[SBSIZE];
int
loadblocknums(boot, devfd)
char *boot;
int devfd;
{
int i, fd;
struct stat statbuf;
struct statfs statfsbuf;
struct fs *fs;
char *buf;
daddr_t blk, *ap;
struct dinode *ip;
int ndb;
/*
* Open 2nd-level boot program and record the block numbers
* it occupies on the filesystem represented by `devfd'.
*/
/* Make sure the (probably new) boot file is on disk. */
sync(); sleep(1);
if ((fd = open(boot, O_RDONLY)) < 0)
err(1, "open: %s", boot);
if (fstatfs(fd, &statfsbuf) != 0)
err(1, "statfs: %s", boot);
if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) &&
strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN) ) {
errx(1, "%s: must be on an FFS filesystem", boot);
}
if (fsync(fd) != 0)
err(1, "fsync: %s", boot);
if (fstat(fd, &statbuf) != 0)
err(1, "fstat: %s", boot);
close(fd);
/* Read 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");
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);
/*
* 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--) {
blk = fsbtodb(fs, *ap);
if (verbose)
printf("%d: %d\n", i, blk);
block_table[i] = blk;
}
if (ndb == 0)
return 0;
/*
* Just one level of indirections; there isn't much room
* for more in the 1st-level bootblocks anyway.
*/
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--) {
blk = fsbtodb(fs, *ap);
if (verbose)
printf("%d: %d\n", i, blk);
block_table[i] = blk;
}
return 0;
}

View File

@ -0,0 +1,45 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $
LIB=sa
NOPIC=nopic
NOPROFILE=noprofile
# Logically src/sys
S=${.CURDIR}/../../../..
DIR_SA=$S/lib/libsa
DIR_KERN=$S/lib/libkern
SRC_net= nfs.c rpc.c net.c ether.c arp.c in_cksum.c \
bootparam.c rarp.c
SRC_sa = alloc.c bcopy.c close.c getfile.c memcpy.c open.c \
printf.c read.c strerror.c ufs.c
SRC_kern= ashrdi3.c bcmp.c bzero.c strcmp.c strlen.c
SRC_sun3= control.c ctrlsp.S
SRC_here= clock.c dev_disk.c devopen.c dvma.c \
exec_sun.c gets.c netif_sun.c panic.c \
promboot.c promcons.c promdev.c
SRCS= ${SRC_net} ${SRC_sa} ${SRC_kern} ${SRC_sun3} ${SRC_here}
CLEANFILES+= SRT0.o SRT1.o
# DBG= -DDEBUG -DNETIF_DEBUG -DNFS_DEBUG -DRPC_DEBUG \
# -DNET_DEBUG -DRARP_DEBUG -DETHER_DEBUG
DEFS= -Dsun3 -DSTANDALONE -DCOMPAT_UFS
INCL= -I${.CURDIR} -I${S}/lib/libsa -I${S}
COPTS= -msoft-float
CFLAGS= -O ${COPTS} ${DEFS} ${DBG} ${INCL}
.PATH: ${DIR_SA} ${DIR_KERN} ${.CURDIR}/../../sun3
all: libsa.a SRT0.o SRT1.o
install:
.include <bsd.lib.mk>

View File

@ -0,0 +1,87 @@
| $NetBSD: SRT0.S,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $
| Copyright (c) 1995 Gordon W. Ross
| 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. The name of the author may not be used to endorse or promote products
| derived from this software without specific prior written permission.
| 4. All advertising materials mentioning features or use of this software
| must display the following acknowledgement:
| This product includes software developed by Gordon Ross
|
| 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.
| 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.
| Get current location via PC-relative load, then...
lea pc@(start:w), a0 | current location (0x4000)
| ...force a long (not PC-relative) load to a1 and compare.
lea start:l, a1 | desired location (LINKADDR)
cmpl a0, a1
beqs restart
| Relocate the code and data to where they belong.
movl #_edata,d0 | Desired end of program
subl a1,d0 | Calculate length, round up.
lsrl #2,d0
Lcp:
movl a0@+, a1@+
dbra d0, Lcp
| Force a long jump to the relocated code (not pc-relative)
lea restart:l, a0
jmp a0@
restart:
| now in the relocated code
| Set up stack (just before relocated text)
lea __estack:l, a0
movl a0, sp
subl a6, a6
| Call the run-time startup C code, which will:
| initialize, call main, call exit
jsr __start:l
| If _start returns, fall into abort.
.globl _abort
_abort:
trap #0
| If abort returns, fall into reset.
.globl _reset
_reset:
reset
jmp _reset
| function to get the vector base register
.globl _getvbr
_getvbr:
movc vbr, d0
rts
| The end.

View File

@ -0,0 +1,78 @@
/* $NetBSD: SRT1.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* 4. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Gordon Ross
*
* 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.
*/
/* SRT1.c - Stand-alone Run-time startup code, part 1 */
#include <stdarg.h>
#include <sys/types.h>
#include <machine/mon.h>
extern int edata[], end[];
extern void ** getvbr();
extern __dead void abort();
extern void main();
__dead void
exit()
{
mon_exit_to_mon();
abort();
}
/*
* This is called by SRT0.S
* to do final prep for main
*/
__dead void
_start()
{
register int *ip;
register void **vbr;
/* Clear BSS */
ip = edata;
do *ip++ = 0;
while (ip < end);
/* Set the vector for trap 0 used by abort. */
vbr = getvbr();
vbr[32] = romVectorPtr->abortEntry;
main(0);
exit();
}
/*
* Boot programs in C++ ? Not likely!
*/
void
__main() {}

View File

@ -0,0 +1,21 @@
#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 int ticks;
ticks = *romVectorPtr->nmiClock;
return (ticks);
}

View File

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

View File

@ -0,0 +1,169 @@
/* $NetBSD: dev_disk.c,v 1.1.1.1 1997/03/13 16:27:28 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"
#define RETRY_COUNT 5
extern int debug;
int disk_opencount;
struct saioreq disk_ioreq;
int
disk_open(f, devname)
struct open_file *f;
char *devname; /* Device part of file name (or NULL). */
{
struct bootparam *bp;
struct saioreq *si;
int error;
#ifdef DEBUG_PROM
if (debug)
printf("disk_open: %s\n", devname);
#endif
si = &disk_ioreq;
if (disk_opencount == 0) {
/*
* Setup our part of the saioreq.
* (determines what gets opened)
*/
bp = *romVectorPtr->bootParam;
si->si_boottab = bp->bootDevice;
si->si_ctlr = bp->ctlrNum;
si->si_unit = bp->unitNum;
si->si_boff = bp->partNum;
if ((error = prom_iopen(si)) != 0)
return (error);
}
disk_opencount++;
f->f_devdata = si;
return 0;
}
int
disk_close(f)
struct open_file *f;
{
struct saioreq *si;
#ifdef DEBUG_PROM
if (debug)
printf("disk_close: ocnt=%d\n", disk_opencount);
#endif
si = f->f_devdata;
f->f_devdata = NULL;
if (disk_opencount <= 0)
return 0;
if (--disk_opencount == 0)
prom_iclose(si);
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 retry, si_flag, xcnt;
si = devdata;
ops = si->si_boottab;
#ifdef DEBUG_PROM
if (debug > 1)
printf("disk_strategy: size=%d dblk=%d\n", size, dblk);
#endif
dmabuf = dvma_mapin(buf, size);
si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
/*
* The PROM strategy will occasionally return -1 and expect
* us to try again. From mouse@Collatz.McRCIM.McGill.EDU
*/
retry = RETRY_COUNT;
do {
si->si_bn = dblk;
si->si_ma = dmabuf;
si->si_cc = size;
xcnt = (*ops->b_strategy)(si, si_flag);
} while ((xcnt <= 0) && (--retry > 0));
dvma_mapout(dmabuf, size);
#ifdef DEBUG_PROM
if (debug > 1)
printf("disk_strategy: xcnt = %x retries=%d\n",
xcnt, RETRY_COUNT - retry);
#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, size_t, void *, size_t *));
int disk_ioctl();

View File

@ -0,0 +1,32 @@
#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;
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,118 @@
/* $NetBSD: dvma.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* 4. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Gordon W. Ross
*
* 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.
*/
/*
* The easiest way to deal with the need for DVMA mappings is to
* create a DVMA alias mapping of the entire address range used by
* the boot program. That way, dvma_mapin can just compute the
* DVMA alias address, and dvma_mapout does nothing.
*
* Note that this assumes that standalone programs will do I/O
* operations only within range (SA_MIN_VA .. SA_MAX_VA) checked.
*/
#include <sys/param.h>
#include <machine/pte.h>
#include <machine/control.h>
#include "stand.h"
#define DVMA_BASE 0xFFf00000
#define DVMA_MAPLEN 0xE0000 /* 1 MB - 128K (save MONSHORTSEG) */
#define SA_MIN_VA 0x200000
#define SA_MAX_VA (SA_MIN_VA + DVMA_MAPLEN)
/* This points to the end of the free DVMA space. */
u_int dvma_end = DVMA_BASE + DVMA_MAPLEN;
void
dvma_init()
{
int segva, dmava, sme;
segva = SA_MIN_VA;
dmava = DVMA_BASE;
while (segva < SA_MAX_VA) {
sme = get_segmap(segva);
set_segmap(dmava, sme);
segva += NBSG;
dmava += NBSG;
}
}
/* Convert a local address to a DVMA address. */
char *
dvma_mapin(char *addr, int len)
{
int va = (int)addr;
/* Make sure the address is in the DVMA map. */
if ((va < SA_MIN_VA) || (va >= SA_MAX_VA))
panic("dvma_mapin");
va -= SA_MIN_VA;
va += DVMA_BASE;
return ((char *) va);
}
/* Convert a DVMA address to a local address. */
char *
dvma_mapout(char *addr, int len)
{
int va = (int)addr;
/* Make sure the address is in the DVMA map. */
if ((va < DVMA_BASE) || (va >= (DVMA_BASE + DVMA_MAPLEN)))
panic("dvma_mapout");
va -= DVMA_BASE;
va += SA_MIN_VA;
return ((char *) va);
}
char *
dvma_alloc(int len)
{
len = _round_page(len);
dvma_end -= len;
return((char*)dvma_end);
}
void
dvma_free(char *dvma, int len)
{
/* not worth the trouble */
}

View File

@ -0,0 +1,9 @@
void dvma_init();
char * dvma_mapin(char *pkt, int len);
void dvma_mapout(char *dmabuf, int len);
char * dvma_alloc(int len);
void dvma_free(char *dvma, int len);

View File

@ -0,0 +1,178 @@
/* $NetBSD: exec_sun.c,v 1.1.1.1 1997/03/13 16:27:28 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"
extern int debug;
int errno;
/*ARGSUSED*/
int
exec_sun(file, loadaddr)
char *file;
char *loadaddr;
{
register int io;
struct exec x;
int cc, magic;
void (*entry)();
register char *cp;
register int *ip;
#ifdef DEBUG
printf("exec_sun: file=%s loadaddr=0x%x\n", file, loadaddr);
#endif
io = open(file, 0);
if (io < 0)
return(-1);
/*
* Read in the exec header, and validate it.
*/
if (read(io, (char *)&x, sizeof(x)) != sizeof(x))
goto shread;
if (N_BADMAG(x)) {
errno = EFTYPE;
goto closeout;
}
cp = loadaddr;
magic = N_GETMAGIC(x);
if (magic == ZMAGIC)
cp += sizeof(x);
entry = (void (*)())cp;
/*
* Leave a copy of the exec header before the text.
* The sun3 kernel uses this to verify that the
* symbols were loaded by this boot program.
*/
bcopy(&x, cp - sizeof(x), sizeof(x));
/*
* Read in the text segment. Note:
* a.out header part of text in zmagic
*/
printf("%d", x.a_text);
cc = x.a_text;
if (magic == ZMAGIC)
cc -= sizeof(x);
if (read(io, cp, cc) != cc)
goto shread;
cp += cc;
/*
* NMAGIC may have a gap between text and data.
*/
if (magic == NMAGIC) {
register int mask = N_PAGSIZ(x) - 1;
while ((int)cp & mask)
*cp++ = 0;
}
/*
* Read in the data segment.
*/
printf("+%d", x.a_data);
if (read(io, cp, x.a_data) != x.a_data)
goto shread;
cp += x.a_data;
/*
* Zero out the BSS section.
* (Kernel doesn't care, but do it anyway.)
*/
printf("+%d", x.a_bss);
cc = x.a_bss;
while ((int)cp & 3) {
*cp++ = 0;
--cc;
}
ip = (int*)cp;
cp += cc;
while ((char*)ip < cp)
*ip++ = 0;
/*
* Read in the symbol table and strings.
* (Always set the symtab size word.)
*/
*ip++ = x.a_syms;
cp = (char*) ip;
if (x.a_syms > 0) {
/* Symbol table and string table length word. */
cc = x.a_syms;
printf("+[%d", cc);
cc += sizeof(int); /* strtab length too */
if (read(io, cp, cc) != cc)
goto shread;
cp += x.a_syms;
ip = (int*)cp; /* points to strtab length */
cp += sizeof(int);
/* String table. Length word includes itself. */
cc = *ip;
printf("+%d]", cc);
cc -= sizeof(int);
if (cc <= 0)
goto shread;
if (read(io, cp, cc) != cc)
goto shread;
cp += cc;
}
printf("=0x%x\n", cp - loadaddr);
close(io);
printf("Starting program at 0x%x\n", (int)entry);
asm("_exec_sun_call_entry:");
(*entry)();
panic("exec returned");
shread:
printf("exec: short read\n");
errno = EIO;
closeout:
close(io);
return(-1);
}

View File

@ -0,0 +1,116 @@
/* $NetBSD: gets.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
/*-
* Copyright (c) 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.
*
* @(#)gets.c 8.1 (Berkeley) 6/11/93
*/
#include "stand.h"
/*
* This implementation assumes that getchar() does echo, because
* on some machines, it is hard to keep echo from being done.
* Those that need it can do echo in their getchar() function.
*
* Yes, the code below will echo CR, DEL, and other control chars,
* but sending CR or DEL here is harmless. All the other editing
* characters will be followed by a newline, so it doesn't matter.
* (Most terminals will not show them anyway.)
*/
void
gets(buf)
char *buf;
{
register int c;
register char *lp;
top:
lp = buf;
for (;;) {
c = getchar() & 0177;
#ifdef GETS_MUST_ECHO /* Preserved in case someone wants it... */
putchar(c);
#endif
switch (c) {
default:
*lp++ = c;
continue;
case '\177':
putchar('\b');
/* fall through */
case '\b':
putchar(' ');
putchar('\b');
/* fall through */
case '#':
if (lp > buf)
lp--;
continue;
#ifdef GETS_REPRINT
/*
* This is not very useful in a boot program.
* (It costs you 52 bytes on m68k, gcc -O3).
*/
case 'r'&037: {
register char *p;
putchar('\n');
for (p = buf; p < lp; ++p)
putchar(*p);
continue;
}
#endif
case '@':
case 'u'&037:
case 'w'&037:
putchar('\n');
goto top;
case '\r':
putchar('\n');
/* fall through */
case '\n':
*lp = '\0';
return;
} /* switch */
}
/*NOTREACHED*/
}

View File

@ -0,0 +1,15 @@
#include "iodesc.h"
struct netif {
void *nif_devdata;
};
ssize_t netif_get __P((struct iodesc *, void *, size_t, time_t));
ssize_t netif_put __P((struct iodesc *, void *, size_t));
int netif_open __P((void *));
int netif_close __P((int));
struct iodesc *socktodesc __P((int));

View File

@ -0,0 +1,451 @@
/* $NetBSD: netif_sun.c,v 1.1.1.1 1997/03/13 16:27:27 gwr Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* 4. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Gordon W. Ross
*
* 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.
*/
/*
* The Sun PROM has a fairly general set of network drivers,
* so it is easiest to just replace the netif module with
* this adaptation to the PROM network interface.
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <string.h>
#include <time.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <machine/control.h>
#include <machine/idprom.h>
#include <machine/mon.h>
#include <machine/saio.h>
#include "stand.h"
#include "net.h"
#include "netif.h"
#include "clock.h"
#include "dvma.h"
#include "promdev.h"
#define PKT_BUF_SIZE 2048
int debug;
int errno;
static void sun3_getether __P((u_char *));
struct iodesc sockets[SOPEN_MAX];
static struct netif prom_nif;
static struct devdata {
struct saioreq dd_si;
int rbuf_len;
char *rbuf;
int tbuf_len;
char *tbuf;
u_short dd_opens;
char dd_myea[6];
} prom_dd;
static struct idprom sun3_idprom;
void
sun3_getether(ea)
u_char *ea;
{
u_char *src, *dst;
int len, x;
if (sun3_idprom.idp_format == 0) {
dst = (char*)&sun3_idprom;
src = (char*)IDPROM_BASE;
len = IDPROM_SIZE;
do {
x = get_control_byte(src++);
*dst++ = x;
} while (--len > 0);
}
MACPY(sun3_idprom.idp_etheraddr, ea);
}
/*
* Open the PROM device.
* Return netif ptr on success.
*/
struct devdata *
netif_init(aux)
void *aux;
{
struct devdata *dd = &prom_dd;
struct saioreq *si;
struct bootparam *bp;
int error;
/*
* Setup our part of the saioreq.
* (determines what gets opened)
*/
si = &dd->dd_si;
bzero((caddr_t)si, sizeof(*si));
bp = *romVectorPtr->bootParam;
si->si_boottab = bp->bootDevice;
si->si_ctlr = bp->ctlrNum;
si->si_unit = bp->unitNum;
si->si_boff = bp->partNum;
#ifdef NETIF_DEBUG
if (debug)
printf("netif_init: calling prom_iopen\n");
#endif
/*
* Note: Sun PROMs will do RARP on open, but does not tell
* you the IP address it gets, so it is just noise to us...
*/
if ((error = prom_iopen(si)) != 0) {
printf("netif_init: prom_iopen, error=%d\n", error);
return (NULL);
}
if (si->si_sif == NULL) {
printf("netif_init: not a network device\n");
prom_iclose(si);
return (NULL);
}
#ifdef NETIF_DEBUG
if (debug)
printf("netif_init: allocating buffers\n");
#endif
/* Allocate the transmit/receive buffers. */
if (dd->rbuf == NULL) {
dd->rbuf_len = PKT_BUF_SIZE;
dd->rbuf = dvma_alloc(dd->rbuf_len);
}
if (dd->tbuf == NULL) {
dd->tbuf_len = PKT_BUF_SIZE;
dd->tbuf = dvma_alloc(dd->tbuf_len);
}
if ((dd->rbuf == NULL) ||
(dd->tbuf == NULL))
panic("netif_init: malloc failed\n");
#ifdef NETIF_DEBUG
if (debug)
printf("netif_init: rbuf=0x%x, tbuf=0x%x\n",
dd->rbuf, dd->tbuf);
#endif
/* Record our ethernet address. */
sun3_getether(dd->dd_myea);
dd->dd_opens = 0;
return(dd);
}
void
netif_fini(dd)
struct devdata *dd;
{
struct saioreq *si;
si = &dd->dd_si;
#ifdef NETIF_DEBUG
if (debug)
printf("netif_fini: calling prom_iclose\n");
#endif
prom_iclose(si);
/* Dellocate the transmit/receive buffers. */
if (dd->rbuf) {
dvma_free(dd->rbuf, dd->rbuf_len);
dd->rbuf = NULL;
}
if (dd->tbuf) {
dvma_free(dd->tbuf, dd->tbuf_len);
dd->tbuf = NULL;
}
}
int
netif_attach(nif, s, aux)
struct netif *nif;
struct iodesc *s;
void *aux;
{
struct devdata *dd;
dd = nif->nif_devdata;
if (dd == NULL) {
dd = netif_init(aux);
if (dd == NULL)
return (ENXIO);
nif->nif_devdata = dd;
}
dd->dd_opens++;
MACPY(dd->dd_myea, s->myea);
s->io_netif = nif;
return(0);
}
void
netif_detach(nif)
struct netif *nif;
{
struct devdata *dd;
dd = nif->nif_devdata;
if (dd == NULL)
return;
dd->dd_opens--;
if (dd->dd_opens > 0)
return;
netif_fini(dd);
nif->nif_devdata = NULL;
}
int
netif_open(aux)
void *aux;
{
struct netif *nif;
struct iodesc *s;
int fd, error;
/* find a free socket */
for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
if (s->io_netif == NULL)
goto found;
errno = EMFILE;
return (-1);
found:
bzero(s, sizeof(*s));
nif = &prom_nif;
error = netif_attach(nif, s);
if (error != 0) {
errno = error;
return (-1);
}
return (fd);
}
int
netif_close(fd)
int fd;
{
struct iodesc *s;
struct netif *nif;
if (fd < 0 || fd >= SOPEN_MAX) {
errno = EBADF;
return(-1);
}
s = &sockets[fd];
nif = s->io_netif;
/* Already closed? */
if (nif == NULL)
return(0);
netif_detach(nif);
s->io_netif = NULL;
return(0);
}
struct iodesc *
socktodesc(fd)
int fd;
{
if (fd < 0 || fd >= SOPEN_MAX) {
errno = EBADF;
return (NULL);
}
return (&sockets[fd]);
}
/*
* Send a packet. The ether header is already there.
* Return the length sent (or -1 on error).
*/
int
netif_put(desc, pkt, len)
struct iodesc *desc;
void *pkt;
size_t len;
{
struct netif *nif;
struct devdata *dd;
struct saioreq *si;
struct saif *sif;
char *dmabuf;
int rv, slen;
#ifdef NETIF_DEBUG
if (debug > 1) {
struct ether_header *eh;
printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
desc, pkt, len);
eh = pkt;
printf("dst: %s ", ether_sprintf(eh->ether_dhost));
printf("src: %s ", ether_sprintf(eh->ether_shost));
printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
}
#endif
nif = desc->io_netif;
dd = nif->nif_devdata;
si = &dd->dd_si;
sif = si->si_sif;
slen = len;
#ifdef PARANOID
if (sif == NULL)
panic("netif_put: no saif ptr\n");
#endif
/*
* Copy into our transmit buffer because the PROM
* network driver might continue using the packet
* after the sif_xmit call returns. We never send
* very much data anyway, so the copy is fine.
*/
if (slen > dd->tbuf_len)
panic("netif_put: slen=%d\n", slen);
bcopy(pkt, dd->tbuf, slen);
if (slen < 60) {
slen = 60;
}
rv = (*sif->sif_xmit)(si->si_devdata, dd->tbuf, slen);
#ifdef NETIF_DEBUG
if (debug > 1)
printf("netif_put: xmit returned %d\n", rv);
#endif
/*
* Just ignore the return value. If the PROM transmit
* function fails, it will make some noise, such as:
* le: No Carrier
*/
return len;
}
/*
* Receive a packet, including the ether header.
* Return the total length received (or -1 on error).
*/
int
netif_get(desc, pkt, maxlen, timo)
struct iodesc *desc;
void *pkt;
size_t maxlen;
time_t timo; /* seconds */
{
struct netif *nif;
struct devdata *dd;
struct saioreq *si;
struct saif *sif;
int tick0, tmo_ticks;
int rlen = 0;
#ifdef NETIF_DEBUG
if (debug > 1)
printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
pkt, maxlen, timo);
#endif
nif = desc->io_netif;
dd = nif->nif_devdata;
si = &dd->dd_si;
sif = si->si_sif;
tmo_ticks = timo * hz;
/* Have to receive into our own buffer and copy. */
do {
tick0 = getticks();
do {
rlen = (*sif->sif_poll)(si->si_devdata, dd->rbuf);
if (rlen != 0)
goto break2;
} while (getticks() == tick0);
} while (--tmo_ticks > 0);
/* No packet arrived. Better reset the interface. */
printf("netif_get: timeout; resetting\n");
(*sif->sif_reset)(si->si_devdata, si);
break2:
#ifdef NETIF_DEBUG
if (debug > 1)
printf("netif_get: received rlen=%d\n", rlen);
#endif
/* Need at least a valid Ethernet header. */
if (rlen < 12)
return -1;
/* If we went beyond our buffer, were dead! */
if (rlen > dd->rbuf_len)
panic("netif_get: rlen=%d\n", rlen);
/* The caller's buffer may be smaller... */
if (rlen > maxlen)
rlen = maxlen;
bcopy(dd->rbuf, pkt, rlen);
#ifdef NETIF_DEBUG
if (debug > 1) {
struct ether_header *eh = pkt;
printf("dst: %s ", ether_sprintf(eh->ether_dhost));
printf("src: %s ", ether_sprintf(eh->ether_shost));
printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
}
#endif
return rlen;
}

View File

@ -0,0 +1,17 @@
#include <stdarg.h>
#include "stand.h"
extern __dead void abort();
__dead void
panic(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
printf("\n");
va_end(ap);
abort();
}

View File

@ -0,0 +1,73 @@
#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;
int debug = 0;
/*
* 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()
{
struct bootparam *bp;
char c, *src, *dst;
#ifdef DEBUG
printf("prom_get_boot_info\n");
#endif
bp = *romVectorPtr->bootParam;
/* Get device and file names. */
src = bp->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 = bp->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;
debug++;
break;
}
}
}
if (debug) {
printf("Debug level %d - enter c to continue...", debug);
/* This will print "\nAbort at ...\n" */
asm(" trap #0");
}
}

View File

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

View File

@ -0,0 +1,26 @@
#include <stdarg.h>
#include <sys/types.h>
#include <machine/mon.h>
int
getchar()
{
return ( (*romVectorPtr->getChar)() );
}
int
peekchar()
{
return ( (*romVectorPtr->mayGet)() );
}
void
putchar(c)
int c;
{
if (c == '\n')
(*romVectorPtr->putChar)('\r');
(*romVectorPtr->putChar)(c);
}

View File

@ -0,0 +1,225 @@
/* $NetBSD: promdev.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
* 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.
*/
#include <sys/param.h>
#include <machine/mon.h>
#include <machine/pte.h>
#include <machine/saio.h>
#include "stand.h"
#include "dvma.h"
extern void set_pte __P((int, int));
extern int debug;
static int promdev_inuse;
static char *
prom_mapin(u_long physaddr, int length, int maptype);
/*
* Note: caller sets the fields:
* si->si_boottab
* si->si_ctlr
* si->si_unit
* si->si_boff
*/
int
prom_iopen(si)
struct saioreq *si;
{
struct boottab *ops;
struct devinfo *dip;
int error;
if (promdev_inuse)
return(EMFILE);
ops = si->si_boottab;
dip = ops->b_devinfo;
#ifdef DEBUG_PROM
if (debug) {
printf("Boot device type: %s\n", ops->b_desc);
printf("d_devbytes=%d\n", dip->d_devbytes);
printf("d_dmabytes=%d\n", dip->d_dmabytes);
printf("d_localbytes=%d\n", dip->d_localbytes);
printf("d_stdcount=%d\n", dip->d_stdcount);
printf("d_stdaddrs[%d]=%x\n", si->si_ctlr,
dip->d_stdaddrs[si->si_ctlr]);
printf("d_devtype=%d\n", dip->d_devtype);
printf("d_maxiobytes=%d\n", dip->d_maxiobytes);
}
#endif
if (si->si_ctlr > dip->d_stdcount) {
printf("Invalid controller number\n");
return(ENXIO);
}
dvma_init();
if (dip->d_devbytes) {
si->si_devaddr = prom_mapin(dip->d_stdaddrs[si->si_ctlr],
dip->d_devbytes, dip->d_devtype);
#ifdef DEBUG_PROM
if (debug)
printf("prom_iopen: devaddr=0x%x pte=0x%x\n",
si->si_devaddr, get_pte(si->si_devaddr));
#endif
}
if (dip->d_dmabytes) {
int addr, size;
/* try page-aligned address... */
size = dip->d_dmabytes + NBPG;
addr = (int) dvma_alloc(size);
addr = _round_page(addr);
si->si_dmaaddr = (char*) addr;
#ifdef DEBUG_PROM
if (debug)
printf("prom_iopen: dmaaddr=0x%x\n", si->si_dmaaddr);
#endif
}
if (dip->d_localbytes) {
si->si_devdata = alloc(dip->d_localbytes);
#ifdef DEBUG_PROM
if (debug)
printf("prom_iopen: devdata=0x%x\n", si->si_devdata);
#endif
}
/* OK, call the PROM device open routine. */
#ifdef DEBUG_PROM
if (debug)
printf("prom_iopen: calling prom open...\n");
#endif
error = (*ops->b_open)(si);
if (error != 0) {
printf("prom_iopen: \"%s\" error=%d\n",
ops->b_desc, error);
return (ENXIO);
}
#ifdef DEBUG_PROM
if (debug)
printf("prom_iopen: prom open returned %d\n", error);
#endif
promdev_inuse++;
return (0);
}
void
prom_iclose(si)
struct saioreq *si;
{
struct boottab *ops;
struct devinfo *dip;
if (promdev_inuse == 0)
return;
ops = si->si_boottab;
dip = ops->b_devinfo;
#ifdef DEBUG_PROM
if (debug)
printf("prom_iclose: calling prom close...\n");
#endif
(*ops->b_close)(si);
promdev_inuse = 0;
}
struct mapinfo {
int maptype;
int pgtype;
int base;
};
static struct mapinfo
prom_mapinfo[] = {
/* On-board memory, I/O */
{ MAP_MAINMEM, PGT_OBMEM, 0 },
{ MAP_OBIO, PGT_OBIO, 0 },
/* Multibus adapter */
{ MAP_MBMEM, PGT_VME_D16, 0xFF000000 },
{ MAP_MBIO, PGT_VME_D16, 0xFFFF0000 },
/* VME A16 */
{ MAP_VME16A16D, PGT_VME_D16, 0xFFFF0000 },
{ MAP_VME16A32D, PGT_VME_D32, 0xFFFF0000 },
/* VME A24 */
{ MAP_VME24A16D, PGT_VME_D16, 0xFF000000 },
{ MAP_VME24A32D, PGT_VME_D32, 0xFF000000 },
/* VME A32 */
{ 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 | (pa & PGOFSET)));
}

View File

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

View File

@ -0,0 +1,19 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $
SA_PROG= netboot
SRCS= boot.c conf.c version.c
OBJS= ${SRCS:S/.c/.o/g}
# Using local rules for these
OBJS+= dev_net.o globals.o
all: ${SA_PROG}.bin
.include <bsd.prog.mk>
dev_net.o : ${S}/lib/libsa/dev_net.c
${CC} ${CFLAGS} ${CPPFLAGS} -DSUN_BOOTPARAMS -c ${.IMPSRC}
globals.o : ${S}/lib/libsa/globals.c
${CC} ${CFLAGS} ${CPPFLAGS} -c ${.IMPSRC}

View File

@ -0,0 +1,80 @@
/* $NetBSD: boot.c,v 1.1.1.1 1997/03/13 16:27:28 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"
/*
* 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 netboot [%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: %s\n", file, strerror(errno));
prom_boothow |= RB_ASKNAME;
}
}

View File

@ -0,0 +1,19 @@
/* $NetBSD: conf.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
#include <sys/types.h>
#include <netinet/in.h>
#include "stand.h"
#include "nfs.h"
#include "dev_net.h"
struct fs_ops file_system[] = {
{ nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat },
};
int nfsys = 1;
struct devsw devsw[] = {
{ "net", net_strategy, net_open, net_close, net_ioctl },
};
int ndevs = 1;

View File

@ -0,0 +1,7 @@
/* $NetBSD: version.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
/*
* NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
*/
char *version = "$Revision: 1.1.1.1 $";

View File

@ -0,0 +1,9 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $
SA_PROG= tapeboot
SRCS= boot.c conf.c rawfs.c dev_tape.c version.c
all: ${SA_PROG}.bin
.include <bsd.prog.mk>

View File

@ -0,0 +1,83 @@
/* $NetBSD: boot.c,v 1.1.1.1 1997/03/13 16:27:28 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] = "1";
char line[80];
main()
{
char *cp, *file;
int io;
printf(">> NetBSD tapeboot [%s]\n", version);
prom_get_boot_info();
file = defname;
cp = prom_bootfile;
if (cp && *cp)
file = cp;
for (;;) {
if (prom_boothow & RB_ASKNAME) {
printf("tapeboot: segment? [1] ");
gets(line);
if (line[0])
file = line;
}
exec_sun(file, LOADADDR);
printf("tapeboot: %s: %s\n", file, strerror(errno));
prom_boothow |= RB_ASKNAME;
}
}

View File

@ -0,0 +1,20 @@
/* $NetBSD: conf.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
#include <stand.h>
#include <rawfs.h>
#include <dev_tape.h>
struct fs_ops file_system[] = {
{
rawfs_open, rawfs_close, rawfs_read,
rawfs_write, rawfs_seek, rawfs_stat,
},
};
int nfsys = 1;
struct devsw devsw[] = {
{ "tape", tape_strategy, tape_open, tape_close, tape_ioctl },
};
int ndevs = 1;
int debug;

View File

@ -0,0 +1,193 @@
/* $NetBSD: dev_tape.c,v 1.1.1.1 1997/03/13 16:27:28 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"
/* #include "dev_tape.h" XXX - needs stdarg.h */
extern int debug;
struct saioreq tape_ioreq;
/*
* This is a special version of devopen() for tape boot.
* In this version, the file name is a numeric string of
* one digit, which is passed to the device open so it
* can open the appropriate tape segment.
*/
int
devopen(f, fname, file)
struct open_file *f;
const char *fname; /* normally "1" */
char **file;
{
struct devsw *dp;
int error;
*file = (char*)fname;
dp = &devsw[0];
f->f_dev = dp;
/* The following will call tape_open() */
return (dp->dv_open(f, fname));
}
int
tape_open(f, fname)
struct open_file *f;
char *fname; /* partition number, i.e. "1" */
{
struct bootparam *bp;
struct saioreq *si;
int error, part;
#ifdef DEBUG
printf("tape_open: part=%s\n", fname);
#endif
/*
* Set the tape segment number to the one indicated
* by the single digit fname passed in above.
*/
if ((fname[0] < '0') && (fname[0] > '9')) {
return ENOENT;
}
part = fname[0] - '0';
/*
* Setup our part of the saioreq.
* (determines what gets opened)
*/
si = &tape_ioreq;
bzero((caddr_t)si, sizeof(*si));
bp = *romVectorPtr->bootParam;
si->si_boottab = bp->bootDevice;
si->si_ctlr = bp->ctlrNum;
si->si_unit = bp->unitNum;
si->si_boff = part; /* default = bp->partNum + 1; */
error = prom_iopen(si);
#ifdef DEBUG
printf("tape_open: prom_iopen returned 0x%x\n", error);
#endif
if (!error)
f->f_devdata = si;
return (error);
}
int
tape_close(f)
struct open_file *f;
{
struct saioreq *si;
#ifdef DEBUG
printf("tape_close: calling prom_iclose\n");
#endif
si = f->f_devdata;
prom_iclose(si);
f->f_devdata = NULL;
return 0;
}
int
tape_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
if (debug > 1)
printf("tape_strategy: size=%d dblk=%d\n", size, dblk);
#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
if (debug > 1)
printf("tape_strategy: xcnt = %x\n", xcnt);
#endif
/* At end of tape, xcnt == 0 (not an error) */
if (xcnt < 0)
return (EIO);
*rsize = xcnt;
return (0);
}
int
tape_ioctl()
{
return EIO;
}

View File

@ -0,0 +1,6 @@
int tape_open __P((struct open_file *, ...));
int tape_close __P((struct open_file *));
int tape_strategy __P((void *, int, daddr_t, size_t, void *, size_t *));
int tape_ioctl();

View File

@ -0,0 +1,201 @@
/* $NetBSD: rawfs.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* 4. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Gordon W. Ross
*
* 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.
*/
/*
* Raw file system - for stream devices like tapes.
* No random access, only sequential read allowed.
* This exists only to allow upper level code to be
* shielded from the fact that the device must be
* read only with whole block position and size.
*/
#include <sys/param.h>
#include <stand.h>
#include <rawfs.h>
extern int debug;
/* Our devices are generally willing to do 8K transfers. */
#define RAWFS_BSIZE 0x2000
/*
* In-core open file.
*/
struct file {
daddr_t fs_nextblk; /* block number to read next */
int fs_len; /* amount left in f_buf */
char * fs_ptr; /* read pointer into f_buf */
char fs_buf[RAWFS_BSIZE];
};
static int
rawfs_get_block __P((struct open_file *));
int rawfs_open(path, f)
char *path;
struct open_file *f;
{
struct file *fs;
/*
* The actual PROM driver has already been opened.
* Just allocate the I/O buffer, etc.
*/
fs = alloc(sizeof(struct file));
fs->fs_nextblk = 0;
fs->fs_len = 0;
fs->fs_ptr = fs->fs_buf;
#ifdef DEBUG_RAWFS
printf("rawfs_open: fs=0x%x\n", fs);
#endif
f->f_fsdata = fs;
return (0);
}
int rawfs_close(f)
struct open_file *f;
{
struct file *fs;
fs = (struct file *) f->f_fsdata;
f->f_fsdata = (void *)0;
#ifdef DEBUG_RAWFS
if (debug) {
printf("rawfs_close: breakpoint...", fs->fs_buf);
__asm (" trap #0");
}
#endif
if (fs != (struct file *)0)
free(fs, sizeof(*fs));
return (0);
}
int rawfs_read(f, start, size, resid)
struct open_file *f;
void *start;
u_int size;
u_int *resid;
{
struct file *fs = (struct file *)f->f_fsdata;
char *addr = start;
int error = 0;
size_t csize;
while (size != 0) {
if (fs->fs_len == 0)
if ((error = rawfs_get_block(f)) != 0)
break;
if (fs->fs_len <= 0)
break; /* EOF */
csize = size;
if (csize > fs->fs_len)
csize = fs->fs_len;
bcopy(fs->fs_ptr, addr, csize);
fs->fs_ptr += csize;
fs->fs_len -= csize;
addr += csize;
size -= csize;
}
if (resid)
*resid = size;
return (error);
}
int rawfs_write(f, start, size, resid)
struct open_file *f;
void *start;
size_t size;
size_t *resid; /* out */
{
#ifdef DEBUG_RAWFS
panic("rawfs_write");
#endif
return (EROFS);
}
off_t rawfs_seek(f, offset, where)
struct open_file *f;
off_t offset;
int where;
{
#ifdef DEBUG_RAWFS
panic("rawfs_seek");
#endif
return (EFTYPE);
}
int rawfs_stat(f, sb)
struct open_file *f;
struct stat *sb;
{
#ifdef DEBUG_RAWFS
panic("rawfs_stat");
#endif
return (EFTYPE);
}
/*
* Read a block from the underlying stream device
* (In our case, a tape drive.)
*/
static int
rawfs_get_block(f)
struct open_file *f;
{
struct file *fs;
int error, len;
fs = (struct file *)f->f_fsdata;
fs->fs_ptr = fs->fs_buf;
twiddle();
error = f->f_dev->dv_strategy(f->f_devdata, F_READ,
fs->fs_nextblk, RAWFS_BSIZE, fs->fs_buf, &len);
if (!error) {
fs->fs_len = len;
fs->fs_nextblk += (RAWFS_BSIZE / DEV_BSIZE);
}
return (error);
}

View File

@ -0,0 +1,15 @@
/* $NetBSD: rawfs.h,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
/*
* Raw file system - for stream devices like tapes.
* No random access, only sequential read allowed.
*/
int rawfs_open __P((char *path, struct open_file *f));
int rawfs_close __P((struct open_file *f));
int rawfs_read __P((struct open_file *f, void *buf,
u_int size, u_int *resid));
int rawfs_write __P((struct open_file *f, void *buf,
u_int size, u_int *resid));
off_t rawfs_seek __P((struct open_file *f, off_t offset, int where));
int rawfs_stat __P((struct open_file *f, struct stat *sb));

View File

@ -0,0 +1,10 @@
/* $NetBSD: version.c,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $ */
/*
* NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
*
* Added "rawfs" to do read buffering and ensure that all
* device access stays strictly on block boundaries.
*/
char *version = "$Revision: 1.1.1.1 $";

View File

@ -0,0 +1,9 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/03/13 16:27:28 gwr Exp $
SA_PROG= ufsboot
SRCS= boot.c conf.c version.c
all: ${SA_PROG}.bin
.include <bsd.prog.mk>

View File

@ -0,0 +1,83 @@
/* $NetBSD: boot.c,v 1.1.1.1 1997/03/13 16:27:28 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: %s\n", file, strerror(errno));
prom_boothow |= RB_ASKNAME;
}
}

View File

@ -0,0 +1,16 @@
/* $NetBSD: conf.c,v 1.1.1.1 1997/03/13 16:27:28 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,7 @@
/* $NetBSD: version.c,v 1.1.1.1 1997/03/13 16:27:29 gwr Exp $ */
/*
* NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
*/
char *version = "$Revision: 1.1.1.1 $";