This is the new unified bootstrap, sometimes known previously as the

'three-stage' bootstrap.
There are a number of caveats with the code in its current state:
 - The i386 bootstrap only supports booting from a floppy.
 - The kernel and kld do not yet know how to deal with the extended
   information and module summary passed in.
 - PnP-based autodetection and demand loading of modules is not implemented.
 - i386 ELF kernel loading is not ready yet.
 - The i386 bootstrap is loaded via an ugly blockmap.

On the alpha, both net- and disk-booting (SRM console machines only) is
supported.  No blockmaps are used by this code.

Obtained from:	Parts from the NetBSD/i386 standalone bootstrap.
This commit is contained in:
Mike Smith 1998-08-21 03:17:42 +00:00
parent 2bd323977f
commit c2f9d95de5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MSMITH/; revision=38465
105 changed files with 13800 additions and 0 deletions

4
sys/boot/Makefile Normal file
View File

@ -0,0 +1,4 @@
# Pick the subdir based on the target architecture.
SUBDIR= ${MACHINE_ARCH}
.include <bsd.subdir.mk>

6
sys/boot/alpha/Makefile Normal file
View File

@ -0,0 +1,6 @@
# $Id$
SUBDIR= libalpha
SUBDIR+= boot1 boot2 netboot
.include <bsd.subdir.mk>

View File

@ -0,0 +1,6 @@
# Options used when building app-specific libalpha components
PRIMARY_LOAD_ADDRESS= 20000000 # "Region 1 start"
SECONDARY_LOAD_ADDRESS= 2000c000 # "Region 1 start" + 48k
HEAP_LIMIT= 20040000 # "Region 1 start" + 256k
BINDIR= /usr/mdec

View File

@ -0,0 +1,47 @@
# $NetBSD: Makefile,v 1.15 1998/03/28 00:21:35 thorpej Exp $
.include <../Makefile.inc>
PROG = boot1
.PATH: ${.CURDIR}/../../common
.PATH: ${.CURDIR}/../libalpha
SRCS= start.S boot1.c sys.c
CFLAGS+= -mno-fp-regs
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
LIBSTANDDIR= /home/dfr/FreeBSD/alpha/src/lib/libstand
LIBSTAND= ${LIBSTANDDIR}/obj/libstand.a
CFLAGS+= -I${LIBSTANDDIR}
LIBALPHA= ${.CURDIR}/../libalpha/obj/libalpha.a
CFLAGS+= -I${.CURDIR}/..
CFLAGS+= -DSECONDARY_LOAD_ADDRESS=0x${SECONDARY_LOAD_ADDRESS} -DMINIMAL
NOMAN=1
STRIP=
BOOT_RELOC = ${PRIMARY_LOAD_ADDRESS}
CLEANFILES+= ${PROG}.sym ${PROG}.nosym ${PROG}.list
all: ${PROG}
afterinstall:
ln -sf boot1 /usr/mdec/sdboot
${PROG}.nosym: ${PROG}.sym
cp ${PROG}.sym ${PROG}.nosym
strip ${PROG}.nosym
${PROG}: ${PROG}.nosym
objcopy -O binary ${PROG}.nosym ${PROG}
.include <bsd.prog.mk>
start.o: ${.CURDIR}/../libalpha/start.S
${CC} -c -DPRIMARY_BOOTBLOCK $<
${PROG}.sym: ${OBJS} ${LIBKERN}
${LD} -M -Ttext ${BOOT_RELOC} -N -e start -o ${PROG}.sym ${OBJS} \
${LIBSTAND} ${LIBALPHA} ${LIBSTAND} > ${.OBJDIR}/${PROG}.list
size ${PROG}.sym

View File

@ -0,0 +1,188 @@
/*
* $Id$
* From $NetBSD: bootxx.c,v 1.4 1997/09/06 14:08:29 drochner Exp $
*/
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#include <sys/param.h>
#include <machine/prom.h>
#define DEBUGxx
extern end[];
int errno;
char *heap = (char*) end;
void
putchar(int c)
{
if (c == '\n')
prom_putchar('\r');
prom_putchar(c);
}
void
puts(const char *s)
{
while (*s)
putchar(*s++);
}
void *
malloc(size_t size)
{
char *p = heap;
size = (size + 7) & ~7;
heap += size;
return p;
}
void
free(void * p)
{
}
void
panic(const char *message, ...)
{
puts(message);
puts("\r\n");
halt();
}
int prom_fd = 0;
int
devopen()
{
prom_return_t ret;
char devname[64];
if (prom_fd)
return;
ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof devname);
ret.bits = prom_open(devname, ret.u.retval + 1);
if (ret.u.status)
panic("devopen: open failed\n");
prom_fd = ret.u.retval;
/* XXX read disklabel and setup partition offset */
return 0;
}
#ifdef DEBUG
void
puthex(u_long v)
{
int digit;
char hex[] = "0123456789abcdef";
if (!v) {
puts("0");
return;
}
for (digit = 0; v >= (0x10L << digit); digit += 4)
;
for (; digit >= 0; digit -= 4)
putchar(hex[(v >> digit) & 0xf]);
}
#endif
void
devread(char *buf, int block, size_t size)
{
#ifdef DEBUG
puts("devread(");
puthex((u_long)buf);
puts(",");
puthex(block);
puts(",");
puthex(size);
puts(")\n");
#endif
prom_read(prom_fd, size, buf, block);
}
void
devclose()
{
if (prom_fd) {
prom_close(prom_fd);
prom_fd = 0;
}
}
void
loadfile(char *name, char *addr)
{
int n;
if (openrd(name)) {
puts("Can't open file ");
puts(name);
puts("\n");
halt();
}
do {
n = read(addr, 1024);
addr += n;
twiddle();
} while (n > 0);
devclose();
}
void
main()
{
char *loadaddr = (char*) SECONDARY_LOAD_ADDRESS;
char *p;
void (*entry) __P((void));
int i;
init_prom_calls();
loadfile("/boot/boot2", loadaddr);
entry = (void (*)())loadaddr;
(*entry)();
}

187
sys/boot/alpha/boot1/sys.c Normal file
View File

@ -0,0 +1,187 @@
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:36:34 rpd
* fromL Id: sys.c,v 1.21 1997/06/09 05:10:56 bde Exp
* $Id$
*/
#include <sys/param.h>
#include <sys/time.h>
#include <ufs/ffs/fs.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <sys/dirent.h>
struct fs *fs;
struct inode inode;
int boff = 0;
#if 0
/* #define BUFSIZE 4096 */
#define BUFSIZE MAXBSIZE
static char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
#endif
#define BUFSIZE 8192
#define MAPBUFSIZE BUFSIZE
static char buf[BUFSIZE], fsbuf[BUFSIZE], iobuf[BUFSIZE];
static char mapbuf[MAPBUFSIZE];
static int mapblock;
int poff;
#ifdef RAWBOOT
#define STARTBYTE 8192 /* Where on the media the kernel starts */
#endif
static int block_map(int file_block);
static int find(char *path);
int
read(char *buffer, int count)
{
int logno, off, size;
int cnt2, bnum2;
struct fs *fs_copy;
int n = 0;
if (poff + count > inode.i_size)
count = inode.i_size - poff;
while (count > 0 && poff < inode.i_size) {
fs_copy = fs;
off = blkoff(fs_copy, poff);
logno = lblkno(fs_copy, poff);
cnt2 = size = blksize(fs_copy, &inode, logno);
bnum2 = fsbtodb(fs_copy, block_map(logno)) + boff;
if ( (!off) && (size <= count)) {
devread(buffer, bnum2, cnt2);
} else {
size -= off;
if (size > count)
size = count;
devread(iobuf, bnum2, cnt2);
bcopy(iobuf+off, buffer, size);
}
buffer += size;
count -= size;
poff += size;
n += size;
}
return n;
}
static int
find(char *path)
{
char *rest, ch;
int block, off, loc, ino = ROOTINO;
struct dirent *dp;
char list_only;
list_only = (path[0] == '?' && path[1] == '\0');
loop:
devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
bcopy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
(void *)&inode.i_din,
sizeof (struct dinode));
if (!*path)
return 1;
while (*path == '/')
path++;
if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
return 0;
for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
*rest = 0;
loc = 0;
do {
if (loc >= inode.i_size) {
if (list_only) {
putchar('\n');
return -1;
} else {
return 0;
}
}
if (!(off = blkoff(fs, loc))) {
block = lblkno(fs, loc);
devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
blksize(fs, &inode, block));
}
dp = (struct dirent *)(iobuf + off);
loc += dp->d_reclen;
if (dp->d_fileno && list_only) {
puts(dp->d_name);
putchar(' ');
}
} while (!dp->d_fileno || strcmp(path, dp->d_name));
ino = dp->d_fileno;
*(path = rest) = ch;
goto loop;
}
static int
block_map(int file_block)
{
int bnum;
if (file_block < NDADDR)
return(inode.i_db[file_block]);
if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
devread(mapbuf, bnum, fs->fs_bsize);
mapblock = bnum;
}
return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
}
int
openrd(char *name)
{
int ret;
if (devopen())
return 1;
/*
* Load Filesystem info (mount the device).
*/
devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
/*
* Find the actual FILE on the mounted device.
*/
ret = find(name);
if (ret == 0)
return 1;
if (ret < 0)
return -1;
poff = 0;
return 0;
}

View File

@ -0,0 +1,69 @@
# $NetBSD: Makefile,v 1.12 1998/02/19 14:18:36 drochner Exp $
BASE= boot2
PROG= ${BASE}
NOMAN=
NEWVERSWHAT= "SRM disk boot"
.PATH: ${.CURDIR}/../common
# i386-specific bootstrap sources
SRCS+= main.c conf.c
# Always add MI sources
.PATH: ${.CURDIR}/../../common
.include <${.CURDIR}/../../common/Makefile.inc>
CFLAGS+= -mno-fp-regs
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
# Verbose ls causes extra heap usage
CFLAGS+= -DVERBOSE_LS
CLEANFILES+= vers.c vers.o gensetdefs.o gensetdefs setdef0.o setdef1.o \
setdefs.h start.o
CLEANFILES+= ${BASE} ${BASE}.sym ${BASE}.list
CFLAGS+= -Wall
# XXX fix to use "standard" versions
LIBSTANDDIR= /home/dfr/FreeBSD/alpha/src/lib/libstand
LIBSTAND= ${LIBSTANDDIR}/obj/libstand.a
CFLAGS+= -I${LIBSTANDDIR}
LIBALPHA= ${.CURDIR}/../libalpha/obj/libalpha.a
CFLAGS+= -I${.CURDIR}/..
CRT= start.o
STRIP=
all: ${BASE}
vers.o: ${.CURDIR}/newvers.sh ${.CURDIR}/Makefile
sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
${CC} -c vers.c
${BASE}: ${BASE}.sym
objcopy -O binary ${BASE}.sym ${BASE}
${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBALPHA} ${CRT} vers.o setdef0.o setdef1.o
${LD} -o ${BASE}.sym -M -e start -N -Ttext ${SECONDARY_LOAD_ADDRESS} \
${CRT} setdef0.o ${OBJS} setdef1.o \
vers.o ${LIBSTAND} ${LIBALPHA} ${LIBSTAND} >${.OBJDIR}/${BASE}.list
# Other fragments still to be brought in from ../Makfile.booters?
start.o: ${.CURDIR}/../libalpha/start.S
${CC} -c $<
setdef0.o: setdefs.h
setdef1.o: setdefs.h
.include <bsd.prog.mk>
setdefs.h: gensetdefs ${OBJS}
@echo Generating linker sets
@./gensetdefs ${OBJS} >setdefs.h
gensetdefs: gensetdefs.o
${CC} -static gensetdefs.o -o $@
gensetdefs.o: gensetdefs.c
${CC} -c $<

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
/*
* $Id$
* From $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $
*/
/*
* Copyright (c) 1997
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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 <stand.h>
#include "libalpha/libalpha.h"
/*
* We could use linker sets for some or all of these, but
* then we would have to control what ended up linked into
* the bootstrap. So it's easier to conditionalise things
* here.
*
* XXX rename these arrays to be consistent and less namespace-hostile
*/
/* Exported for libstand */
struct devsw *devsw[] = {
&srmdisk,
NULL
};
struct fs_ops *file_system[] = {
&ufs_fsops,
&zipfs_fsops,
NULL
};
/* Exported for alpha only */
/*
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
struct module_format *module_formats[] = {
&alpha_elf,
NULL
};
/*
* Consoles
*
* We don't prototype these in libalpha.h because they require
* data structures from bootstrap.h as well.
*/
extern struct console promconsole;
struct console *consoles[] = {
&promconsole,
NULL
};

View File

@ -0,0 +1,44 @@
#!/bin/sh -
#
# $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $
#
# Copyright (c) 1984, 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.
#
# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
u=${USER-root} h=`hostname` t=`date`
r=`head -n 6 $1 | tail -n 1 | awk -F: ' { print $1 } '`
echo "char bootprog_name[] = \"FreeBSD/alpha ${2}\";" > vers.c
echo "char bootprog_rev[] = \"${r}\";" >> vers.c
echo "char bootprog_date[] = \"${t}\";" >> vers.c
echo "char bootprog_maker[] = \"${u}@${h}\";" >> vers.c

View File

@ -0,0 +1,2 @@
/* $Id$ */
DEFINE_SET(Xcommand_set, 15);

View File

@ -0,0 +1,4 @@
char bootprog_name[] = "FreeBSD/alpha SRM disk boot";
char bootprog_rev[] = "0.1";
char bootprog_date[] = "Mon Aug 17 10:38:19 BST 1998";
char bootprog_maker[] = "dfr@salmon.nlsystems.com";

View File

@ -0,0 +1,7 @@
$Id$
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
0.1: Initial i386 version, germinated from the NetBSD i386
standalone, but enormously modified.

View File

@ -0,0 +1,313 @@
/*-
* Copyright (c) 1997 John D. Polstra.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id: gensetdefs.c,v 1.2 1998/06/14 13:44:44 dfr Exp $
*/
#include <sys/types.h>
#include <elf.h>
#include <err.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASHSIZE 1009u /* Number of hash chains. */
#define PREFIX ".set." /* Section name prefix for linker sets. */
/* One entry in the hash table. */
typedef struct hashent {
struct hashent *next; /* Next entry with the same hash. */
char *name; /* Name of the linker set. */
size_t size; /* Size in bytes. */
} hashent;
/* Allocate storage for "count" objects of type "type". */
#define NEW(type, count) ((type *) xmalloc((count) * sizeof(type)))
static hashent *hashtab[HASHSIZE]; /* Hash chain heads. */
static void enter(const char *, size_t);
static int enter_sets(const char *);
static unsigned int hash(const char *);
static hashent *merge(void);
static int my_byte_order(void);
static void *xmalloc(size_t);
static char *xstrdup(const char *);
/*
* This is a special-purpose program to generate the linker set definitions
* needed when building an ELF kernel. Its arguments are the names of
* ELF object files. It scans the section names of the object files,
* building a table of those that begin with ".set.", which represent
* linker sets. Finally, for each set "foo" with "count" elements, it
* writes a line "DEFINE_SET(foo, count);" to the standard output.
*/
int
main(int argc, char **argv)
{
int i;
int status = EXIT_SUCCESS;
hashent *list;
for (i = 1; i < argc; i++)
if (enter_sets(argv[i]) == -1)
status = EXIT_FAILURE;
list = merge();
while (list != NULL) {
hashent *next;
printf("DEFINE_SET(%s, %lu);\n", list->name,
(unsigned long) (list->size / sizeof (void *)));
next = list->next;
free(list->name);
free(list);
list = next;
}
return (status);
}
/*
* Enter the given string into the hash table, if it is not already there.
* Each hash chain is kept sorted, so that it will be easy to merge the
* chains to get a single sorted list.
*/
static void
enter(const char *name, size_t size)
{
int c = 0;
hashent *entp;
hashent **linkp;
hashent *newp;
linkp = &hashtab[hash(name) % HASHSIZE];
while ((entp = *linkp) != NULL && (c = strcmp(name, entp->name)) > 0)
linkp = &entp->next;
if (entp == NULL || c != 0) { /* Not found; create a new entry. */
newp = NEW(hashent, 1);
newp->name = xstrdup(name);
newp->size = 0;
newp->next = entp;
*linkp = newp;
entp = newp;
}
entp->size += size;
}
/*
* Return a hash value for the given string.
*/
static unsigned int
hash(const char *s)
{
unsigned char ch;
unsigned int h = 0;
while((ch = *s) != '\0') {
h = 9*h + ch;
s++;
}
return (h);
}
/*
* Enter the linker sets from the given ELF object file. Returns 0 on
* success, or -1 if an error occurred.
*/
static int
enter_sets(const char *filename)
{
int i;
FILE *iop;
Elf64_Shdr *shdr;
char *shstr;
Elf64_Ehdr ehdr;
if ((iop = fopen(filename, "rb")) == NULL) {
warn("%s", filename);
return (-1);
}
if (fread(&ehdr, sizeof ehdr, 1, iop) != 1 ||
ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
ehdr.e_ident[EI_MAG3] != ELFMAG3) {
warnx("%s: not an ELF file", filename);
fclose(iop);
return (-1);
}
if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
warnx("%s: unsupported ELF version", filename);
fclose(iop);
return (-1);
}
if (ehdr.e_ident[EI_DATA] != my_byte_order()) {
warnx("%s: unsupported byte order", filename);
fclose(iop);
return (-1);
}
if (ehdr.e_shoff == 0) {
warnx("%s: no section table", filename);
fclose(iop);
return (-1);
}
if (ehdr.e_shstrndx == SHN_UNDEF) {
warnx("%s: no section name string table", filename);
fclose(iop);
return (-1);
}
shdr = NEW(Elf64_Shdr, ehdr.e_shnum);
if (fseek(iop, ehdr.e_shoff, SEEK_SET) == -1) {
warn("%s", filename);
free(shdr);
fclose(iop);
return (-1);
}
if (fread(shdr, sizeof *shdr, ehdr.e_shnum, iop) != ehdr.e_shnum) {
warnx("%s: truncated section table", filename);
free(shdr);
fclose(iop);
return (-1);
}
shstr = NEW(char, shdr[ehdr.e_shstrndx].sh_size);
if (fseek(iop, shdr[ehdr.e_shstrndx].sh_offset, SEEK_SET) == -1) {
warn("%s", filename);
free(shstr);
free(shdr);
fclose(iop);
return (-1);
}
if (fread(shstr, sizeof *shstr, shdr[ehdr.e_shstrndx].sh_size, iop) !=
shdr[ehdr.e_shstrndx].sh_size) {
warnx("%s: truncated section name string table", filename);
free(shstr);
free(shdr);
fclose(iop);
return (-1);
}
for (i = 1; i < ehdr.e_shnum; i++) {
const char *name = shstr + shdr[i].sh_name;
if (strncmp(name, PREFIX, sizeof (PREFIX) - 1) == 0)
enter(name + sizeof (PREFIX) - 1, shdr[i].sh_size);
}
free(shstr);
free(shdr);
fclose(iop);
return (0);
}
/*
* Destructively merge all the sorted hash chains into a single sorted
* list, and return a pointer to its first element.
*/
static hashent *
merge(void)
{
unsigned int numchains = HASHSIZE;
while (numchains > 1) { /* More merging to do. */
unsigned int lo = 0;
/*
* Merge chains pairwise from the outside in, halving the
* number of chains.
*/
while (numchains - lo >= 2) {
hashent **linkp = &hashtab[lo];
hashent *l1 = hashtab[lo++];
hashent *l2 = hashtab[--numchains];
while (l1 != NULL && l2 != NULL) {
if (strcmp(l1->name, l2->name) < 0) {
*linkp = l1;
linkp = &l1->next;
l1 = l1->next;
} else {
*linkp = l2;
linkp = &l2->next;
l2 = l2->next;
}
}
*linkp = l1==NULL ? l2 : l1;
}
}
return (hashtab[0]);
}
/*
* Determine the host byte order.
*/
static int
my_byte_order(void)
{
static unsigned short s = 0xbbaa;
int byte0;
byte0 = *(unsigned char *)&s;
if (byte0 == 0xaa)
return (ELFDATA2LSB);
else if (byte0 == 0xbb)
return (ELFDATA2MSB);
else
return (ELFDATANONE);
}
/*
* Allocate a chunk of memory and return a pointer to it. Die if the
* malloc fails.
*/
static void *
xmalloc(size_t size)
{
void *p;
p = malloc(size);
if (p == NULL)
err(EXIT_FAILURE, "malloc");
return (p);
}
/*
* Duplicate a string and return a pointer to the copy. Die if there is
* not enough memory.
*/
static char *
xstrdup(const char *s)
{
int size;
size = strlen(s) + 1;
return (memcpy(xmalloc(size), s, size));
}

View File

@ -0,0 +1,178 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* Copyright (c) 1998 Doug Rabson <dfr@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <string.h>
#include <sys/param.h>
#include <machine/rpb.h>
#include <machine/prom.h>
#include "bootstrap.h"
#include "libalpha/libalpha.h"
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
struct alpha_devdesc currdev; /* our current device */
struct arch_switch archsw; /* MI/MD interface boundary */
extern char end[];
extern void OSFpal(void);
extern void halt(void);
unsigned long
memsize()
{
struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
struct mddt *mddtp;
struct mddt_cluster *memc;
int i;
unsigned long total = 0;
mddtp = (struct mddt *)(((caddr_t)hwrpb) + hwrpb->rpb_memdat_off);
for (i = 0; i < mddtp->mddt_cluster_cnt; i++) {
memc = &mddtp->mddt_clusters[i];
total += memc->mddt_pg_cnt << PAGE_SHIFT;
}
return total;
}
void
main(void)
{
int i;
char bootfile[128];
/*
* Initialise the heap as early as possible. Once this is done, alloc() is usable.
* The stack is buried inside us, so this is safe
*/
setheap((void *)end, (void *)0x20040000);
/*
* XXX Chicken-and-egg problem; we want to have console output early, but some
* console attributes may depend on reading from eg. the boot device, which we
* can't do yet.
*
* We can use printf() etc. once this is done.
*/
cons_probe();
/* switch to OSF pal code. */
OSFpal();
/*
* March through the device switch probing for things.
*/
for (i = 0; devsw[i] != NULL; i++)
if (devsw[i]->dv_init != NULL)
(devsw[i]->dv_init)();
printf("\n");
printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
printf(">> Memory: %ld k\n", memsize() / 1024);
/* We're booting from an SRM disk, try to spiff this */
currdev.d_dev = devsw[0]; /* XXX presumes that biosdisk is first in devsw */
currdev.d_type = currdev.d_dev->dv_type;
currdev.d_kind.srmdisk.unit = 0;
currdev.d_kind.srmdisk.slice = -1; /* XXX should be able to detect this, default to autoprobe */
currdev.d_kind.srmdisk.partition = 0; /* default to 'a' */
/* Create alpha-specific variables */
prom_getenv(PROM_E_BOOTED_FILE, bootfile, sizeof(bootfile));
if (bootfile[0])
setenv("bootfile", bootfile, 1);
env_setenv("currdev", EV_VOLATILE, alpha_fmtdev(&currdev), alpha_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, alpha_fmtdev(&currdev), env_noset, env_nounset);
setenv("LINES", "24", 1); /* optional */
archsw.arch_autoload = alpha_autoload;
archsw.arch_boot = alpha_boot;
archsw.arch_getdev = alpha_getdev;
/*
* XXX should these be in the MI source?
*/
source("/boot/boot.config");
interact(); /* doesn't return */
}
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
static int
command_reboot(int argc, char *argv[])
{
printf("Rebooting...\n");
delay(1000000);
reboot();
/* Note: we shouldn't get to this point! */
panic("Reboot failed!");
exit(0);
}
COMMAND_SET(halt, "halt", "halt the system", command_halt);
static int
command_halt(int argc, char *argv[])
{
halt(); /* never returns */
return(CMD_OK);
}
#if 0
COMMAND_SET(stack, "stack", "show stack usage", command_stack);
static int
command_stack(int argc, char *argv[])
{
char *cp;
for (cp = &stackbase; cp < &stacktop; cp++)
if (*cp != 0)
break;
printf("%d bytes of stack used\n", &stacktop - cp);
return(CMD_OK);
}
#endif
COMMAND_SET(heap, "heap", "show heap usage", command_heap);
static int
command_heap(int argc, char *argv[])
{
printf("heap base at %p, top at %p, used %ld\n", end, sbrk(0), sbrk(0) - end);
return(CMD_OK);
}

View File

@ -0,0 +1,49 @@
/*-
* Copyright (c) 1997 John D. Polstra
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id: setdef0.c,v 1.1 1998/06/10 10:53:12 dfr Exp $
*/
#ifdef __ELF__
#include <sys/param.h>
#include <sys/kernel.h>
/*
* DEFINE_SET creates the section and label for a set, and emits the
* count word at the front of it.
*/
#define DEFINE_SET(set, count) \
__asm__(".section .set." #set ",\"aw\""); \
__asm__(".globl " #set); \
__asm__(".type " #set ",@object"); \
__asm__(".p2align 3"); \
__asm__(#set ":"); \
__asm__(".quad " #count); \
__asm__(".previous")
#include "setdefs.h" /* Contains a `DEFINE_SET' for each set */
#endif /* __ELF__ */

View File

@ -0,0 +1,41 @@
/*-
* Copyright (c) 1997 John D. Polstra
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id: setdef1.c,v 1.1 1998/06/10 10:53:13 dfr Exp $
*/
#ifdef __ELF__
/*
* DEFINE_SET emits the NULL terminator for a set.
*/
#define DEFINE_SET(set, count) \
__asm__(".section .set." #set ",\"aw\""); \
__asm__(".quad 0"); \
__asm__(".previous")
#include "setdefs.h" /* Contains a `DEFINE_SET' for each set */
#endif /* __ELF__ */

View File

@ -0,0 +1,23 @@
# $Id$
LIB= alpha
NOPIC= true
NOPROFILE= true
INTERNALLIB= true
# XXX hack to pick up stand.h
CFLAGS= -I/home/dfr/FreeBSD/alpha/src/lib/libstand
CFLAGS+= -DDEBUG
# Pick up the bootstrap header for some interface items
CFLAGS+= -I${.CURDIR}/../../common -mno-fp-regs
CFLAGS+= -DDISK_DEBUG
#CPPFLAGS+= -DNO_DISKLABEL
#CPPFLAGS+= -DSAVE_MEMORY
SRCS= OSFpal.c elf_freebsd.c prom.c prom_disp.S prom_swpal.S start.S \
pal.S reboot.c delay.c time.c alpha_module.c devicename.c \
srmdisk.c srmnet.c getsecs.c
.include <bsd.lib.mk>

View File

@ -0,0 +1,71 @@
/*
* $Id$
* From $NetBSD: OSFpal.c,v 1.5 1998/06/24 01:33:19 ross Exp $
*/
/*
* Copyright (c) 1994, 1996 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Keith Bostic
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#include <sys/types.h>
#include <stand.h>
#include <machine/prom.h>
#include <machine/rpb.h>
#include <machine/alpha_cpu.h>
vm_offset_t ptbr_save;
#include "common.h"
void
OSFpal()
{
struct rpb *r;
struct pcs *p;
r = (struct rpb *)HWRPB_ADDR;
/*
* Note, cpu_number() is a VMS op, can't necessarily call it.
* Real fun: PAL_VMS_mfpr_whami == PAL_OSF1_rti...
* We might not be rpb_primary_cpu_id, but it is supposed to go
* first so the answer should apply to everyone.
*/
p = LOCATE_PCS(r, r->rpb_primary_cpu_id);
printf("VMS PAL rev: 0x%lx\n", p->pcs_palrevisions[PALvar_OpenVMS]);
printf("OSF PAL rev: 0x%lx\n", p->pcs_palrevisions[PALvar_OSF1]);
if(p->pcs_pal_type==PAL_TYPE_OSF1) {
printf("OSF PAL code already running.\n");
ptbr_save = ((struct alpha_pcb *)p)->apcb_ptbr;
printf("PTBR is: 0x%lx\n", ptbr_save);
return;
}
switch_palcode();
printf("Switch to OSF PAL code succeeded.\n");
}

View File

@ -0,0 +1,64 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* alpha-specific module functionality.
*
*/
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
#include "libalpha.h"
/*
* Look for a method and having found it, boot the kernel module.
*/
int
alpha_boot(void)
{
int i;
for (i = 0; module_formats[i] != NULL; i++) {
if (((loaded_modules->m_flags & MF_FORMATMASK) == module_formats[i]->l_format) &&
(module_formats[i]->l_exec != NULL)) {
return((module_formats[i]->l_exec)(loaded_modules));
}
}
}
/*
* Use voodoo to load modules required by current hardware.
*/
int
alpha_autoload(void)
{
/* XXX use PnP to locate stuff here */
return(0);
}

View File

@ -0,0 +1,57 @@
/*
* $Id$
* From $NetBSD: bbinfo.h,v 1.2 1997/04/06 08:40:57 cgd Exp $
*/
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
struct bbinfoloc {
u_int64_t magic1;
u_int64_t start;
u_int64_t end;
u_int64_t pad1[4];
u_int64_t magic2;
};
struct bbinfo {
int32_t cksum;
int32_t nblocks;
int32_t bsize;
u_int32_t pad1[8];
int32_t blocks[1];
};
struct netbbinfo {
u_int64_t magic1;
u_int8_t set;
u_int8_t ether_addr[6];
u_int8_t force;
u_int64_t pad1[4];
u_int64_t cksum;
u_int64_t magic2;
};

View File

@ -0,0 +1,11 @@
/*
* $Id$
* From: $NetBSD: common.h,v 1.2 1998/01/05 07:02:48 perry Exp $
*/
int prom_open __P((char*, int));
void OSFpal __P((void));
void halt __P((void));
u_int64_t prom_dispatch __P((int, ...));
int cpu_number __P((void));
void switch_palcode __P((void));

View File

@ -0,0 +1,40 @@
/*-
* Copyright (c) 1998 Doug Rabson
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <machine/rpb.h>
void
delay(int usecs)
{
struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
unsigned long start = alpha_rpcc();
unsigned long end = start + (hwrpb->rpb_cc_freq * usecs) / 1000000;
while (alpha_rpcc() < end)
;
}

View File

@ -0,0 +1,232 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <string.h>
#include <sys/disklabel.h>
#include "bootstrap.h"
#include "libalpha.h"
static int alpha_parsedev(struct alpha_devdesc **dev, char *devspec, char **path);
/*
* Point (dev) at an allocated device specifier for the device matching the
* path in (devspec). If it contains an explicit device specification,
* use that. If not, use the default device.
*/
int
alpha_getdev(void **vdev, char *devspec, char **path)
{
struct alpha_devdesc **dev = (struct alpha_devdesc **)vdev;
int rv;
/*
* If it looks like this is just a path and no
* device, go with the current device.
*/
if ((devspec == NULL) ||
(devspec[0] == '/') ||
(strchr(devspec, ':') == NULL)) {
if (((rv = alpha_parsedev(dev, getenv("currdev"), NULL)) == 0) &&
(path != NULL))
*path = devspec;
return(rv);
}
/*
* Try to parse the device name off the beginning of the devspec
*/
return(alpha_parsedev(dev, devspec, path));
}
/*
* Point (dev) at an allocated device specifier matching the string version
* at the beginning of (devspec). Return a pointer to the remaining
* text in (path).
*
* In all cases, the beginning of (devspec) is compared to the names
* of known devices in the device switch, and then any following text
* is parsed according to the rules applied to the device type.
*
* For disk-type devices, the syntax is:
*
* disk<unit>[s<slice>][<partition>]:
*
*/
static int
alpha_parsedev(struct alpha_devdesc **dev, char *devspec, char **path)
{
struct alpha_devdesc *idev;
struct devsw *dv;
int i, unit, slice, partition, err;
char *cp, *np;
/* minimum length check */
if (strlen(devspec) < 2)
return(EINVAL);
/* look for a device that matches */
for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) {
dv = devsw[i];
break;
}
}
if (dv == NULL)
return(ENOENT);
idev = malloc(sizeof(struct alpha_devdesc));
err = 0;
np = (devspec + strlen(dv->dv_name));
switch(dv->dv_type) {
case DEVT_NONE: /* XXX what to do here? Do we care? */
break;
case DEVT_DISK:
unit = -1;
slice = -1;
partition = -1;
if (*np && (*np != ':')) {
unit = strtol(np, &cp, 10); /* next comes the unit number */
if (cp == np) {
err = EUNIT;
goto fail;
}
if (*cp == 's') { /* got a slice number */
np = cp + 1;
slice = strtol(np, &cp, 10);
if (cp == np) {
err = ESLICE;
goto fail;
}
}
if (*cp && (*cp != ':')) {
partition = *cp - 'a'; /* get a partition number */
if ((partition < 0) || (partition >= MAXPARTITIONS)) {
err = EPART;
goto fail;
}
cp++;
}
}
if (*cp && (*cp != ':')) {
err = EINVAL;
goto fail;
}
idev->d_kind.srmdisk.unit = unit;
idev->d_kind.srmdisk.slice = slice;
idev->d_kind.srmdisk.partition = partition;
if (path != NULL)
*path = (*cp == 0) ? cp : cp + 1;
break;
case DEVT_NET:
unit = 0;
if (*np && (*np != ':')) {
unit = strtol(np, &cp, 0); /* get unit number if present */
if (cp == np) {
err = EUNIT;
goto fail;
}
}
if (*cp && (*cp != ':')) {
err = EINVAL;
goto fail;
}
idev->d_kind.netif.unit = unit;
if (path != NULL)
*path = (*cp == 0) ? cp : cp + 1;
break;
default:
err = EINVAL;
goto fail;
}
idev->d_dev = dv;
idev->d_type = dv->dv_type;
if (dev != NULL)
*dev = idev;
return(0);
fail:
free(idev);
return(err);
}
char *
alpha_fmtdev(void *vdev)
{
struct alpha_devdesc *dev = (struct alpha_devdesc *)vdev;
static char buf[128]; /* XXX device length constant? */
char *cp;
switch(dev->d_type) {
case DEVT_NONE:
strcpy(buf, "(no device)");
break;
case DEVT_DISK:
cp = buf;
cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_kind.srmdisk.unit);
if (dev->d_kind.srmdisk.slice > 0)
cp += sprintf(cp, "s%d", dev->d_kind.srmdisk.slice);
if (dev->d_kind.srmdisk.partition >= 0)
cp += sprintf(cp, "%c", dev->d_kind.srmdisk.partition + 'a');
strcat(cp, ":");
break;
case DEVT_NET:
sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_kind.netif.unit);
break;
}
return(buf);
}
/*
* Set currdev to suit the value being supplied in (value)
*/
int
alpha_setcurrdev(struct env_var *ev, int flags, void *value)
{
struct alpha_devdesc *ncurr;
int rv;
if ((rv = alpha_parsedev(&ncurr, value, NULL)) != 0)
return(rv);
free(ncurr);
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
return(0);
}

View File

@ -0,0 +1,316 @@
/* $Id$ */
/* $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* 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 NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ralph Campbell.
*
* 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 <stand.h>
#include <string.h>
#include <sys/param.h>
#include <machine/elf.h>
#include <machine/prom.h>
#include <machine/rpb.h>
#include <machine/bootinfo.h>
#include "bootstrap.h"
#define _KERNEL
struct elf_kernel_module
{
struct loaded_module m;
vm_offset_t m_entry; /* module entrypoint */
struct bootinfo_v1 m_bi; /* legacy bootinfo */
};
static int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
static int elf_exec(struct loaded_module *amp);
static int elf_load(int fd, Elf_Ehdr *elf, vm_offset_t dest);
struct module_format alpha_elf = { MF_ELF, elf_loadmodule, elf_exec };
vm_offset_t ffp_save, ptbr_save;
vm_offset_t ssym, esym;
static int
elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
{
struct elf_kernel_module *mp;
Elf_Ehdr hdr;
ssize_t nr;
int fd, rval;
/* Open the file. */
rval = 1;
if ((fd = open(filename, 0)) < 0) {
(void)printf("open %s: %s\n", filename, strerror(errno));
goto err;
}
/* Read the exec header. */
if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
(void)printf("read header: %s\n", strerror(errno));
goto err;
}
if (!(hdr.e_ident[0] == ELFMAG0
&& hdr.e_ident[1] == ELFMAG1
&& hdr.e_ident[2] == ELFMAG2
&& hdr.e_ident[3] == ELFMAG3)) {
(void)printf("%s: unknown executable format\n", filename);
goto err;
}
/*
* Ok, we think this is for us.
*/
mp = malloc(sizeof(struct elf_kernel_module));
mp->m.m_name = strdup(filename); /* XXX should we prune the name? */
mp->m.m_type = "elf kernel"; /* XXX only if that's what we really are */
mp->m.m_args = NULL; /* XXX should we put the bootstrap args here and parse later? */
mp->m.m_flags = MF_ELF; /* we're an elf kernel */
mp->m_entry = hdr.e_entry;
if (dest == 0)
dest = (vm_offset_t) hdr.e_entry;
if (mod_findmodule(NULL, mp->m.m_type) != NULL) {
printf("elf_loadmodule: kernel already loaded\n");
rval = EPERM;
goto err;
}
rval = elf_load(fd, &hdr, (vm_offset_t) dest);
*result = (struct loaded_module *)mp;
err:
if (fd >= 0)
(void)close(fd);
return (rval);
}
static int
elf_load(int fd, Elf_Ehdr *elf, vm_offset_t dest)
{
Elf_Shdr *shp;
Elf_Off off;
int i;
int first = 1;
int havesyms;
for (i = 0; i < elf->e_phnum; i++) {
Elf_Phdr phdr;
if (lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET)
== -1) {
(void)printf("lseek phdr: %s\n", strerror(errno));
return (1);
}
if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
(void)printf("read phdr: %s\n", strerror(errno));
return (1);
}
if (phdr.p_type != PT_LOAD ||
(phdr.p_flags & (PF_W|PF_X)) == 0)
continue;
/* Read in segment. */
(void)printf("%s%lu", first ? "" : "+", phdr.p_filesz);
if (lseek(fd, phdr.p_offset, SEEK_SET) == -1) {
(void)printf("lseek text: %s\n", strerror(errno));
return (1);
}
if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
phdr.p_filesz) {
(void)printf("read text: %s\n", strerror(errno));
return (1);
}
if (first || ffp_save < phdr.p_vaddr + phdr.p_memsz)
ffp_save = phdr.p_vaddr + phdr.p_memsz;
/* Zero out bss. */
if (phdr.p_filesz < phdr.p_memsz) {
(void)printf("+%lu", phdr.p_memsz - phdr.p_filesz);
bzero((void *)(phdr.p_vaddr + phdr.p_filesz),
phdr.p_memsz - phdr.p_filesz);
}
first = 0;
}
/*
* Copy the ELF and section headers.
*/
ffp_save = roundup(ffp_save, sizeof(long));
ssym = ffp_save;
bcopy(elf, (void *)ffp_save, sizeof(Elf_Ehdr));
ffp_save += sizeof(Elf_Ehdr);
if (lseek(fd, elf->e_shoff, SEEK_SET) == -1) {
printf("lseek section headers: %s\n", strerror(errno));
return (1);
}
if (read(fd, (void *)ffp_save, elf->e_shnum * sizeof(Elf_Shdr)) !=
elf->e_shnum * sizeof(Elf_Shdr)) {
printf("read section headers: %s\n", strerror(errno));
return (1);
}
shp = (Elf_Shdr *)ffp_save;
ffp_save += roundup((elf->e_shnum * sizeof(Elf_Shdr)), sizeof(long));
/*
* Now load the symbol sections themselves. Make sure the
* sections are aligned. Don't bother with string tables if
* there are no symbol sections.
*/
off = roundup((sizeof(Elf_Ehdr) + (elf->e_shnum * sizeof(Elf_Shdr))),
sizeof(long));
for (havesyms = i = 0; i < elf->e_shnum; i++)
if (shp[i].sh_type == SHT_SYMTAB)
havesyms = 1;
for (first = 1, i = 0; i < elf->e_shnum; i++) {
if (shp[i].sh_type == SHT_SYMTAB ||
shp[i].sh_type == SHT_STRTAB) {
printf("%s%ld", first ? " [" : "+", shp[i].sh_size);
if (havesyms) {
if (lseek(fd, shp[i].sh_offset, SEEK_SET)
== -1) {
printf("\nlseek symbols: %s\n",
strerror(errno));
return (1);
}
if (read(fd, (void *)ffp_save, shp[i].sh_size)
!= shp[i].sh_size) {
printf("\nread symbols: %s\n",
strerror(errno));
return (1);
}
}
ffp_save += roundup(shp[i].sh_size, sizeof(long));
shp[i].sh_offset = off;
off += roundup(shp[i].sh_size, sizeof(long));
first = 0;
}
}
esym = ffp_save;
if (first == 0)
printf("]");
ffp_save = ALPHA_K0SEG_TO_PHYS((ffp_save + PAGE_MASK) & ~PAGE_MASK)
>> PAGE_SHIFT;
ffp_save += 2; /* XXX OSF/1 does this, no idea why. */
(void)printf("\n");
/*
* Frob the copied ELF header to give information relative
* to ssym.
*/
elf = (Elf_Ehdr *)ssym;
elf->e_phoff = 0;
elf->e_shoff = sizeof(Elf_Ehdr);
elf->e_phentsize = 0;
elf->e_phnum = 0;
return (0);
}
static int
elf_exec(struct loaded_module *amp)
{
struct elf_kernel_module *mp = (struct elf_kernel_module *)amp;
static struct bootinfo_v1 bootinfo_v1;
/*
* Fill in the bootinfo for the kernel.
*/
bzero(&bootinfo_v1, sizeof(bootinfo_v1));
bootinfo_v1.ssym = ssym;
bootinfo_v1.esym = esym;
strncpy(bootinfo_v1.booted_kernel, mp->m.m_name,
sizeof(bootinfo_v1.booted_kernel));
prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags,
sizeof(bootinfo_v1.boot_flags));
bootinfo_v1.hwrpb = (void *)HWRPB_ADDR;
bootinfo_v1.hwrpbsize = ((struct rpb *)HWRPB_ADDR)->rpb_size;
bootinfo_v1.cngetc = NULL;
bootinfo_v1.cnputc = NULL;
bootinfo_v1.cnpollc = NULL;
printf("Entering %s at 0x%lx...\n", mp->m.m_name, mp->m_entry);
closeall();
alpha_pal_imb();
(*(void (*)())mp->m_entry)(ffp_save, ptbr_save,
BOOTINFO_MAGIC, &bootinfo_v1, 1, 0);
}

View File

@ -0,0 +1,37 @@
/*
* $Id$
* From: $NetBSD: getsecs.c,v 1.5 1998/01/05 07:02:49 perry Exp $
*/
#include <sys/param.h>
#include <machine/prom.h>
#include <machine/rpb.h>
int
getsecs()
{
static long tnsec;
static long lastpcc, wrapsecs;
long curpcc;
if (tnsec == 0) {
tnsec = 1;
lastpcc = alpha_rpcc() & 0xffffffff;
wrapsecs = (0xffffffff /
((struct rpb *)HWRPB_ADDR)->rpb_cc_freq) + 1;
#if 0
printf("getsecs: cc freq = %d, time to wrap = %d\n",
((struct rpb *)HWRPB_ADDR)->rpb_cc_freq, wrapsecs);
#endif
}
curpcc = alpha_rpcc() & 0xffffffff;
if (curpcc < lastpcc)
curpcc += 0x100000000;
tnsec += ((curpcc - lastpcc) * 1000000000) / ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq;
lastpcc = curpcc;
return (tnsec / 1000000000);
}

View File

@ -0,0 +1,107 @@
/* $Id$ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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.
*
*/
/*
* alpha fully-qualified device descriptor
*/
struct alpha_devdesc
{
struct devsw *d_dev;
int d_type;
#define DEVT_NONE 0
#define DEVT_DISK 1
#define DEVT_NET 2
union
{
struct
{
int unit;
int slice;
int partition;
} srmdisk;
struct
{
int unit; /* XXX net layer lives over these? */
} netif;
} d_kind;
};
extern int alpha_getdev(void **vdev, char *devspec, char **path);
extern char *alpha_fmtdev(void *vdev);
extern int alpha_setcurrdev(struct env_var *ev, int flags, void *value);
#define MAXDEV 31 /* maximum number of distinct devices */
typedef unsigned long physaddr_t;
/* exported devices XXX rename? */
extern struct devsw srmdisk;
extern struct netif_driver srmnet;
/* this is in startup code */
extern void delay(int);
extern void reboot(void);
/*
* alpha module loader
*/
#define MF_FORMATMASK 0xf
#define MF_AOUT 0 /* not supported */
#define MF_ELF 1
struct alpha_module
{
char *m_name; /* module name */
char *m_type; /* module type, eg 'kernel', 'pnptable', etc. */
char *m_args; /* arguments for the module */
int m_flags; /* 0xffff reserved for arch-specific use */
struct alpha_module *m_next; /* next module */
physaddr_t m_addr; /* load address */
size_t m_size; /* module size */
};
struct alpha_format
{
int l_format;
/* Load function must return EFTYPE if it can't handle the module supplied */
int (* l_load)(char *filename, physaddr_t dest, struct alpha_module **result);
int (* l_exec)(struct alpha_module *amp);
};
extern struct alpha_format *formats[]; /* supplied by consumer */
extern struct alpha_format alpha_elf;
extern int alpha_boot(void);
extern int alpha_autoload(void);
extern struct alpha_module *alpha_findmodule(char *name, char *type);

View File

@ -0,0 +1,351 @@
/*
* $Id$
* From: $NetBSD: pal.s,v 1.12 1998/02/27 03:44:53 thorpej Exp $
*/
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/*
* The various OSF PALcode routines.
*
* The following code is originally derived from pages: (I) 6-5 - (I) 6-7
* and (III) 2-1 - (III) 2-25 of "Alpha Architecture Reference Manual" by
* Richard L. Sites.
*
* Updates taken from pages: (II-B) 2-1 - (II-B) 2-33 of "Alpha AXP
* Architecture Reference Manual, Second Edition" by Richard L. Sites
* and Richard T. Witek.
*/
#include <machine/asm.h>
inc2: .stabs __FILE__,132,0,0,inc2; .loc 1 __LINE__
/*
* alpha_rpcc: read process cycle counter (XXX INSTRUCTION, NOT PALcode OP)
*/
.text
LEAF(alpha_rpcc,1)
rpcc v0
RET
END(alpha_rpcc)
/*
* alpha_mb: memory barrier (XXX INSTRUCTION, NOT PALcode OP)
*/
.text
LEAF(alpha_mb,0)
mb
RET
END(alpha_mb)
/*
* alpha_wmb: write memory barrier (XXX INSTRUCTION, NOT PALcode OP)
*/
.text
LEAF(alpha_wmb,0)
/* wmb XXX */
mb /* XXX */
RET
END(alpha_wmb)
/*
* alpha_amask: read architecture features (XXX INSTRUCTION, NOT PALcode OP)
*
* Arguments:
* a0 bitmask of features to test
*
* Returns:
* v0 bitmask - bit is _cleared_ if feature is supported
*/
.text
LEAF(alpha_amask,1)
amask a0, v0
RET
END(alpha_amask)
/*
* alpha_implver: read implementation version (XXX INSTRUCTION, NOT PALcode OP)
*
* Returns:
* v0 implementation version - see <machine/alpha_cpu.h>
*/
.text
LEAF(alpha_implver,0)
#if 0
implver 0x1, v0
#else
.long 0x47e03d80 /* XXX gas(1) does the Wrong Thing */
#endif
RET
END(alpha_implver)
/*
* alpha_pal_imb: I-Stream memory barrier. [UNPRIVILEGED]
* (Makes instruction stream coherent with data stream.)
*/
.text
LEAF(alpha_pal_imb,0)
call_pal PAL_imb
RET
END(alpha_pal_imb)
/*
* alpha_pal_cflush: Cache flush [PRIVILEGED]
*
* Flush the entire physical page specified by the PFN specified in
* a0 from any data caches associated with the current processor.
*
* Arguments:
* a0 page frame number of page to flush
*/
.text
LEAF(alpha_pal_cflush,1)
call_pal PAL_cflush
RET
END(alpha_pal_cflush)
/*
* alpha_pal_draina: Drain aborts. [PRIVILEGED]
*/
.text
LEAF(alpha_pal_draina,0)
call_pal PAL_draina
RET
END(alpha_pal_draina)
/*
* alpha_pal_halt: Halt the processor. [PRIVILEGED]
*/
.text
LEAF(alpha_pal_halt,0)
call_pal PAL_halt
br zero,alpha_pal_halt /* Just in case */
RET
END(alpha_pal_halt)
/*
* alpha_pal_rdmces: Read MCES processor register. [PRIVILEGED]
*
* Return:
* v0 current MCES value
*/
.text
LEAF(alpha_pal_rdmces,1)
call_pal PAL_OSF1_rdmces
RET
END(alpha_pal_rdmces)
/*
* alpha_pal_rdps: Read processor status. [PRIVILEGED]
*
* Return:
* v0 current PS value
*/
.text
LEAF(alpha_pal_rdps,0)
call_pal PAL_OSF1_rdps
RET
END(alpha_pal_rdps)
/*
* alpha_pal_rdusp: Read user stack pointer. [PRIVILEGED]
*
* Return:
* v0 current user stack pointer
*/
.text
LEAF(alpha_pal_rdusp,0)
call_pal PAL_OSF1_rdusp
RET
END(alpha_pal_rdusp)
/*
* alpha_pal_rdval: Read system value. [PRIVILEGED]
*
* Returns the sysvalue in v0, allowing access to a 64-bit
* per-processor value for use by the operating system.
*
* Return:
* v0 sysvalue
*/
.text
LEAF(alpha_pal_rdval,0)
call_pal PAL_OSF1_rdval
RET
END(alpha_pal_rdval)
/*
* alpha_pal_swpipl: Swap Interrupt priority level. [PRIVILEGED]
* _alpha_pal_swpipl: Same, from profiling code. [PRIVILEGED]
*
* Arguments:
* a0 new IPL
*
* Return:
* v0 old IPL
*/
.text
LEAF(alpha_pal_swpipl,1)
call_pal PAL_OSF1_swpipl
RET
END(alpha_pal_swpipl)
LEAF_NOPROFILE(_alpha_pal_swpipl,1)
call_pal PAL_OSF1_swpipl
RET
END(_alpha_pal_swpipl)
/*
* alpha_pal_tbi: Translation buffer invalidate. [PRIVILEGED]
*
* Arguments:
* a0 operation selector
* a1 address to operate on (if necessary)
*/
.text
LEAF(alpha_pal_tbi,2)
call_pal PAL_OSF1_tbi
RET
END(alpha_pal_tbi)
/*
* alpha_pal_whami: Who am I? [PRIVILEGED]
*
* Return:
* v0 processor number
*/
.text
LEAF(alpha_pal_whami,0)
call_pal PAL_OSF1_whami
RET
END(alpha_pal_whami)
/*
* alpha_pal_wrent: Write system entry address. [PRIVILEGED]
*
* Arguments:
* a0 new vector
* a1 vector selector
*/
.text
LEAF(alpha_pal_wrent,2)
call_pal PAL_OSF1_wrent
RET
END(alpha_pal_wrent)
/*
* alpha_pal_wrfen: Write floating-point enable. [PRIVILEGED]
*
* Arguments:
* a0 new enable value (val & 0x1 -> enable).
*/
.text
LEAF(alpha_pal_wrfen,1)
call_pal PAL_OSF1_wrfen
RET
END(alpha_pal_wrfen)
/*
* alpha_pal_wripir: Write interprocessor interrupt request. [PRIVILEGED]
*
* Generate an interprocessor interrupt on the processor specified by
* processor number in a0.
*
* Arguments:
* a0 processor to interrupt
*/
.text
LEAF(alpha_pal_wripir,1)
call_pal PAL_ipir
RET
END(alpha_pal_wripir)
/*
* alpha_pal_wrusp: Write user stack pointer. [PRIVILEGED]
*
* Arguments:
* a0 new user stack pointer
*/
.text
LEAF(alpha_pal_wrusp,1)
call_pal PAL_OSF1_wrusp
RET
END(alpha_pal_wrusp)
/*
* alpha_pal_wrvptptr: Write virtual page table pointer. [PRIVILEGED]
*
* Arguments:
* a0 new virtual page table pointer
*/
.text
LEAF(alpha_pal_wrvptptr,1)
call_pal PAL_OSF1_wrvptptr
RET
END(alpha_pal_wrvptptr)
/*
* alpha_pal_wrmces: Write MCES processor register. [PRIVILEGED]
*
* Arguments:
* a0 value to write to MCES
*/
.text
LEAF(alpha_pal_wrmces,1)
call_pal PAL_OSF1_wrmces
RET
END(alpha_pal_wrmces)
/*
* alpha_pal_wrval: Write system value. [PRIVILEGED]
*
* Write the value passed in a0 to this processor's sysvalue.
*
* Arguments:
* a0 value to write to sysvalue
*/
LEAF(alpha_pal_wrval,1)
call_pal PAL_OSF1_wrval
RET
END(alpha_pal_wrval)
/*
* alpha_pal_swpctx: Swap context. [PRIVILEGED]
*
* Switch to a new process context.
*
* Arguments:
* a0 physical address of hardware PCB describing context
*
* Returns:
* v0 physical address of hardware PCB describing previous context
*/
LEAF(alpha_pal_swpctx,1)
call_pal PAL_OSF1_swpctx
RET
END(alpha_pal_swpctx)

View File

@ -0,0 +1,165 @@
/* $Id$ */
/* $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ */
/*
* Mach Operating System
* Copyright (c) 1992 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
#include <sys/types.h>
#include <machine/prom.h>
#include <machine/rpb.h>
#include "common.h"
#include "bootstrap.h"
int console;
static void prom_probe(struct console *cp);
static int prom_init(int);
void prom_putchar(int);
int prom_getchar(void);
static int prom_poll(void);
struct console promconsole = {
"prom",
"SRM firmware console",
0,
prom_probe,
prom_init,
prom_putchar,
prom_getchar,
prom_poll,
};
void
init_prom_calls()
{
extern struct prom_vec prom_dispatch_v;
struct rpb *r;
struct crb *c;
char buf[4];
r = (struct rpb *)HWRPB_ADDR;
c = (struct crb *)((u_int8_t *)r + r->rpb_crb_off);
prom_dispatch_v.routine_arg = c->crb_v_dispatch;
prom_dispatch_v.routine = c->crb_v_dispatch->entry_va;
/* Look for console tty. */
prom_getenv(PROM_E_TTY_DEV, buf, 4);
console = buf[0] - '0';
}
static void
prom_probe(struct console *cp)
{
init_prom_calls();
cp->c_flags |= C_PRESENTIN|C_PRESENTOUT;
}
static int
prom_init(int arg)
{
return 0;
}
void
prom_putchar(int c)
{
prom_return_t ret;
char cbuf;
cbuf = c;
do {
ret.bits = prom_dispatch(PROM_R_PUTS, console, &cbuf, 1);
} while ((ret.u.retval & 1) == 0);
}
static int saved_char = -1;
int
prom_getchar()
{
prom_return_t ret;
if (saved_char != -1) {
int c = saved_char;
saved_char = -1;
return c;
}
for (;;) {
ret.bits = prom_dispatch(PROM_R_GETC, console);
if (ret.u.status == 0 || ret.u.status == 1)
return (ret.u.retval);
}
}
int
prom_poll()
{
prom_return_t ret;
if (saved_char != -1)
return 1;
ret.bits = prom_dispatch(PROM_R_GETC, console);
if (ret.u.status == 0 || ret.u.status == 1) {
saved_char = ret.u.retval;
return 1;
}
return 0;
}
int
prom_getenv(id, buf, len)
int id, len;
char *buf;
{
prom_return_t ret;
ret.bits = prom_dispatch(PROM_R_GETENV, id, buf, len-1);
if (ret.u.status & 0x4)
ret.u.retval = 0;
buf[ret.u.retval] = '\0';
return (ret.u.retval);
}
int
prom_open(dev, len)
char *dev;
int len;
{
prom_return_t ret;
ret.bits = prom_dispatch(PROM_R_OPEN, dev, len);
if (ret.u.status & 0x4)
return (-1);
else
return (ret.u.retval);
}

View File

@ -0,0 +1,118 @@
/*
* $Id$
* From: $NetBSD: prom_disp.S,v 1.2 1997/04/06 08:41:00 cgd Exp $
*/
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#ifndef _LOCORE
#define ASSEMBLER
#include <machine/asm.h>
#include <machine/prom.h>
#include <machine/rpb.h>
#endif
.globl prom_dispatch_v
.comm prom_dispatch_v,16
.text
.align 4
/*
* Dispatcher routine. Implements prom's calling machinery, saves our
* callee-saved registers as required by C.
*/
#define D_RA (7*8)
#define D_S0 (8*8)
#define D_S1 (9*8)
#define D_S2 (10*8)
#define D_S3 (11*8)
#define D_S4 (12*8)
#define D_S5 (13*8)
#define D_S6 (14*8)
#define DISPATCH_FRAME_SIZE (15*8)
#define DISPATCH_REGS IM_RA|IM_S0|IM_S1|IM_S2|IM_S3|IM_S4|IM_S5|IM_S6
NESTED(prom_dispatch, 5, DISPATCH_FRAME_SIZE, ra, DISPATCH_REGS, 0)
LDGP(pv)
lda sp, -DISPATCH_FRAME_SIZE(sp)
stq ra, D_RA(sp)
stq s0, D_S0(sp)
stq s1, D_S1(sp)
stq s2, D_S2(sp)
stq s3, D_S3(sp)
stq s4, D_S4(sp)
stq s5, D_S5(sp)
stq s6, D_S6(sp)
/* Lord have mercy because.. I would not. */
/* #define STUPID_PROM_IS_32_BITS */
#ifdef STUPID_PROM_IS_32_BITS
ldah s0, 0x2000(zero) /* hack for hack */
lda s0, (0x2000-8)(s0)
stq sp, 0(s0)
or s0, zero, sp
#endif /* STUPID_PROM_IS_32_BITS */
lda pv, prom_dispatch_v
ldq v0, 0(pv) /* routine */
ldq pv, 8(pv) /* routine_arg */
jsr ra, (v0)
#ifdef STUPID_PROM_IS_32_BITS
ldah s0, 0x2000(zero) /* hack for hack */
lda s0, (0x2000-8)(s0)
ldq sp, 0(s0)
#endif /* STUPID_PROM_IS_32_BITS */
ldq ra, D_RA(sp)
ldq s0, D_S0(sp)
ldq s1, D_S1(sp)
ldq s2, D_S2(sp)
ldq s3, D_S3(sp)
ldq s4, D_S4(sp)
ldq s5, D_S5(sp)
ldq s6, D_S6(sp)
lda sp, DISPATCH_FRAME_SIZE(sp)
RET
END(prom_dispatch)
#undef D_RA
#undef D_S0
#undef D_S1
#undef D_S2
#undef D_S3
#undef D_S4
#undef D_S5
#undef D_S6
#undef DISPATCH_FRAME_SIZE
#undef DISPATCH_REGS

View File

@ -0,0 +1,139 @@
/*
* $Id$
* From: $NetBSD: prom_swpal.S,v 1.2 1997/04/06 08:41:01 cgd Exp $
*/
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Keith Bostic
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#define ASSEMBLER
#include <machine/asm.h>
#include <machine/prom.h>
#include <machine/rpb.h>
/* Offsets from base of HWRPB. */
#define RPB_SELFREF 0x00
#define RPB_SLOTSIZE 0x98
#define RPB_PERCPU_OFF 0xA0
/* Offsets in a boot PCB. */
#define PCB_KSP 0x00
#define PCB_PTBR 0x10
#define PCB_ASN 0x1c
#define PCB_FEN 0x28
/* Pal values. */
#define PAL_RESERVED 0 /* Reserved to Digital. */
#define PAL_VMS 1 /* VMS */
#define PAL_OSF 2 /* OSF */
/*
* PAL code switch routine.
*/
#define D_RA (7*8)
#define D_S0 (8*8)
#define D_S1 (9*8)
#define D_S2 (10*8)
#define D_S3 (11*8)
#define D_S4 (12*8)
#define D_S5 (13*8)
#define PALSW_FRAME_SIZE (14*8)
#define PALSW_REGS IM_RA|IM_S0|IM_S1|IM_S2|IM_S3|IM_S4|IM_S5
.comm ptbr_save,8
.text
.align 4
NESTED(switch_palcode, 0, PALSW_FRAME_SIZE, ra, PALSW_REGS, 0)
LDGP(pv)
/* ldgp gp, 0(pv)*/
lda sp, -PALSW_FRAME_SIZE(sp)
stq ra, D_RA(sp)
stq s0, D_S0(sp)
stq s1, D_S1(sp)
stq s2, D_S2(sp)
stq s3, D_S3(sp)
stq s4, D_S4(sp)
stq s5, D_S5(sp)
stq pv, 0(sp)
stq gp, 8(sp)
ldiq s0, HWRPB_ADDR /* s0 HWRPB_ADDR */
ldq s1, RPB_SLOTSIZE(s0)
call_pal PAL_VMS_mfpr_whami
mulq s1, v0, s1 /* s1 per_cpu offset from base */
ldq s2, RPB_PERCPU_OFF(s0)
addq s0, s2, s2
addq s2, s1, s2 /* s2 PCB (virtual) */
call_pal PAL_VMS_mfpr_ptbr
stq v0, PCB_PTBR(s2)
stq v0, ptbr_save /* save PTBR for the kernel */
stl zero, PCB_ASN(s2)
stq zero, PCB_FEN(s2)
stq sp, PCB_KSP(s2)
ldq t0, RPB_SELFREF(s0) /* HWRBP base (physical) */
ldq t1, RPB_PERCPU_OFF(s0)
addq t0, t1, t0
addq t0, s1, t0 /* PCB base (phys) */
stq t0, 16(sp)
call_pal PAL_VMS_mfpr_vptb
mov v0, a3
ldiq a0, PAL_OSF
lda a1, contin
ldq a2, 16(sp)
call_pal PAL_swppal /* a0, a1, a2, a3 */
contin: ldq pv, 0(sp)
ldq gp, 8(sp)
ldq ra, D_RA(sp)
ldq s0, D_S0(sp)
ldq s1, D_S1(sp)
ldq s2, D_S2(sp)
ldq s3, D_S3(sp)
ldq s4, D_S4(sp)
ldq s5, D_S5(sp)
lda sp, PALSW_FRAME_SIZE(sp)
RET
END(switch_palcode)
#undef D_RA
#undef D_S0
#undef D_S1
#undef D_S2
#undef D_S3
#undef D_S4
#undef D_S5
#undef PALSW_FRAME_SIZE
#undef PALSW_REGS

View File

@ -0,0 +1,48 @@
/*-
* Copyright (c) 1998 Doug Rabson
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <machine/rpb.h>
void
reboot(void)
{
struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
struct pcs *pcs = LOCATE_PCS(hwrpb, hwrpb->rpb_primary_cpu_id);
pcs->pcs_flags |= PCS_HALT_WARM_BOOT;
alpha_pal_halt();
}
void
exit(int code)
{
struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
struct pcs *pcs = LOCATE_PCS(hwrpb, hwrpb->rpb_primary_cpu_id);
pcs->pcs_flags |= PCS_HALT_STAY_HALTED;
alpha_pal_halt();
}

View File

@ -0,0 +1,334 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* Copyright (c) 1998 Doug Rabson <dfr@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* SRM disk device handling.
*
* Ideas and algorithms from:
*
* - NetBSD libi386/biosdisk.c
* - FreeBSD biosboot/disk.c
*
* XXX Todo: add bad144 support.
*/
#include <stand.h>
#include <sys/disklabel.h>
#include <sys/diskslice.h>
#include <machine/stdarg.h>
#include <machine/prom.h>
#include "libalpha.h"
#define SRMDISK_SECSIZE 512
#define BUFSIZE (1 * SRMDISK_SECSIZE)
#define MAXBDDEV MAXDEV
#ifdef DISK_DEBUG
# define D(x) x
#else
# define D(x)
#endif
static int bd_init(void);
static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
static int bd_open(struct open_file *f, void *vdev);
static int bd_close(struct open_file *f);
struct open_disk {
int od_fd;
int od_unit; /* our unit number */
int od_boff; /* block offset from beginning of SRM disk */
int od_flags;
#define BD_MODEMASK 0x3
#define BD_MODEINT13 0x0
#define BD_MODEEDD1 0x1
#define BD_MODEEDD3 0x2
#define BD_FLOPPY (1<<2)
u_char od_buf[BUFSIZE]; /* transfer buffer (do we want/need this?) */
};
struct devsw srmdisk = {
"disk",
DEVT_DISK,
bd_init,
bd_strategy,
bd_open,
bd_close,
noioctl
};
/*
* List of SRM devices, translation from disk unit number to
* SRM unit number.
*/
static struct
{
char bd_name[64];
int bd_unit; /* SRM unit number */
int bd_namelen;
int bd_flags;
} bdinfo [MAXBDDEV];
static int nbdinfo = 0;
/*
* Quiz SRM for disk devices, save a little info about them.
*/
static int
bd_init(void)
{
prom_return_t ret;
char devname[64];
bdinfo[0].bd_unit = 0; /* XXX */
bdinfo[0].bd_flags = 0; /* XXX */
ret.bits = prom_getenv(PROM_E_BOOTED_DEV,
bdinfo[0].bd_name, sizeof(bdinfo[0].bd_name));
bdinfo[0].bd_namelen = ret.u.retval;
nbdinfo++;
return (0);
}
/*
* Attempt to open the disk described by (dev) for use by (f).
*
* Note that the philosophy here is "give them exactly what
* they ask for". This is necessary because being too "smart"
* about what the user might want leads to complications.
* (eg. given no slice or partition value, with a disk that is
* sliced - are they after the first BSD slice, or the DOS
* slice before it?)
*/
static int
bd_open(struct open_file *f, void *vdev)
{
struct alpha_devdesc *dev = vdev;
struct dos_partition *dptr;
struct open_disk *od;
struct disklabel *lp;
int sector, slice, i;
int error;
int unit;
prom_return_t ret;
unit = dev->d_kind.srmdisk.unit;
if (unit >= nbdinfo) {
D(printf("attempt to open nonexistent disk\n"));
return(ENXIO);
}
/* Call the prom to open the disk. */
ret.bits = prom_open(bdinfo[unit].bd_name, bdinfo[unit].bd_namelen);
if (ret.u.status == 2)
return (ENXIO);
if (ret.u.status == 3)
return (EIO);
od = (struct open_disk *) malloc(sizeof(struct open_disk));
if (!od) {
D(printf("srmdiskopen: no memory\n"));
return (ENOMEM);
}
/* Look up SRM unit number, intialise open_disk structure */
od->od_fd = ret.u.retval;
od->od_unit = dev->d_kind.srmdisk.unit;
od->od_flags = bdinfo[od->od_unit].bd_flags;
od->od_boff = 0;
error = 0;
#if 0
/* Get geometry for this open (removable device may have changed) */
if (set_geometry(&od->od_ll)) {
D(printf("bd_open: can't get geometry\n"));
error = ENXIO;
goto out;
}
#endif
/*
* Following calculations attempt to determine the correct value
* for d->od_boff by looking for the slice and partition specified,
* or searching for reasonable defaults.
*/
#if 0
/*
* Find the slice in the DOS slice table.
*/
if (readsects(&od->od_ll, 0, 1, od->od_buf, 0)) {
D(printf("bd_open: error reading MBR\n"));
error = EIO;
goto out;
}
/*
* Check the slice table magic.
*/
if ((od->od_buf[0x1fe] != 0xff) || (od->od_buf[0x1ff] != 0xaa)) {
/* If a slice number was explicitly supplied, this is an error */
if (dev->d_kind.srmdisk.slice > 0) {
D(printf("bd_open: no slice table/MBR (no magic)\n"));
error = ENOENT;
goto out;
}
sector = 0;
goto unsliced; /* may be a floppy */
}
dptr = (struct dos_partition *) & od->od_buf[DOSPARTOFF];
/*
* XXX No support here for 'extended' slices
*/
if (dev->d_kind.srmdisk.slice <= 0) {
/*
* Search for the first FreeBSD slice; this also works on "unsliced"
* disks, as they contain a "historically bogus" MBR.
*/
for (i = 0; i < NDOSPART; i++, dptr++)
if (dptr->dp_typ == DOSPTYP_386BSD) {
sector = dptr->dp_start;
break;
}
/* Did we find something? */
if (sector == -1) {
error = ENOENT;
goto out;
}
} else {
/*
* Accept the supplied slice number unequivocally (we may be looking
* for a DOS partition) if we can handle it.
*/
if ((dev->d_kind.srmdisk.slice > NDOSPART) || (dev->d_kind.srmdisk.slice < 1)) {
error = ENOENT;
goto out;
}
dptr += (dev->d_kind.srmdisk.slice - 1);
sector = dptr->dp_start;
}
unsliced:
#else
sector = 0;
#endif
/*
* Now we have the slice, look for the partition in the disklabel if we have
* a partition to start with.
*/
if (dev->d_kind.srmdisk.partition < 0) {
od->od_boff = sector; /* no partition, must be after the slice */
} else {
if (bd_strategy(od, F_READ, sector + LABELSECTOR, 512, od->od_buf, 0)) {
D(printf("bd_open: error reading disklabel\n"));
error = EIO;
goto out;
}
lp = (struct disklabel *) (od->od_buf + LABELOFFSET);
if (lp->d_magic != DISKMAGIC) {
D(printf("bd_open: no disklabel\n"));
error = ENOENT;
goto out;
} else if (dev->d_kind.srmdisk.partition >= lp->d_npartitions) {
/*
* The partition supplied is out of bounds; this is fatal.
*/
D(printf("partition '%c' exceeds partitions in table (a-'%c')\n",
'a' + dev->d_kind.srmdisk.partition, 'a' + lp->d_npartitions));
error = EPART;
goto out;
} else {
/*
* Complain if the partition type is wrong and it shouldn't be, but
* regardless accept this partition.
*/
D(if ((lp->d_partitions[dev->d_kind.srmdisk.partition].p_fstype == FS_UNUSED) &&
!(od->od_flags & BD_FLOPPY)) /* Floppies often have bogus fstype */
printf("bd_open: warning, partition marked as unused\n"););
od->od_boff = lp->d_partitions[dev->d_kind.srmdisk.partition].p_offset;
}
}
/*
* Save our context
*/
f->f_devdata = od;
out:
if (error)
free(od);
return(error);
}
static int
bd_close(struct open_file *f)
{
struct open_disk *od = f->f_devdata;
(void)prom_close(od->od_fd);
free(od);
f->f_devdata = NULL;
return(0);
}
static int
bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize)
{
prom_return_t ret;
struct open_disk *od = (struct open_disk *)devdata;
if (size % SRMDISK_SECSIZE)
panic("bd_strategy: I/O not block multiple");
if (flag != F_READ)
return(EROFS);
if (rsize)
*rsize = 0;
ret.bits = prom_read(od->od_fd, size, buf, dblk + od->od_boff);
if (ret.u.status) {
D(printf("read error\n"));
return (EIO);
}
if (rsize)
*rsize = size;
return (0);
}

View File

@ -0,0 +1,257 @@
/*
* $Id$
* From: $NetBSD: if_prom.c,v 1.10 1997/09/06 14:08:33 drochner Exp $
*/
/*
* Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
* Copyright (c) 1993 Adam Glass
* 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 Adam Glass.
* 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 Adam Glass ``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.
*/
#include <sys/param.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <stand.h>
#include <net.h>
#include <netif.h>
#include <machine/prom.h>
#include "bbinfo.h"
int prom_probe();
int prom_match();
void prom_init();
int prom_get();
int prom_put();
void prom_end();
extern struct netif_stats prom_stats[];
struct netif_dif prom_ifs[] = {
/* dif_unit dif_nsel dif_stats dif_private */
{ 0, 1, &prom_stats[0], 0, },
};
struct netif_stats prom_stats[NENTS(prom_ifs)];
struct netbbinfo netbbinfo = {
0xfeedbabedeadbeef, /* magic number */
0, /* set */
{0, 0, 0, 0, 0, 0}, /* ether address */
0, /* force */
{ 0, }, /* pad2 */
0, /* cksum */
0xfeedbeefdeadbabe, /* magic number */
};
struct netif_driver srmnet = {
"prom", /* netif_bname */
prom_match, /* netif_match */
prom_probe, /* netif_probe */
prom_init, /* netif_init */
prom_get, /* netif_get */
prom_put, /* netif_put */
prom_end, /* netif_end */
prom_ifs, /* netif_ifs */
NENTS(prom_ifs) /* netif_nifs */
};
int netfd = 0, broken_firmware;
int
prom_match(nif, machdep_hint)
struct netif *nif;
void *machdep_hint;
{
return (1);
}
int
prom_probe(nif, machdep_hint)
struct netif *nif;
void *machdep_hint;
{
return 0;
}
int
prom_put(desc, pkt, len)
struct iodesc *desc;
void *pkt;
int len;
{
prom_write(netfd, len, pkt, 0);
return len;
}
int
prom_get(desc, pkt, len, timeout)
struct iodesc *desc;
void *pkt;
int len;
time_t timeout;
{
prom_return_t ret;
time_t t;
int cc;
char hate[2000];
t = getsecs();
cc = 0;
while (((getsecs() - t) < timeout) && !cc) {
if (broken_firmware)
ret.bits = prom_read(netfd, 0, hate, 0);
else
ret.bits = prom_read(netfd, sizeof hate, hate, 0);
if (ret.u.status == 0)
cc = ret.u.retval;
}
if (broken_firmware)
cc = min(cc, len);
else
cc = len;
bcopy(hate, pkt, cc);
return cc;
}
extern char *strchr();
void
prom_init(desc, machdep_hint)
struct iodesc *desc;
void *machdep_hint;
{
prom_return_t ret;
char devname[64];
int devlen, i;
int netbbinfovalid;
char *enet_addr;
u_int64_t *qp, csum;
broken_firmware = 0;
csum = 0;
for (i = 0, qp = (u_int64_t *)&netbbinfo;
i < (sizeof netbbinfo / sizeof (u_int64_t)); i++, qp++)
csum += *qp;
netbbinfovalid = (csum == 0);
if (netbbinfovalid)
netbbinfovalid = netbbinfo.set;
printf("netbbinfo ");
if (!netbbinfovalid)
printf("invalid\n");
else
printf("valid: force = %d, ea = %s\n", netbbinfo.force,
ether_sprintf(netbbinfo.ether_addr));
ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname));
devlen = ret.u.retval;
/* Ethernet address is the 9th component of the booted_dev string. */
enet_addr = devname;
for (i = 0; i < 8; i++) {
enet_addr = strchr(enet_addr, ' ');
if (enet_addr == NULL) {
printf("boot: boot device name does not contain ethernet address.\n");
goto punt;
}
enet_addr++;
}
if (enet_addr != NULL) {
int hv, lv;
#define dval(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
(((c) >= 'A' && (c) <= 'F') ? (10 + (c) - 'A') : \
(((c) >= 'a' && (c) <= 'f') ? (10 + (c) - 'a') : -1)))
for (i = 0; i < 6; i++) {
hv = dval(*enet_addr); enet_addr++;
lv = dval(*enet_addr); enet_addr++;
enet_addr++;
if (hv == -1 || lv == -1) {
printf("boot: boot device name contains bogus ethernet address.\n");
goto punt;
}
desc->myea[i] = (hv << 4) | lv;
}
#undef dval
}
if (netbbinfovalid && netbbinfo.force) {
printf("boot: using hard-coded ethernet address (forced).\n");
bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea);
}
gotit:
printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea));
ret.bits = prom_open(devname, devlen + 1);
if (ret.u.status) {
printf("prom_init: open failed: %d\n", ret.u.status);
goto reallypunt;
}
netfd = ret.u.retval;
return;
punt:
broken_firmware = 1;
if (netbbinfovalid) {
printf("boot: using hard-coded ethernet address.\n");
bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea);
goto gotit;
}
reallypunt:
printf("\n");
printf("Boot device name was: \"%s\"\n", devname);
printf("\n");
printf("Your firmware may be too old to network-boot NetBSD/Alpha,\n");
printf("or you might have to hard-code an ethernet address into\n");
printf("your network boot block with setnetbootinfo(8).\n");
halt();
}
void
prom_end(nif)
struct netif *nif;
{
prom_close(netfd);
}

View File

@ -0,0 +1,85 @@
/*
* $Id$
* From: $NetBSD: start.S,v 1.4 1998/03/28 00:54:15 cgd Exp $
*/
/*
* Mach Operating System
* Copyright (c) 1992 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
#include <machine/asm.h>
/*
* start --
* Entry point for boot/standalone programs.
*
* Arguments:
* a0 long (first free physical page)
*
* This is where the prom comes to. Leaves all exception and interrupts
* to prom, runs off prom's stack too. No return values.
*/
.text
.set noreorder /* don't reorder instructions */
#define ENTRY_FRAME 32
NESTED(start, 1, ENTRY_FRAME, ra, 0, 0)
br pv,Lstartgp
Lstartgp:
LDGP(pv)
#ifndef PRIMARY_BOOTBLOCK
lda sp,start /* start stack below text */
lda sp,-ENTRY_FRAME(sp)
#endif
lda a0,_edata
lda a1,_end
subq a1,a0,a1
CALL(bzero)
CALL(main) /* transfer to C */
XLEAF(_rtt, 0)
XLEAF(halt, 0)
call_pal PAL_halt /* halt if we ever return */
END(start)
/*
* Dummy routine for GCC2.
*/
LEAF(__main,0)
RET
END(__main)
/*
* cpu_number
* Return the cpu number, using the whami instruction.
*/
LEAF(cpu_number, 0)
call_pal PAL_VMS_mfpr_whami
RET
END(cpu_number)

View File

@ -0,0 +1,43 @@
/*-
* Copyright (c) 1998 Doug Rabson
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
/*
* Can't do this properly without putting PCI chipset drivers into the
* bootstrap :-(
*/
time_t
time(time_t *tloc)
{
int secs = getsecs();
if (tloc)
*tloc = secs;
return secs;
}

View File

@ -0,0 +1,72 @@
# $NetBSD: Makefile,v 1.12 1998/02/19 14:18:36 drochner Exp $
BASE= netboot
PROG= ${BASE}
NOMAN=
NEWVERSWHAT= "SRM net boot"
.PATH: ${.CURDIR}/../common
# i386-specific bootstrap sources
SRCS+= main.c conf.c dev_net.c
# Always add MI sources
.PATH: ${.CURDIR}/../../common
.include <${.CURDIR}/../../common/Makefile.inc>
CFLAGS+= -mno-fp-regs
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
# Verbose ls causes extra heap usage
CFLAGS+= -DVERBOSE_LS
CLEANFILES+= vers.c vers.o gensetdefs.o gensetdefs setdef0.o setdef1.o \
setdefs.h start.o
CLEANFILES+= ${BASE} ${BASE}.sym ${BASE}.list
CFLAGS+= -Wall
# XXX fix to use "standard" versions
LIBSTANDDIR= /home/dfr/FreeBSD/alpha/src/lib/libstand
LIBSTAND= ${LIBSTANDDIR}/obj/libstand.a
CFLAGS+= -I${LIBSTANDDIR}
LIBALPHA= ${.CURDIR}/../libalpha/obj/libalpha.a
CFLAGS+= -I${.CURDIR}/..
CRT= start.o
STRIP=
all: ${BASE}
vers.o: ${.CURDIR}/newvers.sh ${.CURDIR}/Makefile
sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
${CC} -c vers.c
${BASE}: ${BASE}.sym
objcopy -O binary ${BASE}.sym ${BASE}
${BASE}.nosym: ${BASE}.sym
cp ${BASE}.sym ${BASE}.nosym
strip ${BASE}.nosym
${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBALPHA} ${CRT} vers.o setdef0.o setdef1.o
${LD} -o ${BASE}.sym -M -e start -N -Ttext ${PRIMARY_LOAD_ADDRESS} \
${CRT} setdef0.o ${OBJS} setdef1.o \
vers.o ${LIBSTAND} ${LIBALPHA} ${LIBSTAND} >${.OBJDIR}/${BASE}.list
start.o: ${.CURDIR}/../libalpha/start.S
${CC} -c -DPRIMARY_BOOTBLOCK $<
setdef0.o: setdefs.h
setdef1.o: setdefs.h
.include <bsd.prog.mk>
setdefs.h: gensetdefs ${OBJS}
@echo Generating linker sets
@./gensetdefs ${OBJS} >setdefs.h
gensetdefs: gensetdefs.o
${CC} -static gensetdefs.o -o $@
gensetdefs.o: gensetdefs.c
${CC} -c $<

View File

@ -0,0 +1,89 @@
/*
* $Id$
* From: $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $
*/
/*
* Copyright (c) 1997
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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 <stand.h>
#include "libalpha/libalpha.h"
#include "dev_net.h"
/*
* We could use linker sets for some or all of these, but
* then we would have to control what ended up linked into
* the bootstrap. So it's easier to conditionalise things
* here.
*
* XXX rename these arrays to be consistent and less namespace-hostile
*/
/* Exported for libstand */
struct devsw *devsw[] = {
&netdev,
NULL
};
struct fs_ops *file_system[] = {
&nfs_fsops,
&zipfs_fsops,
NULL
};
struct netif_driver *netif_drivers[] = {
&srmnet,
NULL,
};
/* Exported for alpha only */
/*
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
struct module_format *module_formats[] = {
&alpha_elf,
NULL
};
/*
* Consoles
*
* We don't prototype these in libalpha.h because they require
* data structures from bootstrap.h as well.
*/
extern struct console promconsole;
struct console *consoles[] = {
&promconsole,
NULL
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
#!/bin/sh -
#
# $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $
#
# Copyright (c) 1984, 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.
#
# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
u=${USER-root} h=`hostname` t=`date`
r=`head -n 6 $1 | tail -n 1 | awk -F: ' { print $1 } '`
echo "char bootprog_name[] = \"FreeBSD/alpha ${2}\";" > vers.c
echo "char bootprog_rev[] = \"${r}\";" >> vers.c
echo "char bootprog_date[] = \"${t}\";" >> vers.c
echo "char bootprog_maker[] = \"${u}@${h}\";" >> vers.c

View File

@ -0,0 +1,2 @@
/* $Id$ */
DEFINE_SET(Xcommand_set, 15);

View File

@ -0,0 +1,4 @@
char bootprog_name[] = "FreeBSD/alpha SRM net boot";
char bootprog_rev[] = "0.1";
char bootprog_date[] = "Mon Aug 17 10:38:31 BST 1998";
char bootprog_maker[] = "dfr@salmon.nlsystems.com";

View File

@ -0,0 +1,7 @@
$Id$
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
0.1: Initial i386 version, germinated from the NetBSD i386
standalone, but enormously modified.

View File

@ -0,0 +1,4 @@
# $Id$
SRCS+= boot.c commands.c console.c devopen.c interp.c ls.c misc.c module.c
SRCS+= panic.c

229
sys/boot/common/boot.c Normal file
View File

@ -0,0 +1,229 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* Loading modules, booting the system
*/
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
static char *getbootfile(int try);
/* List of kernel names to try (may be overwritten by boot.config) XXX should move from here? */
static char *default_bootfiles = "kernel,kernel.old";
/*
* The user wants us to boot.
*/
COMMAND_SET(boot, "boot", "boot a file or loaded kernel", command_boot);
static int
command_boot(int argc, char *argv[])
{
struct loaded_module *km;
char *cp;
int try;
/*
* See if the user has specified an explicit kernel to boot.
*/
if ((argc > 1) && (argv[1][0] != '-')) {
/* XXX maybe we should discard everything and start again? */
if (mod_findmodule(NULL, NULL) != NULL) {
sprintf(command_errbuf, "can't boot '%s', kernel module already loaded", argv[0]);
return(CMD_ERROR);
}
/* find/load the kernel module */
if (mod_load(argv[1], argc - 2, argv + 2) != 0)
return(CMD_ERROR);
/* we have consumed all arguments */
argc = 1;
}
/*
* See if there is a kernel module already loaded
*/
if (mod_findmodule(NULL, NULL) == NULL) {
for (try = 0; (cp = getbootfile(try)) != NULL; try++) {
if (mod_load(cp, argc - 1, argv + 1) != 0) {
printf("can't load '%s'\n", argv[0]);
} else {
/* we have consumed all arguments */
argc = 1;
break;
}
}
}
/*
* Loaded anything yet?
*/
if ((km = mod_findmodule(NULL, NULL)) == NULL) {
command_errmsg = "no bootable kernel";
return(CMD_ERROR);
}
/*
* If we were given arguments, discard any previous.
* XXX should we merge arguments? Hard to DWIM.
*/
if (argc > 1) {
if (km->m_args != NULL)
free(km->m_args);
km->m_args = unargv(argc - 1, argv + 1);
}
/* Hook for platform-specific autoloading of modules */
if (archsw.arch_autoload() != 0)
return(CMD_ERROR);
archsw.arch_boot();
return(CMD_ERROR);
}
/*
* Autoboot after a delay
*/
COMMAND_SET(autoboot, "autoboot", "boot automatically after a delay", command_autoboot);
/*
* XXX note the 'prompt' argument is not really useful until quoting is implemented
*/
static int
command_autoboot(int argc, char *argv[])
{
int howlong;
char *cp, *prompt;
prompt = NULL;
howlong = -1;
switch(argc) {
case 3:
prompt = argv[2];
/* FALLTHROUGH */
case 2:
howlong = strtol(argv[1], &cp, 0);
if (*cp != 0) {
sprintf(command_errbuf, "bad delay '%s'", argv[1]);
return(CMD_ERROR);
}
/* FALLTHROUGH */
case 1:
return(autoboot(howlong, prompt));
}
command_errmsg = "too many arguments";
return(CMD_ERROR);
}
int
autoboot(int delay, char *prompt)
{
time_t when, otime, ntime;
int c, yes;
char *argv[2];
if (delay == -1)
delay = 5; /* env var? compile-time define? */
otime = time(NULL);
when = otime + delay; /* when to boot */
yes = 0;
/* XXX could try to work out what we might boot */
printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt);
for (;;) {
if (ischar()) {
c = getchar();
if ((c == '\r') || (c == '\n'))
yes = 1;
break;
}
ntime = time(NULL);
if (ntime == when) {
yes = 1;
break;
}
if (ntime != otime) {
printf("\rBooting [%s] in %d seconds...", getbootfile(0), (int)(when - ntime));
otime = ntime;
}
}
printf("\n");
if (yes) {
argv[0] = "boot";
argv[1] = NULL;
return(command_boot(1, argv));
}
return(CMD_OK);
}
/*
* Scrounge for the name of the (try)'th file we will try to boot.
*/
static char *
getbootfile(int try)
{
static char *name = NULL;
char *spec, *ep;
int len;
/* we use dynamic storage */
if (name != NULL) {
free(name);
name = NULL;
}
/*
* Try $bootfile, then try our builtin default
*/
if ((spec = getenv("bootfile")) == NULL)
spec = default_bootfiles;
while ((try > 0) && (spec != NULL))
spec = strchr(spec, ',');
if (spec != NULL) {
if ((ep = strchr(spec, ',')) != NULL) {
len = ep - spec;
} else {
len = strlen(spec);
}
name = malloc(len + 1);
strncpy(name, spec, len);
name[len] = 0;
}
return(name);
}

226
sys/boot/common/bootstrap.h Normal file
View File

@ -0,0 +1,226 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <sys/types.h>
/* XXX debugging */
extern struct console vidconsole;
#define MARK(s, c) {vidconsole.c_out(s); vidconsole.c_out(c); while (!vidconsole.c_ready()) ; vidconsole.c_in();}
/*
* Generic device specifier; architecture-dependant
* versions may be larger, but should be allowed to
* overlap.
*/
struct devdesc
{
struct devsw *d_dev;
int d_type;
#define DEVT_NONE 0
#define DEVT_DISK 1
#define DEVT_NET 2
};
/* Commands and return values; nonzero return sets command_errmsg != NULL */
typedef int (bootblk_cmd_t)(int argc, char *argv[]);
extern char *command_errmsg;
extern char command_errbuf[]; /* XXX blah, length */
#define CMD_OK 0
#define CMD_ERROR 1
/* interp.c */
extern void interact(void);
extern void source(char *filename);
/* boot.c */
extern int autoboot(int delay, char *prompt);
/* misc.c */
extern char *unargv(int argc, char *argv[]);
/*
* Modular console support.
*/
struct console
{
char *c_name;
char *c_desc;
int c_flags;
#define C_PRESENTIN (1<<0)
#define C_PRESENTOUT (1<<1)
#define C_ACTIVEIN (1<<2)
#define C_ACTIVEOUT (1<<3)
void (* c_probe)(struct console *cp); /* set c_flags to match hardware */
int (* c_init)(int arg); /* reinit XXX may need more args */
void (* c_out)(int c); /* emit c */
int (* c_in)(void); /* wait for and return input */
int (* c_ready)(void); /* return nonzer if input waiting */
};
extern struct console *consoles[];
extern void cons_probe(void);
/*
* Module loader.
*/
#define MF_FORMATMASK 0xf
#define MF_AOUT 0
#define MF_ELF 1
/*
* Module metadata header.
*
* Metadata are allocated on our heap, and copied into kernel space
* before executing the kernel.
*/
struct module_metadata
{
size_t md_size;
u_int16_t md_type;
struct module_metadata *md_next;
char md_data[0]; /* data are immediately appended */
};
/*
* Loaded module information.
*
* At least one module (the kernel) must be loaded in order to boot.
* The kernel is always loaded first.
*/
struct loaded_module
{
char *m_name; /* module name */
char *m_type; /* module type, eg 'kernel', 'pnptable', etc. */
char *m_args; /* arguments for the module */
void *m_metadata; /* metadata that will be placed in the module directory */
int m_flags; /* 0xffff reserved for arch-specific use */
vm_offset_t m_addr; /* load address */
size_t m_size; /* module size */
struct loaded_module *m_next; /* next module */
};
struct module_format
{
int l_format;
/* Load function must return EFTYPE if it can't handle the module supplied */
int (* l_load)(char *filename, vm_offset_t dest, struct loaded_module **result);
int (* l_exec)(struct loaded_module *amp);
};
extern struct module_format *module_formats[]; /* supplied by consumer */
extern struct loaded_module *loaded_modules;
extern int mod_load(char *name, int argc, char *argv[]);
extern struct loaded_module *mod_findmodule(char *name, char *type);
/* XXX these belong in <machine/bootinfo.h> */
#define MODINFO_NAME 0x0000
#define MODINFO_TYPE 0x0001
#define MODINFO_ADDR 0x0002
#define MODINFO_SIZE 0x0003
#define MODINFO_METADATA 0x8000
#if defined(__ELF__)
/*
* Alpha GAS needs an align before the section change. It seems to assume
* that after the .previous, it is aligned, so the following .align 3 is
* ignored. Since the previous instructions often contain strings, this is
* a problem.
*/
#ifdef __alpha__
#define MAKE_SET(set, sym) \
__asm(".align 3"); \
__asm(".section .set." #set ",\"aw\""); \
__asm(".quad " #sym); \
__asm(".previous")
#else
#define MAKE_SET(set, sym) \
__asm(".section .set." #set ",\"aw\""); \
__asm(".long " #sym); \
__asm(".previous")
#endif
#define TEXT_SET(set, sym) MAKE_SET(set, sym)
#define DATA_SET(set, sym) MAKE_SET(set, sym)
#define BSS_SET(set, sym) MAKE_SET(set, sym)
#define ABS_SET(set, sym) MAKE_SET(set, sym)
#else
/*
* Linker set support, directly from <sys/kernel.h>
*
* NB: the constants defined below must match those defined in
* ld/ld.h. Since their calculation requires arithmetic, we
* can't name them symbolically (e.g., 23 is N_SETT | N_EXT).
*/
#define MAKE_SET(set, sym, type) \
static void const * const __set_##set##_sym_##sym = &sym; \
__asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym)
#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23)
#define DATA_SET(set, sym) MAKE_SET(set, sym, 25)
#define BSS_SET(set, sym) MAKE_SET(set, sym, 27)
#define ABS_SET(set, sym) MAKE_SET(set, sym, 21)
#endif
struct linker_set {
int ls_length;
const void *ls_items[1]; /* really ls_length of them, trailing NULL */
};
/*
* Support for commands
*/
struct bootblk_command
{
const char *c_name;
const char *c_desc;
bootblk_cmd_t *c_fn;
};
#define COMMAND_SET(tag, key, desc, func) \
static bootblk_cmd_t func; \
static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \
DATA_SET(Xcommand_set, _cmd_ ## tag);
extern struct linker_set Xcommand_set;
/*
* functions called down from the generic code
*/
struct arch_switch
{
/* Automatically load modules as required by detected hardware */
int (* arch_autoload)();
/* Boot the loaded kernel (first loaded module) */
int (* arch_boot)(void);
/* Locate the device for (name), return pointer to tail in (*path) */
int (*arch_getdev)(void **dev, char *name, char **path);
};
extern struct arch_switch archsw;

155
sys/boot/common/commands.c Normal file
View File

@ -0,0 +1,155 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <string.h>
#include <sys/reboot.h>
#include "bootstrap.h"
char *command_errmsg;
char command_errbuf[256]; /* XXX should have procedural interface for setting, size limit? */
COMMAND_SET(help, "help", "detailed help", command_help);
static int
command_help(int argc, char *argv[])
{
char helppath[80]; /* XXX buffer size? */
/* page the help text from our load path */
sprintf(helppath, "%s/boot.help", getenv("loaddev"));
printf("%s\n", helppath);
if (pager_file(helppath) == -1)
printf("Verbose help not available, use '?' to list commands\n");
return(CMD_OK);
}
COMMAND_SET(commandlist, "?", "list commands", command_commandlist);
static int
command_commandlist(int argc, char *argv[])
{
struct bootblk_command **cmdp;
int i;
printf("Available commands:\n");
cmdp = (struct bootblk_command **)Xcommand_set.ls_items;
for (i = 0; i < Xcommand_set.ls_length; i++)
if (cmdp[i]->c_name != NULL)
printf(" %-15s %s\n", cmdp[i]->c_name, cmdp[i]->c_desc);
return(CMD_OK);
}
/*
* XXX set/show should become set/echo if we have variable
* substitution happening.
*/
COMMAND_SET(show, "show", "show variable(s)", command_show);
static int
command_show(int argc, char *argv[])
{
struct env_var *ev;
char *cp;
if (argc < 2) {
/*
* With no arguments, print everything.
*/
pager_open();
for (ev = environ; ev != NULL; ev = ev->ev_next) {
pager_output(ev->ev_name);
cp = getenv(ev->ev_name);
if (cp != NULL) {
pager_output("=");
pager_output(cp);
}
pager_output("\n");
}
pager_close();
} else {
if ((cp = getenv(argv[1])) != NULL) {
printf("%s\n", cp);
} else {
sprintf(command_errbuf, "variable '%s' not found", argv[1]);
return(CMD_ERROR);
}
}
return(CMD_OK);
}
COMMAND_SET(set, "set", "set a variable", command_set);
static int
command_set(int argc, char *argv[])
{
int err;
if (argc != 2) {
command_errmsg = "wrong number of arguments";
return(CMD_ERROR);
} else {
if ((err = putenv(argv[1])) != 0) {
command_errmsg = strerror(err);
return(CMD_ERROR);
}
}
return(CMD_OK);
}
COMMAND_SET(unset, "unset", "unset a variable", command_unset);
static int
command_unset(int argc, char *argv[])
{
int err;
if (argc != 2) {
command_errmsg = "wrong number of arguments";
return(CMD_ERROR);
} else {
if ((err = unsetenv(argv[1])) != 0) {
command_errmsg = strerror(err);
return(CMD_ERROR);
}
}
return(CMD_OK);
}
COMMAND_SET(panic, "panic", "test panic", command_panic);
static int
command_panic(int argc, char *argv[])
{
char *cp;
cp = unargv(argc - 1, argv + 1);
panic(cp);
}

142
sys/boot/common/console.c Normal file
View File

@ -0,0 +1,142 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
/*
* Core console support
*/
static int cons_set(struct env_var *ev, int flags, void *value);
static int cons_find(char *name);
/*
* Detect possible console(s) to use. The first probed console
* is marked active. Also create the console variable.
*
* XXX Add logic for multiple console support.
*/
void
cons_probe(void)
{
int cons;
int active;
/* Do all console probes, make the fist fully functional console active */
for (cons = 0, active = -1; consoles[cons] != NULL; cons++) {
consoles[cons]->c_flags = 0;
consoles[cons]->c_probe(consoles[cons]);
if ((consoles[cons]->c_flags == (C_PRESENTIN | C_PRESENTOUT)) && (active == -1)) {
consoles[cons]->c_flags |= (C_ACTIVEIN | C_ACTIVEOUT);
active = cons;
}
}
printf("Console: %s\n", consoles[active]->c_desc);
env_setenv("console", 0, consoles[active]->c_name, cons_set, env_nounset);
}
int
getchar(void)
{
int cons;
int rv;
/* Loop forever polling all active consoles */
for(;;)
for (cons = 0; consoles[cons] != NULL; cons++)
if ((consoles[cons]->c_flags & C_ACTIVEIN) &&
((rv = consoles[cons]->c_in()) != -1))
return(rv);
}
int
ischar(void)
{
int cons;
for (cons = 0; consoles[cons] != NULL; cons++)
if ((consoles[cons]->c_flags & C_ACTIVEIN) &&
(consoles[cons]->c_ready() != 0))
return(1);
return(0);
}
void
putchar(int c)
{
int cons;
/* Expand newlines */
if (c == '\n')
putchar('\r');
for (cons = 0; consoles[cons] != NULL; cons++)
if (consoles[cons]->c_flags & C_ACTIVEOUT)
consoles[cons]->c_out(c);
}
static int
cons_find(char *name)
{
int cons;
for (cons = 0; consoles[cons] != NULL; cons++)
if (!strcmp(consoles[cons]->c_name, name))
return(cons);
return(-1);
}
/*
* Select a console.
*
* XXX Note that the console system design allows for some extension
* here (eg. multiple consoles, input/output only, etc.)
*/
static int
cons_set(struct env_var *ev, int flags, void *value)
{
int cons, active;
if ((active = cons_find(value)) == -1) {
printf("no such console '%s'\n", (char *)value);
return(CMD_ERROR);
}
/* disable all current consoles */
for (cons = 0; consoles[cons] != NULL; cons++)
consoles[cons]->c_flags &= ~(C_ACTIVEIN | C_ACTIVEOUT);
/* enable selected console */
consoles[active]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
return(CMD_OK);
}

275
sys/boot/common/dev_net.c Normal file
View File

@ -0,0 +1,275 @@
/*
* $Id$
* From: $NetBSD: dev_net.c,v 1.12 1997/12/10 20:38:37 gwr Exp $
*/
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Gordon W. Ross.
*
* 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 NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* This module implements a "raw device" interface suitable for
* use by the stand-alone I/O library NFS code. This interface
* does not support any "block" access, and exists only for the
* purpose of initializing the network interface, getting boot
* parameters, and performing the NFS mount.
*
* At open time, this does:
*
* find interface - netif_open()
* RARP for IP address - rarp_getipaddress()
* RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...)
* RPC/mountd - nfs_mount(sock, ip, path)
*
* the root file handle from mountd is saved in a global
* for use by the NFS open code (NFS/lookup).
*/
#include <machine/stdarg.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <stand.h>
#include <net.h>
#include <netif.h>
#include <nfs.h>
#include <bootparam.h>
#include "dev_net.h"
#include "bootstrap.h"
int debug = 0;
static int netdev_sock = -1;
static int netdev_opens;
static int net_init(void);
static int net_open(struct open_file *, void *vdev);
static int net_close(struct open_file *);
static int net_ioctl();
static int net_strategy();
static int net_getparams(int sock);
struct devsw netdev = {
"net",
DEVT_NET,
net_init,
net_strategy,
net_open,
net_close,
noioctl
};
int
net_init(void)
{
return 0;
}
/*
* Called by devopen after it sets f->f_dev to our devsw entry.
* This opens the low-level device and sets f->f_devdata.
* This is declared with variable arguments...
*/
int
net_open(struct open_file *f, void *vdev)
{
char *devname; /* Device part of file name (or NULL). */
int error = 0;
devname = vdev;
/* On first open, do netif open, mount, etc. */
if (netdev_opens == 0) {
/* Find network interface. */
if (netdev_sock < 0) {
netdev_sock = netif_open(devname);
if (netdev_sock < 0) {
printf("net_open: netif_open() failed\n");
return (ENXIO);
}
if (debug)
printf("net_open: netif_open() succeeded\n");
}
if (rootip.s_addr == 0) {
/* Get root IP address, and path, etc. */
error = net_getparams(netdev_sock);
if (error) {
/* getparams makes its own noise */
netif_close(netdev_sock);
netdev_sock = -1;
return (error);
}
}
}
netdev_opens++;
f->f_devdata = &netdev_sock;
return (error);
}
int
net_close(f)
struct open_file *f;
{
#ifdef NETIF_DEBUG
if (debug)
printf("net_close: opens=%d\n", netdev_opens);
#endif
/* On last close, do netif close, etc. */
f->f_devdata = NULL;
/* Extra close call? */
if (netdev_opens <= 0)
return (0);
/*
* On SRM boots opening the device the first time takes ages
* I don't see the point of doing this every time you load a file
*/
/* netdev_opens--; */
/* Not last close? */
if (netdev_opens > 0)
return(0);
rootip.s_addr = 0;
if (netdev_sock >= 0) {
if (debug)
printf("net_close: calling netif_close()\n");
netif_close(netdev_sock);
netdev_sock = -1;
}
return (0);
}
int
net_ioctl()
{
return EIO;
}
int
net_strategy()
{
return EIO;
}
#define SUPPORT_BOOTP
/*
* Get info for NFS boot: our IP address, our hostname,
* server IP address, and our root path on the server.
* There are two ways to do this: The old, Sun way,
* and the more modern, BOOTP way. (RFC951, RFC1048)
*
* The default is to use the Sun bootparams RPC
* (because that is what the kernel will do).
* MD code can make try_bootp initialied data,
* which will override this common definition.
*/
#ifdef SUPPORT_BOOTP
int try_bootp = 1;
int bootp(int sock);
#endif
static int
net_getparams(sock)
int sock;
{
char buf[MAXHOSTNAMELEN];
n_long smask;
#ifdef SUPPORT_BOOTP
/*
* Try to get boot info using BOOTP. If we succeed, then
* the server IP address, gateway, and root path will all
* be initialized. If any remain uninitialized, we will
* use RARP and RPC/bootparam (the Sun way) to get them.
*/
if (try_bootp)
bootp(sock);
if (myip.s_addr != 0)
return (0);
if (debug)
printf("net_open: BOOTP failed, trying RARP/RPC...\n");
#endif
/*
* Use RARP to get our IP address. This also sets our
* netmask to the "natural" default for our address.
*/
if (rarp_getipaddress(sock)) {
printf("net_open: RARP failed\n");
return (EIO);
}
printf("net_open: client addr: %s\n", inet_ntoa(myip));
/* Get our hostname, server IP address, gateway. */
if (bp_whoami(sock)) {
printf("net_open: bootparam/whoami RPC failed\n");
return (EIO);
}
printf("net_open: client name: %s\n", hostname);
/*
* Ignore the gateway from whoami (unreliable).
* Use the "gateway" parameter instead.
*/
smask = 0;
gateip.s_addr = 0;
if (bp_getfile(sock, "gateway", &gateip, buf) == 0) {
/* Got it! Parse the netmask. */
smask = ip_convertaddr(buf);
}
if (smask) {
netmask = smask;
printf("net_open: subnet mask: %s\n", intoa(netmask));
}
if (gateip.s_addr)
printf("net_open: net gateway: %s\n", inet_ntoa(gateip));
/* Get the root server and pathname. */
if (bp_getfile(sock, "root", &rootip, rootpath)) {
printf("net_open: bootparam/getfile RPC failed\n");
return (EIO);
}
printf("net_open: server addr: %s\n", inet_ntoa(rootip));
printf("net_open: server path: %s\n", rootpath);
return (0);
}

30
sys/boot/common/dev_net.h Normal file
View File

@ -0,0 +1,30 @@
/*-
* Copyright (c) 1998 Doug Rabson <dfr@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
extern struct devsw netdev;

61
sys/boot/common/devopen.c Normal file
View File

@ -0,0 +1,61 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
int
devopen(struct open_file *f, const char *fname, char **file)
{
struct devdesc *dev;
int result;
if ((result = archsw.arch_getdev((void *)&dev, fname, file)) == 0) { /* get the device */
/* point to device-specific data so that device open can use it */
f->f_devdata = dev;
if ((result = dev->d_dev->dv_open(f, dev)) == 0) { /* try to open it */
/* reference the devsw entry from the open_file structure */
f->f_dev = dev->d_dev;
} else {
free(dev); /* release the device descriptor */
}
}
return(result);
}
int
devclose(struct open_file *f)
{
if (f->f_devdata != NULL) {
free(f->f_devdata);
}
return(0);
}

207
sys/boot/common/interp.c Normal file
View File

@ -0,0 +1,207 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* Simple commandline interpreter.
*
* XXX may be obsoleted by BootFORTH
*/
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
#define MAXARGS 20 /* maximum number of arguments allowed */
static int parse(char *buf, int *argcp, char **argvp[]);
static void prompt(void);
/*
* Parse the supplied text into argv/argc form.
* XXX should perhaps learn about quotes, etc?
* XXX can also do alias expansion, variable substitution, etc. here
*/
static int
parse(char *buf, int *argcp, char **argvp[])
{
static int argc;
static char *argv[MAXARGS], *cp;
argc = 0;
cp = buf;
while ((*cp != 0) && (argc < MAXARGS)) {
if (isspace(*cp)) {
*(cp++) = 0;
} else {
argv[argc++] = cp++;
while ((*cp != 0) && !isspace(*cp))
cp++;
}
}
argv[argc] = NULL;
/* command too complex */
if (argc >= MAXARGS) {
printf("too many arguments\n");
return(1);
}
*argcp = argc;
*argvp = argv;
return(0);
}
/*
* Perform the command
*/
static int
perform(int argc, char *argv[])
{
int i, result;
struct bootblk_command **cmdp;
bootblk_cmd_t *cmd;
if (argc < 1)
return(CMD_OK);
/* set return defaults; a successful command will override these */
command_errmsg = command_errbuf;
strcpy(command_errbuf, "no error message");
cmd = NULL;
result = CMD_ERROR;
cmdp = (struct bootblk_command **)Xcommand_set.ls_items;
for (i = 0; i < Xcommand_set.ls_length; i++) {
if ((cmdp[i]->c_name != NULL) && !strcmp(argv[0], cmdp[i]->c_name))
cmd = cmdp[i]->c_fn;
}
if (cmd != NULL) {
result = (cmd)(argc, argv);
} else {
command_errmsg = "unknown command";
}
return(result);
}
/*
* Interactive mode
*/
void
interact(void)
{
char input[256]; /* big enough? */
int argc;
char **argv;
for (;;) {
input[0] = '\0';
prompt();
ngets(input, sizeof(input));
if (!parse(input, &argc, &argv) &&
(perform(argc, argv) != 0))
printf("%s: %s\n", argv[0], command_errmsg);
}
}
/*
* Read command from a file
*/
COMMAND_SET(source, "source", "read commands from a file", command_source);
static int
command_source(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++)
source(argv[i]);
return(CMD_OK);
}
void
source(char *filename)
{
char input[256]; /* big enough? */
int argc;
char **argv, *cp;
int fd;
if (((fd = open(filename, O_RDONLY)) == -1)) {
printf("can't open '%s': %s\n", filename, strerror(errno));
} else {
while (fgetstr(input, sizeof(input), fd) > 0) {
/* Discard comments */
if (input[0] == '#')
continue;
cp = input;
/* Echo? */
if (input[0] == '@') {
cp++;
} else {
prompt();
printf("%s\n", input);
}
if (!parse(cp, &argc, &argv) &&
(argc > 0) &&
(perform(argc, argv) != 0))
printf("%s: %s\n", argv[0], command_errmsg);
}
close(fd);
}
}
/*
* Emit the current prompt; support primitive embedding of
* environment variables.
* We're a little rude here, modifying the return from getenv().
*/
static void
prompt(void)
{
char *p, *cp, *ev, c;
if ((p = getenv("prompt")) == NULL)
p = ">";
while (*p != 0) {
if (*p == '$') {
for (cp = p + 1; (*cp != 0) && isalpha(*cp); cp++)
;
c = *cp;
*cp = 0;
ev = getenv(p + 1);
*cp = c;
if (ev != NULL) {
printf(ev);
p = cp;
continue;
}
}
putchar(*p++);
}
putchar(' ');
}

101
sys/boot/common/load.c Normal file
View File

@ -0,0 +1,101 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#define LOAD_TINYBUF 2048
/*
* Attempt to load the file at (path) into an allocated
* area on the heap, return a pointer to it or NULL
* on failure.
*
* Because in many cases it is impossible to determine the
* true size of a file without reading it, we do just that.
*/
char *
filedup(const char *path, int flags)
{
char *buf;
int fd;
size_t size, result;
if ((fd = open(path, F_READ | flags)) == -1)
return(NULL);
printf("%s open, flags 0x%x\n", path, files[fd].f_flags);
buf = alloc(LOAD_TINYBUF);
/* Read the first buffer-full */
size = read(fd, buf, LOAD_TINYBUF);
if (size < 1) {
free(buf, LOAD_TINYBUF);
close(fd);
return(NULL);
}
/* If it all fitted, then just return the buffer straight out */
if (size < LOAD_TINYBUF) {
close(fd);
buf[size] = 0;
return(buf);
}
printf("tinybuf loaded, size %d\n", size);
getchar();
/* Read everything until we know how big it is */
for (;;) {
result = read(fd, buf, LOAD_TINYBUF);
if (size == -1) {
free(buf, LOAD_TINYBUF);
close(fd);
return(NULL);
}
if (result == 0)
break;
size += result;
}
/* discard the old buffer, close the file */
free(buf, LOAD_TINYBUF);
close(fd);
/* reopen the file, realloc the buffer */
if ((fd = open(path, F_READ | flags)) == -1)
return(NULL);
buf = alloc(size);
result = read(fd, buf, size);
close(fd);
if (result != size) {
free(buf, size);
return(NULL);
}
return(buf);
}

160
sys/boot/common/ls.c Normal file
View File

@ -0,0 +1,160 @@
/*
* $Id$
* From: $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $
*/
/*
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1996
* Matthias Drochner. 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.
*/
#include <sys/param.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <stand.h>
#include "bootstrap.h"
static char typestr[] = "?fc?d?b? ?l?s?w";
COMMAND_SET(ls, "ls", "list files", command_ls);
static int
command_ls(int argc, char *argv[])
{
int fd;
struct stat sb;
size_t size;
char dirbuf[DIRBLKSIZ];
char pathbuf[128]; /* XXX path length constant? */
char buf[128]; /* must be long enough for dir entry! */
char *path;
int result, ch;
#ifdef VERBOSE_LS
int verbose;
verbose = 0;
optind = 1;
while ((ch = getopt(argc, argv, "l")) != -1) {
switch(ch) {
case 'l':
verbose = 1;
break;
case '?':
default:
/* getopt has already reported an error */
return(CMD_OK);
}
}
argv += (optind - 1);
argc -= (optind - 1);
#endif
if (argc < 2) {
path = "/";
} else {
path = argv[1];
}
pager_open();
pager_output(path);
pager_output("\n");
fd = open(path, O_RDONLY);
if (fd < 0) {
sprintf(command_errbuf, "open '%s' failed: %s", path, strerror(errno));
return(CMD_ERROR);
}
result = CMD_OK;
if (fstat(fd, &sb) < 0) {
sprintf(command_errbuf, "stat failed: %s", strerror(errno));
result = CMD_ERROR;
goto out;
}
if (!S_ISDIR(sb.st_mode)) {
sprintf(command_errbuf, "%s: %s", path, strerror(ENOTDIR));
result = CMD_ERROR;
goto out;
}
while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) {
struct direct *dp, *edp;
dp = (struct direct *) dirbuf;
edp = (struct direct *) (dirbuf + size);
while (dp < edp) {
if (dp->d_ino != (ino_t) 0) {
if ((dp->d_namlen > MAXNAMLEN + 1) || (dp->d_type > sizeof(typestr))) {
/*
* This does not handle "old"
* filesystems properly. On little
* endian machines, we get a bogus
* type name if the namlen matches a
* valid type identifier. We could
* check if we read namlen "0" and
* handle this case specially, if
* there were a pressing need...
*/
command_errmsg = "bad dir entry";
result = CMD_ERROR;
goto out;
}
if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
#ifdef VERBOSE_LS /* too much UFS activity blows the heap out */
if (verbose) {
/* stat the file, if possible */
sb.st_size = 0;
sprintf(buf, "%s/%s", pathbuf, dp->d_name);
/* ignore return */
if (stat(buf, &sb))
sb.st_size = -1;
sprintf(buf, " %c %8d %s\n", typestr[dp->d_type], (int)sb.st_size, dp->d_name);
#endif
} else
sprintf(buf, " %c %s\n", typestr[dp->d_type], dp->d_name);
if (pager_output(buf))
goto out;
}
}
dp = (struct direct *) ((char *) dp + dp->d_reclen);
}
}
out:
pager_close();
close(fd);
return(result);
}

55
sys/boot/common/misc.c Normal file
View File

@ -0,0 +1,55 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <string.h>
#include <stand.h>
/*
* Concatenate the (argc) elements of (argv) into a single string, and return
* a copy of same.
*/
char *
unargv(int argc, char *argv[])
{
size_t hlong;
int i;
char *cp;
for (hlong = 0, i = 0, hlong = 0; i < argc; i++)
hlong += strlen(argv[i]) + 1;
if(hlong == 0)
return(NULL);
cp = malloc(hlong);
cp[0] = 0;
for (i = 0; i < argc; i++)
strcat(cp, argv[i]);
return(cp);
}

129
sys/boot/common/module.c Normal file
View File

@ -0,0 +1,129 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* module function dispatcher, support, etc.
*
* XXX need a 'searchmodule' function that takes a name and
* traverses a search path.
*/
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
/* Initially determined from kernel load address */
static vm_offset_t loadaddr = 0;
struct loaded_module *loaded_modules = NULL;
COMMAND_SET(load, "load", "load a kernel or module", command_load);
static int
command_load(int argc, char *argv[])
{
return(mod_load(argv[1], argc - 2, argv + 2));
}
COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod);
static int
command_lsmod(int argc, char *argv[])
{
struct loaded_module *am;
char lbuf[80];
pager_open();
for (am = loaded_modules; (am != NULL); am = am->m_next) {
sprintf(lbuf, " %p: %s (%s, 0x%x)\n",
am->m_addr, am->m_name, am->m_type, am->m_size);
pager_output(lbuf);
if (am->m_args != NULL) {
pager_output(" args: ");
pager_output(am->m_args);
pager_output("\n");
}
}
pager_close();
return(CMD_OK);
}
int
mod_load(char *name, int argc, char *argv[])
{
struct loaded_module *am, *cm;
int i, err;
for (i = 0, am = NULL; (module_formats[i] != NULL) && (am == NULL); i++) {
/* XXX call searchmodule() to search for module (name) */
if ((err = (module_formats[i]->l_load)(name, loadaddr, &am)) != 0) {
/* Unknown to this handler? */
if (err == EFTYPE)
continue;
/* Fatal error */
sprintf(command_errbuf, "can't load module '%s': %s", name, strerror(err));
return(CMD_ERROR);
}
}
if (am == NULL) {
sprintf(command_errbuf, "can't work out what to do with '%s'", name);
return(CMD_ERROR);
}
/* where can we put the next one? */
loadaddr = am->m_addr + am->m_size;
/* Load was OK, set args */
am->m_args = unargv(argc, argv);
/* Append to list of loaded modules */
am->m_next = NULL;
if (loaded_modules == NULL) {
loaded_modules = am;
} else {
for (cm = loaded_modules; cm->m_next != NULL; cm = cm->m_next)
;
cm->m_next = am;
}
return(CMD_OK);
}
struct loaded_module *
mod_findmodule(char *name, char *type)
{
struct loaded_module *mp;
for (mp = loaded_modules; mp != NULL; mp = mp->m_next) {
if (((name == NULL) || !strcmp(name, mp->m_name)) &&
((type == NULL) || !strcmp(type, mp->m_type)))
break;
}
return(mp);
}

56
sys/boot/common/panic.c Normal file
View File

@ -0,0 +1,56 @@
/*
* $Id$
* From: $NetBSD: panic.c,v 1.2 1997/03/22 01:48:36 thorpej Exp $
*/
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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 <stand.h>
#include <machine/stdarg.h>
__dead void
panic(const char *fmt,...)
{
va_list ap;
printf("panic: ");
va_start(ap, fmt);
printf(fmt, ap);
printf("\n");
va_end(ap);
printf("Press a key to reboot\n");
getchar();
exit(1);
}

3
sys/boot/i386/Makefile Normal file
View File

@ -0,0 +1,3 @@
SUBDIR= installboot libi386 loader
.include <bsd.subdir.mk>

View File

@ -0,0 +1,16 @@
# $NetBSD: Makefile,v 1.5 1998/03/02 19:57:01 cgd Exp $
.include <bsd.own.mk>
BINDIR= /usr/mdec
PROG= installboot
SRCS= installboot.c bootblks.c getmount.c
NOMAN= yes
CPPFLAGS= -I${.CURDIR}/../libi386/crt/bootsect
CFLAGS+= -Wall ${CPPFLAGS}
LDSTATIC?=-static
.include <bsd.prog.mk>

View File

@ -0,0 +1,146 @@
/* $NetBSD: bootblks.c,v 1.2 1997/07/21 18:04:35 drochner Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <err.h>
#include "installboot.h"
static char bootblkpath[MAXPATHLEN];
static char backuppath[MAXPATHLEN];
static char backupext[] = ".bak";
static int havebackup;
ino_t
createfileondev(diskdev, bootblkname, bp, size)
char *diskdev, *bootblkname;
char *bp;
int size;
{
char *mntpoint;
int fd = -1;
struct stat statbuf;
int allok = 0;
if ((mntpoint = getmountpoint(diskdev)) == NULL)
return ((ino_t) - 1);
/*
* create file in fs root for bootloader data
* try to rename existing file before
*/
havebackup = 0;
sprintf(bootblkpath, "%s/%s", mntpoint, bootblkname);
sprintf(backuppath, "%s%s", bootblkpath, backupext);
if(rename(bootblkpath, backuppath) == -1) {
if(errno != ENOENT) {
warn("rename old %s", bootblkpath);
goto out;
}
} else {
if(verbose)
fprintf(stderr, "renamed %s -> %s\n",
bootblkpath, backuppath);
havebackup = 1;
}
fd = open(bootblkpath, O_RDWR | O_CREAT | O_EXCL, 0444);
if (fd < 0) {
warn("open %s", bootblkpath);
goto out;
}
/*
* do the write, flush, get inode number
*/
if (write(fd, bp, size) < 0) {
warn("write %s", bootblkpath);
goto out;
}
if (fsync(fd) != 0) {
warn("fsync: %s", bootblkpath);
goto out;
}
if (fstat(fd, &statbuf) != 0) {
warn("fstat: %s", bootblkpath);
goto out;
}
allok = 1;
out:
if (fd != -1) {
close(fd);
if (!allok)
unlink(bootblkpath);
}
if(!allok && havebackup)
rename(backuppath, bootblkpath);
cleanupmount(mntpoint);
return (allok ? statbuf.st_ino : (ino_t) - 1);
}
void
cleanupfileondev(diskdev, bootblkname, recover)
char *diskdev, *bootblkname;
{
char *mntpoint;
/* save some work if nothing to do */
if(!(recover || havebackup))
return;
if ((mntpoint = getmountpoint(diskdev)) == NULL)
return;
sprintf(bootblkpath, "%s/%s", mntpoint, bootblkname);
sprintf(backuppath, "%s%s", bootblkpath, backupext);
if(recover) {
unlink(bootblkpath);
if(havebackup) {
fprintf(stderr, "renaming %s -> %s\n",
backuppath, bootblkpath);
rename(backuppath, bootblkpath);
}
} else if(havebackup) {
if(verbose)
fprintf(stderr, "deleting %s\n", backuppath);
unlink(backuppath);
}
cleanupmount(mntpoint);
}

View File

@ -0,0 +1,156 @@
/* $NetBSD: getmount.c,v 1.3 1998/03/01 13:22:55 fvdl Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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 <ufs/ufs/ufsmount.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
#include "installboot.h"
static int tempmounted = 0;
/* make block device name from character device name */
static char *
getbdev(dev)
char *dev;
{
static char bdiskdev[MAXPATHLEN];
if (strncmp(dev, "/dev/r", 6)) {
warnx("bad device name %s", dev);
return (0);
}
sprintf(bdiskdev, "/dev/%s", dev + 6);
return (bdiskdev);
}
/*
* create mountpoint and mount given block device there, return
* mountpoint
*/
static char *
dotempmount(bdiskdev)
char *bdiskdev;
{
static char dir[] = "/tmp/installbootXXXXXX";
struct ufs_args data;
if (mktemp(dir) == NULL) {
warnx("mktemp failed");
return (0);
}
if (mkdir(dir, 0700)) {
warn("could not create temporary dir %s", dir);
return (0);
}
bzero(&data, sizeof(data));
data.fspec = bdiskdev;
/* this code if FFS only */
if (mount("ufs", dir, 0, &data) == -1) {
warn("mount %s->%s failed", bdiskdev, dir);
rmdir(dir);
return (0);
}
if (verbose)
fprintf(stderr, "mounted %s at %s\n", bdiskdev, dir);
tempmounted = 1;
return (dir);
}
/*
* Find out if given character device is already mounted. If not, mount it
* temporarily.
*/
char *
getmountpoint(diskdev)
char *diskdev;
{
char *bdiskdev;
struct statfs *buf;
int num, i;
bdiskdev = getbdev(diskdev);
if (bdiskdev == NULL)
return (0);
num = getmntinfo(&buf, MNT_WAIT);
if (num == 0) {
warn("getmntinfo");
return (0);
}
for (i = 0; i < num; i++)
if (strncmp(bdiskdev, buf[i].f_mntfromname, MNAMELEN) == 0) {
int j;
/* Device is mounted. If there are more devices mounted
at the same point, the fs could be hidden. Don't think
too much about layering order - simply refuse. */
for (j = 0; j < num; j++)
if ((i != j) && (strncmp(buf[i].f_mntonname,
buf[j].f_mntonname,
MNAMELEN) == 0)) {
warnx("there is more than 1 mount at %s",
buf[i].f_mntonname);
return (0);
}
/* this code is FFS only */
if (strncmp(buf[i].f_fstypename, "ufs", MFSNAMELEN)) {
warnx("%s: must be a FFS filesystem", bdiskdev);
return (0);
}
return (buf[i].f_mntonname);
}
if (verbose)
fprintf(stderr, "%s is not mounted\n", bdiskdev);
return (dotempmount(bdiskdev));
}
void
cleanupmount(dir)
char *dir;
{
if (tempmounted) {
if (verbose)
fprintf(stderr, "unmounting\n");
unmount(dir, 0);
rmdir(dir);
tempmounted = 0;
}
}

View File

@ -0,0 +1,150 @@
.\" $NetBSD: installboot.8,v 1.1.1.1 1997/03/14 02:40:32 perry Exp $
.\"
.\" Copyright (c) 1997 Perry E. Metzger. All rights reserved.
.\" Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
.\" Copyright (c) 1995 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.
.\" 3. 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.
.\"
.Dd March 14, 1997
.Dt INSTALLBOOT 8 i386
.Os
.Sh NAME
.Nm installboot
.Nd install disk bootstrap software
.Sh SYNOPSIS
.Nm installboot
.Op Fl nvf
.Ar bootfile
.Ar rawdiskdevice
.Sh DESCRIPTION
The
.Nm installboot
utility prepares a disk for bootstrapping.
.Pp
The
.Nx /i386
disk bootstrap software is split into two parts:
a small first-stage boot program that is written into the disklabel
area of a disk and a second-stage boot program that resides in a FFS file
system on the disk (named
.Pa /boot ) .
Both parts of the boot are derived from a single object file
which is split by
.Nm
during the installation process.
The first-stage boot program is loaded into memory by the BIOS.
After receiving control of the system, it loads the
second-stage boot program from a set of filesystem block numbers that
have been hard-coded into it by
.Nm
during execution.
The second-stage boot program then locates and loads the kernel.
.Pp
Note: so that the
.Pa /boot
file can be installed on the bootable partition, the partition must be
mounted before
.Nm
is run.
.Pp
The options recognized by
.Nm installboot
are as follows:
.Bl -tag -width flag
.It Fl n
Do not actually write anything on the disk.
.It Fl v
Verbose mode.
.It Fl f
Force a write of the boot blocks (with the first stage put at offset
zero) even if no disk label is detected.
This is useful if there is no disk label (as is often the case with
floppy or vnode devices).
.El
.Pp
The arguments are:
.Bl -tag -width rawdiskdevice
.It Ar bootfile
The name of the special object file
(typically
.Pa /usr/mdec/biosboot.sym )
where the first and second stage boot programs to be installed reside.
.It Ar rawdiskdevice
The name of the device corresponding to the raw whole-disk partition (the
.Dq raw partition )
of the disk on which the first-stage boot program is to be installed.
.El
.Sh EXAMPLES
Assuming the file containing the boot program is in its typical place,
and you wished to make
.Pa /dev/fd0a
bootable. One might first mount
.Pa /dev/fd0a
on
.Pa /mnt ,
and in the case that there is already a file named
.Pa boot
in that directory, remove it.
To install the boot blocks, one then would issue the command:
.Bd -literal -offset indent
installboot -f /usr/mdec/biosboot.sym /dev/rfd0a
.Ed
Note that the -f option is needed if the floppy is unlabeled -- see
.Xr disklabel 8 .
.Sh BUGS
The NetBSD/i386 boot blocks can only read from the first 1024
cylinders of the disk because they use the BIOS to do their I/O. Thus,
it is advisable that
.Dq a
partitions reside entirely within the first 1024 cylinders.
.Pp
.Nm
requires simultaneous access to the mounted file system and
the disks' raw partition.
That is not allowed with the kernel
.Dv securelevel
variable
.Po
see
.Xr sysctl 8
.Pc
set to a value greater than one, or with
.Dv securelevel
set to one if the
.Dq boot
program resides in a file system on the disk's raw partition.
.Sh "SEE ALSO"
.Xr boot 8 ,
.Xr disklabel 8 ,
.Xr init 8 ,
.Xr sysctl 8 ,
.Xr vnd 4
.Sh HISTORY
The NetBSD/i386
.Nm
command first appeared in
.Nx 1.3 .

View File

@ -0,0 +1,433 @@
/* $NetBSD: installboot.c,v 1.5 1997/11/01 06:49:50 lukem Exp $ */
/*
* Copyright (c) 1994 Paul Kranenburg
* All rights reserved.
* Copyright (c) 1996, 1997
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996, 1997
* Perry E. Metzger. 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.
* This product includes software developed for the NetBSD Project
* by Matthias Drochner.
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 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/disklabel.h>
/* #include <sys/dkio.h> */
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
#include <sys/errno.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>
#include <sys/ioctl.h>
#include "installboot.h"
#include "bbinfo.h"
#define DEFBBLKNAME "boot"
struct fraglist *fraglist;
struct nlist nl[] = {
#define X_fraglist 0
{{"_fraglist"}},
{{NULL}}
};
int verbose = 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;
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 text!). */
for (nlp = nl; nlp->n_un.n_name; nlp++) {
if (nlp->n_type != (N_TEXT | 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%lx", eh.a_midmag);
goto bad;
}
/*
* We need only text and data.
*/
tdsize = eh.a_text + eh.a_data;
bbsize = roundup(tdsize, DEV_BSIZE);
if ((bp = calloc(bbsize, 1)) == NULL) {
warnx("malloc: %s: no memory", fname);
goto bad;
}
/* read the rest of the file. */
if (read(fd, bp, tdsize) != tdsize) {
warn("read: %s", fname);
goto bad;
}
*size = bbsize; /* aligned to DEV_BSIZE */
fraglist = (struct fraglist *) (bp + nl[X_fraglist].n_value);
if (fraglist->magic != FRAGLISTMAGIC) {
warnx("invalid bootblock version");
goto bad;
}
if (verbose) {
fprintf(stderr, "%s: entry point %#lx\n", fname, eh.a_entry);
fprintf(stderr, "proto bootblock size %ld\n", *size);
fprintf(stderr, "room for %d filesystem blocks at %#lx\n",
fraglist->maxentries, nl[X_fraglist].n_value);
}
close(fd);
return bp;
bad:
if (bp)
free(bp);
if (fd >= 0)
close(fd);
return NULL;
}
static int
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)) {
warn("%s: devread: lseek", msg);
return (1);
}
if (read(fd, buf, size) != size) {
warn("%s: devread: read", msg);
return (1);
}
return (0);
}
/* add file system blocks to fraglist */
static int
add_fsblk(fs, blk, blcnt)
struct fs *fs;
daddr_t blk;
int blcnt;
{
int nblk;
/* convert to disk blocks */
blk = fsbtodb(fs, blk);
nblk = fs->fs_bsize / DEV_BSIZE;
if (nblk > blcnt)
nblk = blcnt;
if (verbose)
fprintf(stderr, "dblk: %d, num: %d\n", blk, nblk);
/* start new entry or append to previous? */
if (!fraglist->numentries ||
(fraglist->entries[fraglist->numentries - 1].offset
+ fraglist->entries[fraglist->numentries - 1].num != blk)) {
/* need new entry */
if (fraglist->numentries > fraglist->maxentries - 1) {
errx(1, "not enough fragment space in bootcode\n");
return(-1);
}
fraglist->entries[fraglist->numentries].offset = blk;
fraglist->entries[fraglist->numentries++].num = 0;
}
fraglist->entries[fraglist->numentries - 1].num += nblk;
return (blcnt - nblk);
}
static char sblock[SBSIZE];
int
loadblocknums(diskdev, inode)
char *diskdev;
ino_t inode;
{
int devfd = -1;
struct fs *fs;
char *buf = 0;
daddr_t blk, *ap;
struct dinode *ip;
int i, ndb;
int allok = 0;
devfd = open(diskdev, O_RDONLY, 0);
if (devfd < 0) {
warn("open raw partition");
return (1);
}
/* Read superblock */
if (devread(devfd, sblock, SBLOCK, SBSIZE, "superblock"))
goto out;
fs = (struct fs *) sblock;
if (fs->fs_magic != FS_MAGIC) {
warnx("invalid super block");
goto out;
}
/* Read inode */
if ((buf = malloc(fs->fs_bsize)) == NULL) {
warnx("No memory for filesystem block");
goto out;
}
blk = fsbtodb(fs, ino_to_fsba(fs, inode));
if (devread(devfd, buf, blk, fs->fs_bsize, "inode"))
goto out;
ip = (struct dinode *) (buf) + ino_to_fsbo(fs, inode);
/*
* Have the inode. Figure out how many blocks we need.
*/
ndb = ip->di_size / DEV_BSIZE; /* size is rounded! */
if (verbose)
fprintf(stderr, "Will load %d blocks.\n", ndb);
/*
* Get the block numbers, first direct blocks
*/
ap = ip->di_db;
for (i = 0; i < NDADDR && *ap && ndb > 0; i++, ap++)
ndb = add_fsblk(fs, *ap, ndb);
if (ndb > 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]);
if (devread(devfd, buf, blk, fs->fs_bsize, "indirect block"))
goto out;
ap = (daddr_t *) buf;
for (; i < NINDIR(fs) && *ap && ndb > 0; i++, ap++) {
ndb = add_fsblk(fs, *ap, ndb);
}
}
if (!ndb)
allok = 1;
else {
if (ndb > 0)
warnx("too many fs blocks");
/* else, ie ndb < 0, add_fsblk returned error */
goto out;
}
out:
if (buf)
free(buf);
if (devfd >= 0)
close(devfd);
return (!allok);
}
static void
usage()
{
fprintf(stderr,
"usage: installboot [-n] [-v] [-f] <boot> <device>\n");
exit(1);
}
int
main(argc, argv)
int argc;
char *argv[];
{
char c, *bp = 0;
long size;
ino_t inode = (ino_t) -1;
int devfd = -1;
struct disklabel dl;
int bsdoffs;
int i, res;
int forceifnolabel = 0;
char *bootblkname = DEFBBLKNAME;
int nowrite = 0;
int allok = 0;
while ((c = getopt(argc, argv, "vnf")) != -1) {
switch (c) {
case 'n':
/* Do not actually write the bootblock to disk */
nowrite = 1;
break;
case 'v':
/* Chat */
verbose = 1;
break;
case 'f':
/* assume zero offset if no disklabel */
forceifnolabel = 1;
break;
default:
usage();
}
}
if (argc - optind != 2) {
usage();
}
bp = loadprotoblocks(argv[optind], &size);
if (!bp)
errx(1, "error reading bootblocks");
fraglist->numentries = 0;
/* do we need the fraglist? */
if (size > fraglist->loadsz * DEV_BSIZE) {
inode = createfileondev(argv[optind + 1], bootblkname,
bp + fraglist->loadsz * DEV_BSIZE,
size - fraglist->loadsz * DEV_BSIZE);
if (inode == (ino_t) - 1)
goto out;
/* paranoia */
sync();
sleep(3);
if (loadblocknums(argv[optind + 1], inode))
goto out;
size = fraglist->loadsz * DEV_BSIZE;
/* size to be written to bootsect */
}
devfd = open(argv[optind + 1], O_RDWR, 0);
if (devfd < 0) {
warn("open raw partition RW");
goto out;
}
if (ioctl(devfd, DIOCGDINFO, &dl) < 0) {
if ((errno == EINVAL) || (errno == ENOTTY)) {
if (forceifnolabel)
bsdoffs = 0;
else {
warnx("no disklabel, use -f to install anyway");
goto out;
}
} else {
warn("get disklabel");
goto out;
}
} else {
char c = argv[optind + 1][strlen(argv[optind + 1]) - 1];
#define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
if(!isvalidpart(c) || (c - 'a') >= dl.d_npartitions) {
warnx("invalid partition");
goto out;
}
bsdoffs = dl.d_partitions[c - 'a'].p_offset;
}
if (verbose)
fprintf(stderr, "BSD partition starts at sector %d\n", bsdoffs);
/*
* add offset of BSD partition to fraglist entries
*/
for (i = 0; i < fraglist->numentries; i++)
fraglist->entries[i].offset += bsdoffs;
if (!nowrite) {
/*
* write first blocks (max loadsz) to start of BSD partition,
* skip disklabel (in second disk block)
*/
lseek(devfd, 0, SEEK_SET);
res = write(devfd, bp, DEV_BSIZE);
if (res < 0) {
warn("final write1");
goto out;
}
lseek(devfd, 2 * DEV_BSIZE, SEEK_SET);
res = write(devfd, bp + 2 * DEV_BSIZE, size - 2 * DEV_BSIZE);
if (res < 0) {
warn("final write2");
goto out;
}
}
allok = 1;
out:
if (devfd >= 0)
close(devfd);
if (bp)
free(bp);
if (inode != (ino_t) - 1) {
cleanupfileondev(argv[optind + 1], bootblkname, !allok || nowrite);
}
return (!allok);
}

View File

@ -0,0 +1,9 @@
/* $NetBSD: installboot.h,v 1.3 1998/01/05 07:02:57 perry Exp $ */
ino_t createfileondev __P((char *, char *, char *, int));
void cleanupfileondev __P((char *, char *, int));
char *getmountpoint __P((char *));
void cleanupmount __P((char *));
extern int verbose;

View File

@ -0,0 +1,21 @@
# $Id$
#
SUBDIR= crt
LIB= i386
NOPIC=
NOPROFILE=
SRCS= aout_freebsd.c biosdelay.S biosdisk.c biosdisk_support.S biosgetrtc.S \
biosmem.S biosreboot.S bootinfo.c comconsole.c comconsole_support.S \
devicename.c gatea20.c getsecs.c i386_module.c pread.c startprog.S \
vidconsole.c vidconsole_support.S
CFLAGS+= -I${.CURDIR}/../../common
# Make the disk code more talkative
#CFLAGS+= -DDISK_DEBUG
# Minimise the pread() buffer at the price of slower loads
#CPPFLAGS+= -DSAVE_MEMORY
.include <bsd.lib.mk>

View File

@ -0,0 +1,274 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/imgact_aout.h>
#include <sys/reboot.h>
#include <string.h>
#include <machine/bootinfo.h>
#include <stand.h>
#include "bootstrap.h"
#include "libi386.h"
struct aout_kernel_module
{
struct loaded_module m;
vm_offset_t m_entry; /* module entrypoint */
struct bootinfo m_bi; /* legacy bootinfo */
};
static int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
static int aout_exec(struct loaded_module *amp);
struct module_format i386_aout = { MF_AOUT, aout_loadmodule, aout_exec };
static int aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr);
/*
* Attempt to load the file (file) as an a.out module. It will be stored at
* (dest), and a pointer to a module structure describing the loaded object
* will be saved in (result).
*/
static int
aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
{
struct aout_kernel_module *mp;
struct exec ehdr;
int fd;
vm_offset_t addr;
int err;
u_int pad;
/*
* Open the image, read and validate the a.out header
*
* XXX what do kld modules look like? We only handle kernels here.
*/
if (filename == NULL) /* can't handle nameless */
return(EFTYPE);
if ((fd = open(filename, O_RDONLY)) == -1)
return(errno);
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
return(EFTYPE); /* could be EIO, but may be small file */
if (N_BADMAG(ehdr))
return(EFTYPE);
/*
* Ok, we think this is for us.
*/
mp = malloc(sizeof(struct aout_kernel_module));
mp->m.m_name = strdup(filename); /* XXX should we prune the name? */
mp->m.m_type = "a.out kernel"; /* XXX only if that's what we really are */
mp->m.m_args = NULL; /* XXX should we put the bootstrap args here and parse later? */
mp->m.m_flags = MF_AOUT; /* we're an a.out kernel */
mp->m_entry = (vm_offset_t)(ehdr.a_entry & 0xffffff);
if (dest == 0)
dest = (vm_offset_t)(ehdr.a_entry & 0x100000);
if (mod_findmodule(NULL, mp->m.m_type) != NULL) {
printf("aout_loadmodule: kernel already loaded\n");
err = EPERM;
goto out;
}
printf("%s at 0x%x\n", filename, dest);
mp->m.m_addr = addr = dest;
mp->m.m_size = aout_loadimage(fd, addr, &ehdr);
printf("\n");
if (mp->m.m_size == 0)
goto ioerr;
/* XXX and if these parts don't exist? */
mp->m_bi.bi_symtab = mp->m.m_addr + ehdr.a_text + ehdr.a_data + ehdr.a_bss;
mp->m_bi.bi_esymtab = mp->m_bi.bi_symtab + sizeof(ehdr.a_syms) + ehdr.a_syms;
/* Load OK, return module pointer */
*result = (struct loaded_module *)mp;
return(0);
ioerr:
err = EIO;
out:
close(fd);
free(mp);
return(err);
}
/*
* With the file (fd) open on the image, and (ehdr) containing
* the exec header, load the image at (addr)
*
* Fixup the a_bss field in (ehdr) to reflect the padding added to
* align the symbol table.
*/
static int
aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr)
{
u_int pad;
vm_offset_t addr;
int ss;
addr = loadaddr;
lseek(fd, N_TXTOFF(*ehdr), SEEK_SET);
/* text segment */
printf("text=0x%x ", ehdr->a_text);
if (pread(fd, addr, ehdr->a_text) != ehdr->a_text)
return(0);
addr += ehdr->a_text;
/* data segment */
printf("data=0x%x ", ehdr->a_data);
if (pread(fd, addr, ehdr->a_data) != ehdr->a_data)
return(0);
addr += ehdr->a_data;
/* skip the BSS */
printf("bss=0x%x ", ehdr->a_bss);
addr += ehdr->a_bss;
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;
if (pad != 0) {
pad = PAGE_SIZE - pad;
addr += pad;
ehdr->a_bss += pad;
}
/* XXX bi_symtab = addr */
/* symbol table size */
vpbcopy(&ehdr->a_syms, addr, sizeof(ehdr->a_syms));
addr += sizeof(ehdr->a_syms);
/* symbol table */
printf("symbols=[0x%x+0x%x+0x%x", pad, sizeof(ehdr->a_syms), ehdr->a_syms);
if (pread(fd, addr, ehdr->a_syms) != ehdr->a_syms)
return(0);
addr += ehdr->a_syms;
/* string table */
read(fd, &ss, sizeof(ss));
vpbcopy(&ss, addr, sizeof(ss));
addr += sizeof(ss);
ss -= sizeof(ss);
printf("+0x%x+0x%x]", sizeof(ss), ss);
if (pread(fd, addr, ss) != ss)
return(0);
/* XXX bi_esymtab = addr */
addr += ss;
return(addr - loadaddr);
}
/*
* There is an a.out kernel and one or more a.out modules loaded.
* We wish to start executing the kernel image, so make such
* preparations as are required, and do so.
*/
static int
aout_exec(struct loaded_module *amp)
{
struct aout_kernel_module *mp = (struct aout_kernel_module *)amp;
struct loaded_module *xp;
struct i386_devdesc *currdev;
u_int32_t argv[6]; /* kernel arguments */
int major, bootdevnr;
vm_offset_t addr;
u_int pad;
if ((amp->m_flags & MF_FORMATMASK) != MF_AOUT)
return(EFTYPE);
/* Boot from whatever the current device is */
i386_getdev((void **)(&currdev), NULL, NULL);
switch(currdev->d_type) {
case DEVT_DISK:
major = 0; /* XXX in the short term, have to work out a major number here for old kernels */
bootdevnr = MAKEBOOTDEV(major,
currdev->d_kind.biosdisk.slice >> 4,
currdev->d_kind.biosdisk.slice & 0xf,
currdev->d_kind.biosdisk.unit,
currdev->d_kind.biosdisk.partition);
break;
default:
printf("aout_loadmodule: WARNING - don't know how to boot from device type %d\n", currdev->d_type);
}
free(currdev);
/* Device data is kept in the kernel argv array */
argv[1] = bootdevnr;
argv[0] = bi_getboothowto(amp->m_args);
/* argv[2] = vtophys(bootinfo); /* old cyl offset (do we care about this?) */
argv[3] = 0;
argv[4] = 0;
argv[5] = (u_int32_t)vtophys(&(mp->m_bi));
/* legacy bootinfo structure */
mp->m_bi.bi_version = BOOTINFO_VERSION;
mp->m_bi.bi_memsizes_valid = 1;
/* XXX bi_vesa */
mp->m_bi.bi_basemem = getbasemem();
mp->m_bi.bi_extmem = getextmem();
/* find the last module in the chain */
for (xp = amp; xp->m_next != NULL; xp = xp->m_next)
;
addr = xp->m_addr + xp->m_size;
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;
if (pad != 0) {
pad = PAGE_SIZE - pad;
addr += pad;
}
/* copy our environment XXX save addr here as env pointer */
addr = bi_copyenv(addr);
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;
if (pad != 0) {
pad = PAGE_SIZE - pad;
addr += pad;
}
/* copy module list and metadata */
bi_copymodules(addr);
#ifdef DEBUG
{
int i;
for (i = 0; i < 6; i++)
printf("argv[%d]=%lx\n", i, argv[i]);
}
printf("Start @ 0x%lx ...\n", mp->m_entry);
#endif
startprog(mp->m_entry, 6, argv, (vm_offset_t)0x90000);
panic("exec returned");
}

View File

@ -0,0 +1,79 @@
/* $NetBSD: biosdelay.S,v 1.1.1.1 1997/03/14 02:40:32 perry Exp $ */
/*
* Copyright (c) 1996, 1997
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. The names of the authors 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 <machine/asm.h>
#define data32 .byte 0x66
.text
/*
# BIOS call "INT 15H Function 86H" to sleep for a set number of microseconds
# Call with %ah = 0x86
# %cx = time interval (high)
# %dx = time interval (low)
# Return:
# If error
# CF = set
# else
# CF = clear
*/
ENTRY(delay)
pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
movw 20(%esp), %dx
movw 22(%esp), %cx
call CNAME(prot_to_real)
movb $0x86, %ah
int $0x15
setnc %ah
movb %ah, %bl # real_to_prot uses %eax
data32
call CNAME(real_to_prot)
xorl %eax, %eax
movb %bl, %al
popl %edi
popl %esi
popl %ebx
popl %ebp
ret

View File

@ -0,0 +1,408 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* BIOS disk device handling.
*
* Ideas and algorithms from:
*
* - NetBSD libi386/biosdisk.c
* - FreeBSD biosboot/disk.c
*
* XXX Todo: add bad144 support.
*/
#include <stand.h>
#include <sys/disklabel.h>
#include <sys/diskslice.h>
#include "bootstrap.h"
#include "libi386.h"
#include "crt/biosdisk_ll.h"
#define BUFSIZE (1 * BIOSDISK_SECSIZE)
#define MAXBDDEV MAXDEV
#ifdef DISK_DEBUG
# define D(x) x
#else
# define D(x)
#endif
/* biosdisk_support.S */
extern u_long bd_int13fn8(int unit);
static int bd_edd3probe(int unit);
static int bd_edd1probe(int unit);
static int bd_int13probe(int unit);
static int bd_init(void);
static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
static int bd_open(struct open_file *f, void *vdev);
static int bd_close(struct open_file *f);
struct open_disk {
struct biosdisk_ll od_ll; /* contains bios unit, geometry (XXX absorb) */
int od_unit; /* our unit number */
int od_boff; /* block offset from beginning of BIOS disk */
int od_flags;
#define BD_MODEMASK 0x3
#define BD_MODEINT13 0x0
#define BD_MODEEDD1 0x1
#define BD_MODEEDD3 0x2
#define BD_FLOPPY (1<<2)
u_char od_buf[BUFSIZE]; /* transfer buffer (do we want/need this?) */
};
struct devsw biosdisk = {
"disk",
DEVT_DISK,
bd_init,
bd_strategy,
bd_open,
bd_close,
noioctl
};
/*
* List of BIOS devices, translation from disk unit number to
* BIOS unit number.
*/
static struct
{
int bd_unit; /* BIOS unit number */
int bd_flags;
} bdinfo [MAXBDDEV];
static int nbdinfo = 0;
/*
* Quiz the BIOS for disk devices, save a little info about them.
*
* XXX should we be consulting the BIOS equipment list, specifically
* the value at 0x475?
*/
static int
bd_init(void)
{
int base, unit;
/* sequence 0, 0x80 */
for (base = 0; base <= 0x80; base += 0x80) {
for (unit = base; (nbdinfo < MAXBDDEV); unit++) {
bdinfo[nbdinfo].bd_unit = -1;
bdinfo[nbdinfo].bd_flags = (unit < 0x80) ? BD_FLOPPY : 0;
if (bd_edd3probe(unit)) {
bdinfo[nbdinfo].bd_flags |= BD_MODEEDD3;
} else if (bd_edd1probe(unit)) {
bdinfo[nbdinfo].bd_flags |= BD_MODEEDD1;
} else if (bd_int13probe(unit)) {
bdinfo[nbdinfo].bd_flags |= BD_MODEINT13;
} else {
break;
}
/* XXX we need "disk aliases" to make this simpler */
printf("BIOS drive %c: is disk%d\n",
(unit < 0x80) ? ('A' + unit) : ('C' + unit - 0x80), nbdinfo);
bdinfo[nbdinfo].bd_unit = unit;
nbdinfo++;
}
}
return(0);
}
/*
* Try to detect a device supported by an Enhanced Disk Drive 3.0-compliant BIOS
*/
static int
bd_edd3probe(int unit)
{
return(0); /* XXX not implemented yet */
}
/*
* Try to detect a device supported by an Enhanced Disk Drive 1.1-compliant BIOS
*/
static int
bd_edd1probe(int unit)
{
return(0); /* XXX not implemented yet */
}
/*
* Try to detect a device supported by the legacy int13 BIOS
*/
static int
bd_int13probe(int unit)
{
u_long geom;
/* try int 0x13, function 8 */
geom = bd_int13fn8(unit);
return(geom != 0);
}
/*
* Attempt to open the disk described by (dev) for use by (f).
*
* Note that the philosophy here is "give them exactly what
* they ask for". This is necessary because being too "smart"
* about what the user might want leads to complications.
* (eg. given no slice or partition value, with a disk that is
* sliced - are they after the first BSD slice, or the DOS
* slice before it?)
*/
static int
bd_open(struct open_file *f, void *vdev)
{
struct i386_devdesc *dev = (struct i386_devdesc *)vdev;
struct dos_partition *dptr;
struct open_disk *od;
struct disklabel *lp;
int sector, slice, i;
int error;
if (dev->d_kind.biosdisk.unit >= nbdinfo) {
D(printf("bd_open: attempt to open nonexistent disk\n"));
return(ENXIO);
}
od = (struct open_disk *)malloc(sizeof(struct open_disk));
if (!od) {
D(printf("bd_open: no memory\n"));
return (ENOMEM);
}
/* Look up BIOS unit number, intialise open_disk structure */
od->od_unit = dev->d_kind.biosdisk.unit;
od->od_ll.dev = bdinfo[od->od_unit].bd_unit;
od->od_flags = bdinfo[od->od_unit].bd_flags;
od->od_boff = 0;
error = 0;
#if 0
D(printf("bd_open: open '%s' - unit 0x%x slice %d partition %c\n",
i386_fmtdev(dev), dev->d_kind.biosdisk.unit,
dev->d_kind.biosdisk.slice, dev->d_kind.biosdisk.partition + 'a'));
#endif
/* Get geometry for this open (removable device may have changed) */
if (set_geometry(&od->od_ll)) {
D(printf("bd_open: can't get geometry\n"));
error = ENXIO;
goto out;
}
/*
* Following calculations attempt to determine the correct value
* for d->od_boff by looking for the slice and partition specified,
* or searching for reasonable defaults.
*/
/*
* Find the slice in the DOS slice table.
*/
if (readsects(&od->od_ll, 0, 1, od->od_buf, 0)) {
D(printf("bd_open: error reading MBR\n"));
error = EIO;
goto out;
}
/*
* Check the slice table magic.
*/
if ((od->od_buf[0x1fe] != 0xff) || (od->od_buf[0x1ff] != 0xaa)) {
/* If a slice number was explicitly supplied, this is an error */
if (dev->d_kind.biosdisk.slice > 0) {
D(printf("bd_open: no slice table/MBR (no magic)\n"));
error = ENOENT;
goto out;
}
sector = 0;
goto unsliced; /* may be a floppy */
}
dptr = (struct dos_partition *) & od->od_buf[DOSPARTOFF];
/*
* XXX No support here for 'extended' slices
*/
if (dev->d_kind.biosdisk.slice <= 0) {
/*
* Search for the first FreeBSD slice; this also works on "unsliced"
* disks, as they contain a "historically bogus" MBR.
*/
for (i = 0; i < NDOSPART; i++, dptr++)
if (dptr->dp_typ == DOSPTYP_386BSD) {
sector = dptr->dp_start;
break;
}
/* Did we find something? */
if (sector == -1) {
error = ENOENT;
goto out;
}
} else {
/*
* Accept the supplied slice number unequivocally (we may be looking
* for a DOS partition) if we can handle it.
*/
if ((dev->d_kind.biosdisk.slice > NDOSPART) || (dev->d_kind.biosdisk.slice < 1)) {
error = ENOENT;
goto out;
}
dptr += (dev->d_kind.biosdisk.slice - 1);
sector = dptr->dp_start;
}
unsliced:
/*
* Now we have the slice, look for the partition in the disklabel if we have
* a partition to start with.
*
* XXX we might want to check the label checksum.
*/
if (dev->d_kind.biosdisk.partition < 0) {
od->od_boff = sector; /* no partition, must be after the slice */
D(printf("bd_open: opening raw slice\n"));
} else {
if (readsects(&od->od_ll, sector + LABELSECTOR, 1, od->od_buf, 0)) {
D(printf("bd_open: error reading disklabel\n"));
error = EIO;
goto out;
}
lp = (struct disklabel *) (od->od_buf + LABELOFFSET);
if (lp->d_magic != DISKMAGIC) {
D(printf("bd_open: no disklabel\n"));
error = ENOENT;
goto out;
} else if (dev->d_kind.biosdisk.partition >= lp->d_npartitions) {
/*
* The partition supplied is out of bounds; this is fatal.
*/
D(printf("partition '%c' exceeds partitions in table (a-'%c')\n",
'a' + dev->d_kind.biosdisk.partition, 'a' + lp->d_npartitions));
error = EPART;
goto out;
} else {
/*
* Complain if the partition type is wrong and it shouldn't be, but
* regardless accept this partition.
*/
D(if ((lp->d_partitions[dev->d_kind.biosdisk.partition].p_fstype == FS_UNUSED) &&
!(od->od_flags & BD_FLOPPY)) /* Floppies often have bogus fstype */
printf("bd_open: warning, partition marked as unused\n"););
od->od_boff = lp->d_partitions[dev->d_kind.biosdisk.partition].p_offset;
}
}
/*
* Save our context
*/
((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data = od;
#if 0
D(printf("bd_open: open_disk %p\n", od));
#endif
out:
if (error)
free(od);
return(error);
}
static int
bd_close(struct open_file *f)
{
struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data);
#if 0
D(printf("bd_close: open_disk %p\n", od));
#endif
/* XXX is this required? (especially if disk already open...) */
if (od->od_flags & BD_FLOPPY)
delay(3000000);
free(od);
return(0);
}
static int
bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
{
struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data);
int blks;
#ifdef BD_SUPPORT_FRAGS
char fragbuf[BIOSDISK_SECSIZE];
size_t fragsize;
fragsize = size % BIOSDISK_SECSIZE;
#else
if (size % BIOSDISK_SECSIZE)
panic("bd_strategy: %d bytes I/O not multiple of block size", size);
#endif
#if 0
D(printf("bd_strategy: open_disk %p\n", od));
#endif
if (rw != F_READ)
return(EROFS);
blks = size / BIOSDISK_SECSIZE;
#if 0
D(printf("bd_strategy: read %d from %d+%d to %p\n", blks, od->od_boff, dblk, buf));
#endif
if (rsize)
*rsize = 0;
if (blks && readsects(&od->od_ll, dblk + od->od_boff, blks, buf, 0)) {
D(printf("read error\n"));
return (EIO);
}
#ifdef BD_SUPPORT_FRAGS
#if 0
D(printf("bd_strategy: frag read %d from %d+%d+d to %p\n",
#endif
fragsize, od->od_boff, dblk, blks, buf + (blks * BIOSDISK_SECSIZE)));
if (fragsize && readsects(&od->od_ll, dblk + od->od_boff + blks, 1, fragsize, 0)) {
D(printf("frag read error\n"));
return(EIO);
}
bcopy(fragbuf, buf + (blks * BIOSDISK_SECSIZE), fragsize);
#endif
if (rsize)
*rsize = size;
return (0);
}

View File

@ -0,0 +1,114 @@
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
* $Id: bios.S,v 1.12 1997/07/31 08:07:53 phk Exp $
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <machine/asm.h>
#define addr32 .byte 0x67
#define data32 .byte 0x66
/*
*
* get_diskinfo(): return a word that represents the
* max number of sectors and heads and drives for this device
*
*/
ENTRY(bd_int13fn8)
push %ebp
mov %esp, %ebp
push %ebx
push %esi
push %edi
movb 0x8(%ebp), %dl /* diskinfo(drive #) */
call CNAME(prot_to_real) /* enter real mode */
movb $0x8, %ah /* ask for disk info */
sti
int $0x13
cli
jnc ok
/* call failed, return 0 */
subb %cl, %cl
subb %ch, %ch
subb %dl, %dl
subb %dh, %dh
ok:
data32
call CNAME(real_to_prot) /* back to protected mode */
/*
* form a longword representing all this gunk:
* 6 bit zero
* 10 bit max cylinder (0 based)
* 8 bit max head (0 based)
* 2 bit zero
* 6 bit max sector (1 based) = # sectors
*/
movb %cl, %al /* Upper two bits of cylinder count */
andl $0xc0,%eax
leal 0(,%eax,4),%eax /* << 2 */
movb %ch, %al /* Lower 8 bits */
sall $16,%eax /* << 16 */
movb %dh, %ah /* max head */
andb $0x3f, %cl /* mask of cylinder gunk */
movb %cl, %al /* max sector (and # sectors) */
pop %edi
pop %esi
pop %ebx
pop %ebp
ret

View File

@ -0,0 +1,77 @@
/* $NetBSD: biosgetrtc.S,v 1.2 1997/06/13 13:42:27 drochner Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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 <machine/asm.h>
#define addr32 .byte 0x67
#define data32 .byte 0x66
ENTRY(biosgetrtc)
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
xorl %ebx, %ebx
call CNAME(prot_to_real) # enter real mode
movb $2, %ah
int $0x1a
jnc ok
data32
movl $-1, %ebx
ok:
data32
call CNAME(real_to_prot) # back to protected mode
movl 8(%ebp), %eax
movl $0, (%eax)
movb %ch, (%eax)
movb %cl, 1(%eax)
movb %dh, 2(%eax)
movl %ebx, %eax
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret

View File

@ -0,0 +1,99 @@
/* $NetBSD: biosmem.S,v 1.5 1997/08/18 22:44:01 hannken Exp $ */
/*
* Copyright (c) 1996
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. The names of the authors 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 <machine/asm.h>
#define data32 .byte 0x66
.text
/* get mem below 1M, in kByte */
ENTRY(getbasemem)
pushl %ebp
movl %esp,%ebp
pushl %ebx
push %esi
push %edi
call CNAME(prot_to_real)
int $0x12
# zero-extend 16-bit result to 32 bits.
data32
movl $0, %ebx
mov %eax,%ebx # !!! at run time, it is mov %ax,%bx
data32
call CNAME(real_to_prot)
movl %ebx, %eax
pop %edi
pop %esi
popl %ebx
popl %ebp
ret
/* get mem above 1M, in kByte */
ENTRY(getextmem)
pushl %ebp
movl %esp,%ebp
pushl %ebx
push %esi
push %edi
call CNAME(prot_to_real)
movb $0x88,%ah
int $0x15
# zero-extend 16-bit result to 32 bits.
data32
movl $0, %ebx
mov %eax,%ebx # !!! at run time, it is mov %ax,%bx
data32
call CNAME(real_to_prot)
movl %ebx, %eax
pop %edi
pop %esi
popl %ebx
popl %ebp
ret

View File

@ -0,0 +1,66 @@
/* $NetBSD: biosreboot.S,v 1.1 1997/04/13 18:45:37 perry Exp $ */
/*
* Copyright (c) 1997
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. The names of the authors 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 <machine/asm.h>
#define data32 .byte 0x66
.text
/* Call INT 19 to do the equivalent of CTL-ALT-DEL */
ENTRY(reboot)
pushl %ebp
movl %esp,%ebp
pushl %ebx
push %esi
push %edi
call CNAME(prot_to_real)
int $0x19
/* NOTE: We should never even get past this point. */
data32
call CNAME(real_to_prot)
movl %ebx, %eax
pop %edi
pop %esi
popl %ebx
popl %ebp
ret

View File

@ -0,0 +1,197 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <sys/reboot.h>
#include <stand.h>
#include "bootstrap.h"
/*
* Return a 'boothowto' value corresponding to the kernel arguments in
* (kargs) and any relevant environment variables.
*/
static struct
{
char *ev;
int mask;
} howto_names[] = {
{"boot_askname", RB_ASKNAME},
{"boot_userconfig", RB_CONFIG},
{"boot_ddb", RB_KDB},
{"boot_gdb", RB_GDB},
{"boot_single", RB_SINGLE},
{"boot_verbose", RB_VERBOSE},
{NULL, 0}
};
int
bi_getboothowto(char *kargs)
{
char *cp;
int howto;
int active;
int i;
howto = 0;
if (kargs != NULL) {
cp = kargs;
active = 0;
while (*cp != 0) {
if (!active && (*cp == '-')) {
active = 1;
} else if (active)
switch (*cp) {
case 'a':
howto |= RB_ASKNAME;
break;
case 'c':
howto |= RB_CONFIG;
break;
case 'd':
howto |= RB_KDB;
break;
case 'g':
howto |= RB_GDB;
break;
case 'h':
howto |= RB_SERIAL;
break;
case 'r':
howto |= RB_DFLTROOT;
break;
case 's':
howto |= RB_SINGLE;
break;
case 'v':
howto |= RB_VERBOSE;
break;
default:
active = 0;
break;
}
}
cp++;
}
for (i = 0; howto_names[i].ev != NULL; i++)
if (getenv(howto_names[i].ev) != NULL)
howto |= howto_names[i].mask;
if (!strcmp(getenv("console"), "comconsole"))
howto |= RB_SERIAL;
return(howto);
}
/*
* Copy the environment into the load area starting at (addr).
* Each variable is formatted as <name>=<value>, with a single nul
* separating each variable, and a double nul terminating the environment.
*/
vm_offset_t
bi_copyenv(vm_offset_t addr)
{
struct env_var *ep;
/* traverse the environment */
for (ep = environ; ep != NULL; ep = ep->ev_next) {
vpbcopy(ep->ev_name, addr, strlen(ep->ev_name));
addr += strlen(ep->ev_name);
vpbcopy("=", addr, 1);
addr++;
if (ep->ev_value != NULL) {
vpbcopy(ep->ev_value, addr, strlen(ep->ev_value));
addr += strlen(ep->ev_value);
}
vpbcopy("", addr, 1);
addr++;
}
vpbcopy("", addr, 1);
addr++;
}
/*
* Copy module-related data into the load area, where it can be
* used as a directory for loaded modules.
*
* Module data is presented in a self-describing format. Each datum
* is preceeded by a 16-bit identifier and a 16-bit size field.
*
* Currently, the following data are saved:
*
* MOD_NAME (variable) module name (string)
* MOD_TYPE (variable) module type (string)
* MOD_ADDR sizeof(vm_offset_t) module load address
* MOD_SIZE sizeof(size_t) module size
* MOD_METADATA (variable) type-specific metadata
*/
#define MOD_STR(t, a, s) { \
u_int32_t ident = (t << 16) + strlen(s) + 1; \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(s, a, strlen(s) + 1); \
a += strlen(s) + 1; \
}
#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
#define MOD_VAR(t, a, s) { \
u_int32_t ident = (t << 16) + sizeof(s); \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(&s, a, sizeof(s)); \
a += sizeof(s); \
}
#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
#define MOD_METADATA(a, mm) { \
u_int32_t ident = ((MODINFO_METADATA | mm->md_type) << 16) + mm->md_size; \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(mm->md_data, a, mm->md_size); \
a += mm->md_size; \
}
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
MOD_NAME(addr, mp->m_name);
MOD_TYPE(addr, mp->m_type);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
MOD_METADATA(addr, md);
}
return(addr);
}

View File

@ -0,0 +1,197 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <sys/reboot.h>
#include <stand.h>
#include "bootstrap.h"
/*
* Return a 'boothowto' value corresponding to the kernel arguments in
* (kargs) and any relevant environment variables.
*/
static struct
{
char *ev;
int mask;
} howto_names[] = {
{"boot_askname", RB_ASKNAME},
{"boot_userconfig", RB_CONFIG},
{"boot_ddb", RB_KDB},
{"boot_gdb", RB_GDB},
{"boot_single", RB_SINGLE},
{"boot_verbose", RB_VERBOSE},
{NULL, 0}
};
int
bi_getboothowto(char *kargs)
{
char *cp;
int howto;
int active;
int i;
howto = 0;
if (kargs != NULL) {
cp = kargs;
active = 0;
while (*cp != 0) {
if (!active && (*cp == '-')) {
active = 1;
} else if (active)
switch (*cp) {
case 'a':
howto |= RB_ASKNAME;
break;
case 'c':
howto |= RB_CONFIG;
break;
case 'd':
howto |= RB_KDB;
break;
case 'g':
howto |= RB_GDB;
break;
case 'h':
howto |= RB_SERIAL;
break;
case 'r':
howto |= RB_DFLTROOT;
break;
case 's':
howto |= RB_SINGLE;
break;
case 'v':
howto |= RB_VERBOSE;
break;
default:
active = 0;
break;
}
}
cp++;
}
for (i = 0; howto_names[i].ev != NULL; i++)
if (getenv(howto_names[i].ev) != NULL)
howto |= howto_names[i].mask;
if (!strcmp(getenv("console"), "comconsole"))
howto |= RB_SERIAL;
return(howto);
}
/*
* Copy the environment into the load area starting at (addr).
* Each variable is formatted as <name>=<value>, with a single nul
* separating each variable, and a double nul terminating the environment.
*/
vm_offset_t
bi_copyenv(vm_offset_t addr)
{
struct env_var *ep;
/* traverse the environment */
for (ep = environ; ep != NULL; ep = ep->ev_next) {
vpbcopy(ep->ev_name, addr, strlen(ep->ev_name));
addr += strlen(ep->ev_name);
vpbcopy("=", addr, 1);
addr++;
if (ep->ev_value != NULL) {
vpbcopy(ep->ev_value, addr, strlen(ep->ev_value));
addr += strlen(ep->ev_value);
}
vpbcopy("", addr, 1);
addr++;
}
vpbcopy("", addr, 1);
addr++;
}
/*
* Copy module-related data into the load area, where it can be
* used as a directory for loaded modules.
*
* Module data is presented in a self-describing format. Each datum
* is preceeded by a 16-bit identifier and a 16-bit size field.
*
* Currently, the following data are saved:
*
* MOD_NAME (variable) module name (string)
* MOD_TYPE (variable) module type (string)
* MOD_ADDR sizeof(vm_offset_t) module load address
* MOD_SIZE sizeof(size_t) module size
* MOD_METADATA (variable) type-specific metadata
*/
#define MOD_STR(t, a, s) { \
u_int32_t ident = (t << 16) + strlen(s) + 1; \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(s, a, strlen(s) + 1); \
a += strlen(s) + 1; \
}
#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
#define MOD_VAR(t, a, s) { \
u_int32_t ident = (t << 16) + sizeof(s); \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(&s, a, sizeof(s)); \
a += sizeof(s); \
}
#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
#define MOD_METADATA(a, mm) { \
u_int32_t ident = ((MODINFO_METADATA | mm->md_type) << 16) + mm->md_size; \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(mm->md_data, a, mm->md_size); \
a += mm->md_size; \
}
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
MOD_NAME(addr, mp->m_name);
MOD_TYPE(addr, mp->m_type);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
MOD_METADATA(addr, md);
}
return(addr);
}

View File

@ -0,0 +1,197 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <sys/reboot.h>
#include <stand.h>
#include "bootstrap.h"
/*
* Return a 'boothowto' value corresponding to the kernel arguments in
* (kargs) and any relevant environment variables.
*/
static struct
{
char *ev;
int mask;
} howto_names[] = {
{"boot_askname", RB_ASKNAME},
{"boot_userconfig", RB_CONFIG},
{"boot_ddb", RB_KDB},
{"boot_gdb", RB_GDB},
{"boot_single", RB_SINGLE},
{"boot_verbose", RB_VERBOSE},
{NULL, 0}
};
int
bi_getboothowto(char *kargs)
{
char *cp;
int howto;
int active;
int i;
howto = 0;
if (kargs != NULL) {
cp = kargs;
active = 0;
while (*cp != 0) {
if (!active && (*cp == '-')) {
active = 1;
} else if (active)
switch (*cp) {
case 'a':
howto |= RB_ASKNAME;
break;
case 'c':
howto |= RB_CONFIG;
break;
case 'd':
howto |= RB_KDB;
break;
case 'g':
howto |= RB_GDB;
break;
case 'h':
howto |= RB_SERIAL;
break;
case 'r':
howto |= RB_DFLTROOT;
break;
case 's':
howto |= RB_SINGLE;
break;
case 'v':
howto |= RB_VERBOSE;
break;
default:
active = 0;
break;
}
}
cp++;
}
for (i = 0; howto_names[i].ev != NULL; i++)
if (getenv(howto_names[i].ev) != NULL)
howto |= howto_names[i].mask;
if (!strcmp(getenv("console"), "comconsole"))
howto |= RB_SERIAL;
return(howto);
}
/*
* Copy the environment into the load area starting at (addr).
* Each variable is formatted as <name>=<value>, with a single nul
* separating each variable, and a double nul terminating the environment.
*/
vm_offset_t
bi_copyenv(vm_offset_t addr)
{
struct env_var *ep;
/* traverse the environment */
for (ep = environ; ep != NULL; ep = ep->ev_next) {
vpbcopy(ep->ev_name, addr, strlen(ep->ev_name));
addr += strlen(ep->ev_name);
vpbcopy("=", addr, 1);
addr++;
if (ep->ev_value != NULL) {
vpbcopy(ep->ev_value, addr, strlen(ep->ev_value));
addr += strlen(ep->ev_value);
}
vpbcopy("", addr, 1);
addr++;
}
vpbcopy("", addr, 1);
addr++;
}
/*
* Copy module-related data into the load area, where it can be
* used as a directory for loaded modules.
*
* Module data is presented in a self-describing format. Each datum
* is preceeded by a 16-bit identifier and a 16-bit size field.
*
* Currently, the following data are saved:
*
* MOD_NAME (variable) module name (string)
* MOD_TYPE (variable) module type (string)
* MOD_ADDR sizeof(vm_offset_t) module load address
* MOD_SIZE sizeof(size_t) module size
* MOD_METADATA (variable) type-specific metadata
*/
#define MOD_STR(t, a, s) { \
u_int32_t ident = (t << 16) + strlen(s) + 1; \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(s, a, strlen(s) + 1); \
a += strlen(s) + 1; \
}
#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
#define MOD_VAR(t, a, s) { \
u_int32_t ident = (t << 16) + sizeof(s); \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(&s, a, sizeof(s)); \
a += sizeof(s); \
}
#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
#define MOD_METADATA(a, mm) { \
u_int32_t ident = ((MODINFO_METADATA | mm->md_type) << 16) + mm->md_size; \
vpbcopy(&ident, a, sizeof(ident)); \
a += sizeof(ident); \
vpbcopy(mm->md_data, a, mm->md_size); \
a += mm->md_size; \
}
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
MOD_NAME(addr, mp->m_name);
MOD_TYPE(addr, mp->m_type);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
MOD_METADATA(addr, md);
}
return(addr);
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
*
* $Id$
*/
#include <stand.h>
#include "bootstrap.h"
/* in comconsole.S */
extern void cominit(int s);
extern void computc(int c);
extern int comgetc(void);
extern int comiskey(void);
static void comc_probe(struct console *cp);
static int comc_init(int arg);
static int comc_in(void);
struct console comconsole = {
"comconsole",
"BIOS serial port",
0,
comc_probe,
comc_init,
computc,
comc_in,
comiskey
};
static void
comc_probe(struct console *cp)
{
/* XXX check the BIOS equipment list? */
cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
}
static int
comc_init(int arg)
{
/* XXX arg is unit number, should we use variables instead? */
cominit(arg);
return(0);
}
static int
comc_in(void)
{
if (comiskey()) {
return(comgetc());
} else {
return(-1);
}
}

View File

@ -0,0 +1,147 @@
/* $NetBSD: comio.S,v 1.2 1997/10/27 19:51:18 drochner Exp $ */
/* serial console handling
modelled after code in FreeBSD:sys/i386/boot/netboot/start2.S
*/
#include <machine/asm.h>
#define addr32 .byte 0x67
#define data32 .byte 0x66
.text
/**************************************************************************
INIT - Initialization (com number)
**************************************************************************/
ENTRY(cominit)
push %ebp
mov %esp,%ebp
push %ebx
push %edx
push %esi
push %edi
movl 8(%ebp), %edx
call CNAME(prot_to_real) # enter real mode
# Initialize the serial port (dl) to 9600 baud, 8N1.
movb $0xe3, %al
movb $0, %ah
int $0x14
mov %ax,%bx
data32
call CNAME(real_to_prot) # back to protected mode
xor %eax,%eax
mov %bx,%ax
pop %edi
pop %esi
pop %edx
pop %ebx
pop %ebp
ret
/**************************************************************************
PUTC - Print a character (char, com number)
**************************************************************************/
ENTRY(computc)
push %ebp
mov %esp,%ebp
push %ecx
push %ebx
push %edx
push %esi
push %edi
movb 8(%ebp),%cl
movl 12(%ebp),%edx
call CNAME(prot_to_real) # enter real mode
movb %cl,%al
movb $0x01, %ah
int $0x14
movb %ah,%bl
data32
call CNAME(real_to_prot) # back to protected mode
xor %eax,%eax
movb %bl,%al
pop %edi
pop %esi
pop %edx
pop %ebx
pop %ecx
pop %ebp
ret
/**************************************************************************
GETC - Get a character (com number)
**************************************************************************/
ENTRY(comgetc)
push %ebp
mov %esp,%ebp
push %ebx
push %edx
push %esi
push %edi
movl 8(%ebp),%edx
call CNAME(prot_to_real) # enter real mode
movb $0x02, %ah
int $0x14
movl %eax,%ebx # at run time, it is mov %ax,%bx
data32
call CNAME(real_to_prot) # back to protected mode
xor %eax,%eax
mov %bx,%ax
pop %edi
pop %esi
pop %edx
pop %ebx
pop %ebp
ret
/**************************************************************************
ISKEY - Check for keyboard interrupt (com number)
**************************************************************************/
ENTRY(comiskey)
push %ebp
mov %esp,%ebp
push %ebx
push %edx
push %esi
push %edi
movl 8(%ebp),%edx
call CNAME(prot_to_real) # enter real mode
movb $0x03, %ah
int $0x14
mov %ax,%bx
data32
call CNAME(real_to_prot) # back to protected mode
xor %eax,%eax
mov %bx,%ax
pop %edi
pop %esi
pop %edx
pop %ebx
pop %ebp
ret

View File

@ -0,0 +1,3 @@
SUBDIR= bootsect
.include <bsd.subdir.mk>

View File

@ -0,0 +1,176 @@
/*
* $Id$
* From: $NetBSD: bios_disk.S,v 1.1.1.1 1997/03/14 02:40:32 perry Exp $
*/
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* extracted from netbsd:sys/arch/i386/boot/bios.S */
#include <machine/asm.h>
#define addr32 .byte 0x67
#define data32 .byte 0x66
/*
# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
# Call with %ah = 0x2
# %al = number of sectors
# %ch = cylinder
# %cl = sector
# %dh = head
# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
# %es:%bx = segment:offset of buffer
# Return:
# %al = 0x0 on success; err code on failure
*/
ENTRY(biosread)
pushl %ebp
movl %esp, %ebp
pushl %ebx
push %ecx
push %edx
push %esi
push %edi
movb 16(%ebp), %dh
movw 12(%ebp), %cx
xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
rorb $2, %cl
movb 20(%ebp), %al
orb %al, %cl
incb %cl # sector; sec starts from 1, not 0
movb 8(%ebp), %dl # device
movl 28(%ebp), %ebx # offset
# prot_to_real will set %es to BOOTSEG
call CNAME(prot_to_real) # enter real mode
movb $0x2, %ah # subfunction
addr32
movb 24(%ebp), %al # number of sectors
int $0x13
setc %bl
data32
call CNAME(real_to_prot) # back to protected mode
xorl %eax, %eax
movb %bl, %al # return value in %ax
pop %edi
pop %esi
pop %edx
pop %ecx
popl %ebx
popl %ebp
ret
/*
#
# get_diskinfo(): return a word that represents the
# max number of sectors and heads and drives for this device
#
*/
ENTRY(get_diskinfo)
pushl %ebp
movl %esp, %ebp
push %es
pushl %ebx
push %ecx
push %edx
push %esi
push %edi
movb 8(%ebp), %dl # diskinfo(drive #)
call CNAME(prot_to_real) # enter real mode
movb $0x08, %ah # ask for disk info
int $0x13
jnc ok
/*
* Urk. Call failed. It is not supported for floppies by old BIOS's.
* Guess it's a 15-sector floppy. Initialize all the registers for
* documentation, although we only need head and sector counts.
*/
# subb %ah, %ah # %ax = 0
# movb %ah, %bh # %bh = 0
# movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M
# movb $79, %ch # max track
movb $15, %cl # max sector
movb $1, %dh # max head
# movb $1, %dl # # floppy drives installed
# es:di = parameter table
# carry = 0
ok:
data32
call CNAME(real_to_prot) # back to protected mode
xorl %eax, %eax
/*form a longword representing all this gunk*/
movb %dh, %ah # max head
andb $0x3f, %cl # mask of cylinder gunk
movb %cl, %al # max sector (and # sectors)
pop %edi
pop %esi
pop %edx
pop %ecx
popl %ebx
pop %es
popl %ebp
ret

View File

@ -0,0 +1,148 @@
/*
* $Id$
* From: $NetBSD: biosdisk_ll.c,v 1.3 1997/06/13 13:36:06 drochner Exp $
*/
/*
* Copyright (c) 1996
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Matthias Drochner.
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. The names of the authors 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.
*/
/*
* shared by bootsector startup (bootsectmain) and biosdisk.c
* needs lowlevel parts from bios_disk.S
*/
#include <stand.h>
#include "biosdisk_ll.h"
#include "diskbuf.h"
/* XXX prototypes from export header? */
extern int get_diskinfo(int);
extern int biosread(int, int, int, int, int, char *);
#define SPT(di) ((di)&0xff)
#define HEADS(di) ((((di)>>8)&0xff)+1)
int
set_geometry(d)
struct biosdisk_ll *d;
{
int diskinfo;
diskinfo = get_diskinfo(d->dev);
d->spc = (d->spt = SPT(diskinfo)) * HEADS(diskinfo);
/*
* get_diskinfo assumes floppy if BIOS call fails. Check at least
* "valid" geometry.
*/
return (!d->spc || !d->spt);
}
/*
* Global shared "diskbuf" is used as read ahead buffer. For reading from
* floppies, the bootstrap has to be loaded on a 64K boundary to ensure that
* this buffer doesn't cross a 64K DMA boundary.
*/
static int ra_dev;
static int ra_end;
static int ra_first;
int
readsects(d, dblk, num, buf, cold) /* reads ahead if (!cold) */
struct biosdisk_ll *d;
int dblk, num;
char *buf;
int cold; /* don't use data segment or bss, don't call
* library functions */
{
while (num) {
int nsec;
/* check for usable data in read-ahead buffer */
if (cold || diskbuf_user != &ra_dev || d->dev != ra_dev
|| dblk < ra_first || dblk >= ra_end) {
/* no, read from disk */
int cyl, head, sec;
char *trbuf;
cyl = dblk / d->spc;
head = (dblk % d->spc) / d->spt;
sec = dblk % d->spt;
nsec = d->spt - sec;
if (cold) {
/* transfer directly to buffer */
trbuf = buf;
if (nsec > num)
nsec = num;
} else {
/* fill read-ahead buffer */
trbuf = diskbuf;
if (nsec > diskbuf_size)
nsec = diskbuf_size;
ra_dev = d->dev;
ra_first = dblk;
ra_end = dblk + nsec;
diskbuf_user = &ra_dev;
}
if (biosread(d->dev, cyl, head, sec, nsec, trbuf)) {
if (!cold)
diskbuf_user = 0; /* mark invalid */
return (-1); /* XXX cannot output here if
* (cold) */
}
} else /* can take blocks from end of read-ahead
* buffer */
nsec = ra_end - dblk;
if (!cold) {
/* copy data from read-ahead to user buffer */
if (nsec > num)
nsec = num;
bcopy(diskbuf + (dblk - ra_first) * BIOSDISK_SECSIZE,
buf, nsec * BIOSDISK_SECSIZE);
}
buf += nsec * BIOSDISK_SECSIZE;
num -= nsec;
dblk += nsec;
}
return (0);
}

View File

@ -0,0 +1,54 @@
/*
* $Id$
* From: $NetBSD: biosdisk_ll.h,v 1.2 1997/03/22 01:41:36 thorpej Exp $
*/
/*
* Copyright (c) 1996
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Matthias Drochner.
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. The names of the authors 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.
*/
/*
* shared by bootsector startup (bootsectmain) and biosdisk.c needs lowlevel
* parts from bios_disk.S
*/
struct biosdisk_ll {
int dev; /* BIOS device number */
int spt, spc; /* geometry */
};
#define BIOSDISK_SECSIZE 512
extern int set_geometry(struct biosdisk_ll *);
extern int readsects(struct biosdisk_ll *, int, int, char *, int);

View File

@ -0,0 +1,25 @@
#
# Build a startup module
#
# Disk buffer size in sectors
CFLAGS+= -DDISKBUFSIZE=18
# Stack size in bytes
CFLAGS+= -DSTACKSIZE=0x1000
PROG= bscrt.o
LDFLAGS= -static -nostartfiles -nostdlib -Xlinker -r
NOMAN= yes
# Bootblock-specific sources
SRCS= start_bootsect.S fraglist.S bootsectmain.c
# Includes for libsa support routines XXX fix path!
CFLAGS+= -I${.CURDIR}/../../../../../whole/lib/libstand
# Common items across all startups
.PATH: ${.CURDIR}/..
CFLAGS+= -I${.CURDIR}/..
SRCS+= biosdisk_ll.c bios_disk.S buffers.S
.include <bsd.prog.mk>

View File

@ -0,0 +1,64 @@
/*
* $Id$
* From: $NetBSD: bbinfo.h,v 1.3 1997/11/07 16:59:41 drochner Exp $
*/
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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.
*
*/
/* data structure shared by bootsector
and installboot
*/
#ifndef __ASSEMBLER__
struct fraglist {
int magic;
int loadsz; /* blocks loaded by primary boot */
int numentries, maxentries;
struct {
int offset, num;
} entries[1];
};
#endif
#define FRAGLISTVERSION 0
#define FRAGLISTMAGIC (0xb00deda5 + FRAGLISTVERSION)
/* only used by bootsect code (not by installboot) */
#ifndef MAXFLENTRIES
#define MAXFLENTRIES 10
#endif
#ifndef PRIM_LOADSZ
#define PRIM_LOADSZ 15
#endif

View File

@ -0,0 +1,88 @@
/*
* $Id$
* From: $NetBSD: bootsectmain.c,v 1.1.1.1 1997/03/14 02:40:34 perry Exp $
*/
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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.
*
*/
/* load remainder of boot program
(blocks from fraglist),
start main()
needs lowlevel parts from biosdisk_ll.c
*/
#include "biosdisk_ll.h"
#include "bbinfo.h"
int boot_biosdev; /* exported */
extern struct fraglist fraglist;
extern char edata[], end[];
extern void main(void);
void bootsectmain(biosdev)
int biosdev;
{
struct biosdisk_ll d;
int i;
char *buf;
/*
* load sectors from bootdev
*/
d.dev = biosdev;
set_geometry(&d);
buf = (char*)(PRIM_LOADSZ * BIOSDISK_SECSIZE);
for(i = 0; i < fraglist.numentries; i++) {
int dblk, num;
dblk = fraglist.entries[i].offset;
num = fraglist.entries[i].num;
if(readsects(&d, dblk, num, buf, 1))
return; /* halts in start_bootsect.S */
buf += num * BIOSDISK_SECSIZE;
}
/* clear BSS */
buf = edata;
while(buf < end) *buf++ = 0;
/* call main() */
boot_biosdev = biosdev;
/* main(); */
}

View File

@ -0,0 +1,49 @@
/* $NetBSD: fraglist.S,v 1.1.1.1 1997/03/14 02:40:34 perry Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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.
*
*/
/* space for fragment list
goes to text section - must be loaded by primary boot
*/
#include "bbinfo.h"
.text
.globl _fraglist
_fraglist:
.long FRAGLISTMAGIC
.long PRIM_LOADSZ /* blocks already in memory */
.long 0
.long MAXFLENTRIES
. = . + 2 * MAXFLENTRIES * 4

View File

@ -0,0 +1,540 @@
/* $NetBSD: start_bootsect.S,v 1.3 1998/02/19 14:15:38 drochner Exp $ */
/* BIOS bootsector startup
parts from netbsd:sys/arch/i386/boot/start.S
and freebsd:sys/i386/boot/biosboot/boot2.S
*/
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <machine/asm.h>
#define addr32 .byte 0x67
#define data32 .byte 0x66
/* #include <machine/disklabel.h> */
#include "bbinfo.h"
BOOTSEG = 0x0100 # boot will be loaded here (below 640K)
BOOTSTACK = 0xfffc # boot stack
LOADSZ = PRIM_LOADSZ # size of first loaded chunk
SIGNATURE = 0xaa55
PARTSTART = 0x1be # starting address of partition table
NUMPART = 4 # number of partitions in partition table
PARTSZ = 16 # sizeof(struct dos_partition)
BSDPART = 0xA5
BOOTABLE = 0x80 # value of dp_flag, means bootable partition
.text
_boot1:
ENTRY(start)
# start (aka boot1) is loaded at 0x0:0x7c00 but we want 0x7c0:0
# ljmp to the next instruction to adjust %cs
data32
ljmp $0x7c0, $start1
start1:
# set up %ds
movl %cs, %ax
movl %ax, %ds
# temporary stack while we locate boot2
# set up %ss and %esp
data32
movl $BOOTSEG, %eax
movl %ax, %ss
data32
movl $BOOTSTACK, %esp
/*** set up %es, (where we will load boot2 to) ***/
movl %ax, %es
# bootstrap passes us drive number in %dl
cmpb $0x80, %dl
data32
jae hd
fd:
# reset the disk system
movb $0x00, %ah
int $0x13
data32
movl $0x0001, %ecx # cyl 0, sector 1
movb $0x00, %dh # head
# XXX Override the drive number.
movb $0x00, %dl
data32
jmp load
hd: /**** load sector 0 (DOSBBSECTOR) into the BOOTSEG ****/
data32
movl $0x0201, %eax
xorl %ebx, %ebx # %bx = 0
data32
movl $0x0001, %ecx
data32
andl $0xff, %edx
/*mov $0x0080, %edx*/
int $0x13
data32
jb read_error
/***# find the first BSD partition *****/
data32
movl $PARTSTART, %ebx
data32
movl $NUMPART, %ecx
again:
addr32
movb %es:4(%ebx), %al /* dp_typ */
cmpb $BSDPART, %al
data32
je found
data32
addl $PARTSZ, %ebx
data32
loop again
/* didn't find either NetBSD or 386BSD partitions */
data32
movl $enoboot, %esi
data32
jmp err_stop
/*
# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
# Call with %ah = 0x2
# %al = number of sectors
# %ch = cylinder
# %cl = sector
# %dh = head
# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
# %es:%bx = segment:offset of buffer
# Return:
# %al = 0x0 on success; err code on failure
*/
found:
addr32
movb %es:1(%ebx), %dh /* head: dp_sdh */
addr32
movl %es:2(%ebx), %ecx /*sect, cyl: dp_ssect + (dp_scyl << 8)*/
load:
movb $0x2, %ah /* function 2 */
movb $LOADSZ, %al /* number of blocks */
xorl %ebx, %ebx /* %bx = 0, put it at 0 in the BOOTSEG */
int $0x13
data32
jb read_error
# ljmp to the second stage boot loader (boot2).
# After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
# for stack space while we load boot3.
data32
ljmp $BOOTSEG, $CNAME(boot2)
#
# read_error
#
read_error:
data32
movl $eread, %esi
err_stop:
data32
call message
data32
jmp stop
#
# message: write the error message in %ds:%esi to console
#
message:
/*
# BIOS call "INT 10H Function 0Eh" to write character to console
# Call with %ah = 0x0e
# %al = character
# %bh = page
# %bl = foreground color
*/
data32
pushl %eax
data32
pushl %ebx
data32
pushl %edx
nextb:
cld
lodsb # load a byte into %al
testb %al, %al
data32
jz done
movb $0x0e, %ah
data32
movl $0x0001, %ebx
int $0x10
data32
jmp nextb
done:
data32
popl %edx
data32
popl %ebx
data32
popl %eax
data32
ret
_ourseg:
.long 0
/**************************************************************************
GLOBAL DESCRIPTOR TABLE
**************************************************************************/
.align 4
gdt: /* 0x0 */
.word 0, 0
.byte 0, 0x00, 0x00, 0
/* additional dummy for Linux support (?) */ /* 0x8 */
.word 0, 0
.byte 0, 0x00, 0x00, 0
/* kernel code segment */
.globl flatcodeseg
flatcodeseg = . - gdt /* 0x10 */
.word 0xffff, 0
.byte 0, 0x9f, 0xcf, 0
/* kernel data segment */
.globl flatdataseg
flatdataseg = . - gdt /* 0x18 */
.word 0xffff, 0
.byte 0, 0x93, 0xcf, 0
/* boot code segment, will be patched */
bootcodeseg = . - gdt /* 0x20 */
.word 0xffff, 0
.byte 0, 0x9e, 0x40, 0
/* boot data segment, will be patched */
bootdataseg = . - gdt /* 0x28 */
.word 0xffff, 0
.byte 0, 0x92, 0x0f, 0
/* 16 bit real mode, will be patched */
bootrealseg = . - gdt /* 0x30 */
.word 0xffff, 0
.byte 0, 0x9e, 0x00, 0
gdtlen = . - gdt
.align 4
gdtarg:
.word gdtlen-1 /* limit */
.long 0 /* addr, will be inserted */
_boot2:
data32
xorl %eax, %eax
movl %cs, %ax
movl %ax, %ds
movl %ax, %es
addr32
data32
movl %eax, CNAME(ourseg)
data32
shll $4, %eax
/* fix up GDT entries for bootstrap */
#define FIXUP(gdt_index) \
addr32; \
movl %eax, gdt+gdt_index+2; /* actually movw %ax */ \
addr32; \
movb %bl, gdt+gdt_index+4
data32
shldl $16, %eax, %ebx
FIXUP(bootcodeseg)
FIXUP(bootrealseg)
FIXUP(bootdataseg)
/* fix up GDT pointer */
data32
addl $gdt, %eax
addr32
data32
movl %eax, gdtarg+2
/* change to protected mode */
data32
call CNAME(real_to_prot)
/* move the stack over the top of boot1 while we load */
movl $_ourseg - 4, %eax
movl %eax, %esp
movzbl %dl, %edx /* discard head (%dh) and random high bits */
pushl %edx
call CNAME(bootsectmain)
/* Go to internal stack */
movl $CNAME(stacktop), %eax
movl %eax, %esp
call CNAME(main)
ENTRY(exit)
stop:
cli
hlt
eread: .asciz "Read error\r\n"
enoboot: .asciz "No bootable partition\r\n"
endofcode:
/* throw in a partition in case we are block0 as well */
/* flag, head, sec, cyl, typ, ehead, esect, ecyl, start, len */
. = CNAME(boot1) + PARTSTART
.byte 0x0,0,0,0,0,0,0,0
.long 0,0
.byte 0x0,0,0,0,0,0,0,0
.long 0,0
.byte 0x0,0,0,0,0,0,0,0
.long 0,0
.byte BOOTABLE,0,1,0,BSDPART,255,255,255
.long 0,50000
/* the last 2 bytes in the sector 0 contain the signature */
. = CNAME(boot1) + 0x1fe
.short SIGNATURE
. = CNAME(boot1) + 0x200
.globl _disklabel
_disklabel:
. = CNAME(boot1) + 0x400
CR0_PE = 0x1
/*
* real_to_prot()
* transfer from real mode to protected mode.
*/
ENTRY(real_to_prot)
# guarantee that interrupt is disabled when in prot mode
cli
# load the gdtr
addr32
data32
lgdt gdtarg
# set the PE bit of CR0
movl %cr0, %eax
data32
orl $CR0_PE, %eax
movl %eax, %cr0
# make intrasegment jump to flush the processor pipeline and
# reload CS register
data32
ljmp $bootcodeseg, $xprot
xprot:
# we are in USE32 mode now
# set up the protected mode segment registers : DS, SS, ES
movl $bootdataseg, %eax
movl %ax, %ds
movl %ax, %ss
movl %ax, %es
ret
/*
* prot_to_real()
* transfer from protected mode to real mode
*/
ENTRY(prot_to_real)
# set up a dummy stack frame for the second seg change.
# Adjust the intersegment jump instruction following
# the clearing of protected mode bit.
# This is self-modifying code, but we need a writable
# code segment, and an intersegment return does not give us that.
movl _ourseg, %eax
movw %ax, xreal-2
# Change to use16 mode.
ljmp $bootrealseg, $x16
x16:
# clear the PE bit of CR0
movl %cr0, %eax
data32
andl $~CR0_PE, %eax
movl %eax, %cr0
# Here we have an 16 bits intersegment jump.
.byte 0xea
.word xreal
.word 0
xreal:
# we are in real mode now
# set up the real mode segment registers : DS, SS, ES
movl %cs, %ax
movl %ax, %ds
movl %ax, %ss
movl %ax, %es
sti
data32
ret
/*
* pbzero(dst, cnt)
* where dst is a physical address and cnt is the length
*/
ENTRY(pbzero)
pushl %ebp
movl %esp, %ebp
pushl %es
pushl %edi
cld
# set %es to point at the flat segment
movl $flatdataseg, %eax
movl %ax, %es
movl 8(%ebp), %edi # destination
movl 12(%ebp), %ecx # count
xorl %eax, %eax # value
rep
stosb
popl %edi
popl %es
popl %ebp
ret
/*
* vpbcopy(src, dst, cnt)
* where src is a virtual address and dst is a physical address
*/
ENTRY(vpbcopy)
pushl %ebp
movl %esp, %ebp
pushl %es
pushl %esi
pushl %edi
cld
# set %es to point at the flat segment
movl $flatdataseg, %eax
movl %ax, %es
movl 8(%ebp), %esi # source
movl 12(%ebp), %edi # destination
movl 16(%ebp), %ecx # count
rep
movsb
popl %edi
popl %esi
popl %es
popl %ebp
ret
/*
* pvbcopy(src, dst, cnt)
* where src is a physical address and dst is a virtual address
*/
ENTRY(pvbcopy)
pushl %ebp
movl %esp, %ebp
pushl %ds
pushl %esi
pushl %edi
cld
# set %ds to point at the flat segment
movl $flatdataseg, %eax
movl %ax, %ds
movl 8(%ebp), %esi # source
movl 12(%ebp), %edi # destination
movl 16(%ebp), %ecx # count
rep
movsb
popl %edi
popl %esi
popl %ds
popl %ebp
ret
ENTRY(vtophys)
movl _ourseg, %eax
shll $4, %eax
addl 4(%esp), %eax
ret

View File

@ -0,0 +1,27 @@
/*
* Provide buffer space for various items.
*
* We do this in the text segment so that we can control the location
* of the buffers at the link stage, and thus ensure that they are
* within reach of the real-mode support routines.
*
* It is especially important to have the stack down low so that
* it is reachable from both 32-bit and 16-bit code.
*/
#include <machine/asm.h>
.text
.align 4
ENTRY(diskbuf)
. = CNAME(diskbuf) + (DISKBUFSIZE * 512)
ENTRY(diskbuf_user)
.long 0
ENTRY(diskbuf_size)
.long DISKBUFSIZE
.align 4
ENTRY(stackbase)
. = CNAME(stackbase) + STACKSIZE
ENTRY(stacktop)
.long 0

View File

@ -0,0 +1,42 @@
/*
* $Id$
* From: $NetBSD: diskbuf.h,v 1.1.1.1 1997/03/14 02:40:32 perry Exp $
*/
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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.
*
*/
/* data buffer for BIOS disk / DOS I/O */
extern char diskbuf[]; /* client-supplied disk buffer */
extern void *diskbuf_user; /* using function sets it to unique value to allow check if overwritten*/
extern int diskbuf_size; /* size of client-supplied buffer in sectors */

View File

@ -0,0 +1,234 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <string.h>
#include <sys/disklabel.h>
#include "bootstrap.h"
#include "libi386.h"
static int i386_parsedev(struct i386_devdesc **dev, char *devspec, char **path);
/*
* Point (dev) at an allocated device specifier for the device matching the
* path in (devspec). If it contains an explicit device specification,
* use that. If not, use the default device.
*/
int
i386_getdev(void **vdev, char *devspec, char **path)
{
struct i386_devdesc **dev = (struct i386_devdesc **)vdev;
int rv;
/*
* If it looks like this is just a path and no
* device, go with the current device.
*/
if ((devspec == NULL) ||
(devspec[0] == '/') ||
(strchr(devspec, ':') == NULL)) {
if (((rv = i386_parsedev(dev, getenv("currdev"), NULL)) == 0) &&
(path != NULL))
*path = devspec;
return(rv);
}
/*
* Try to parse the device name off the beginning of the devspec
*/
return(i386_parsedev(dev, devspec, path));
}
/*
* Point (dev) at an allocated device specifier matching the string version
* at the beginning of (devspec). Return a pointer to the remaining
* text in (path).
*
* In all cases, the beginning of (devspec) is compared to the names
* of known devices in the device switch, and then any following text
* is parsed according to the rules applied to the device type.
*
* For disk-type devices, the syntax is:
*
* disk<unit>[s<slice>][<partition>]:
*
*/
static int
i386_parsedev(struct i386_devdesc **dev, char *devspec, char **path)
{
struct i386_devdesc *idev;
struct devsw *dv;
int i, unit, slice, partition, err;
char *cp, *np;
/* minimum length check */
if (strlen(devspec) < 2)
return(EINVAL);
/* look for a device that matches */
for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) {
dv = devsw[i];
break;
}
}
if (dv == NULL)
return(ENOENT);
idev = malloc(sizeof(struct i386_devdesc));
err = 0;
np = (devspec + strlen(dv->dv_name));
switch(dv->dv_type) {
case DEVT_NONE: /* XXX what to do here? Do we care? */
break;
case DEVT_DISK:
unit = -1;
slice = -1;
partition = -1;
if (*np && (*np != ':')) {
unit = strtol(np, &cp, 10); /* next comes the unit number */
if (cp == np) {
err = EUNIT;
goto fail;
}
if (*cp == 's') { /* got a slice number */
np = cp + 1;
slice = strtol(np, &cp, 10);
if (cp == np) {
err = ESLICE;
goto fail;
}
}
if (*cp && (*cp != ':')) {
partition = *cp - 'a'; /* get a partition number */
if ((partition < 0) || (partition >= MAXPARTITIONS)) {
err = EPART;
goto fail;
}
cp++;
}
}
if (*cp && (*cp != ':')) {
err = EINVAL;
goto fail;
}
idev->d_kind.biosdisk.unit = unit;
idev->d_kind.biosdisk.slice = slice;
idev->d_kind.biosdisk.partition = partition;
if (path != NULL)
*path = (*cp == 0) ? cp : cp + 1;
break;
case DEVT_NET:
unit = 0;
if (*np && (*np != ':')) {
unit = strtol(np, &cp, 0); /* get unit number if present */
if (cp == np) {
err = EUNIT;
goto fail;
}
}
if (*cp && (*cp != ':')) {
err = EINVAL;
goto fail;
}
idev->d_kind.netif.unit = unit;
if (path != NULL)
*path = (*cp == 0) ? cp : cp + 1;
break;
default:
err = EINVAL;
goto fail;
}
idev->d_dev = dv;
idev->d_type = dv->dv_type;
if (dev == NULL) {
free(idev);
} else {
*dev = idev;
}
return(0);
fail:
free(idev);
return(err);
}
char *
i386_fmtdev(void *vdev)
{
struct i386_devdesc *dev = (struct i386_devdesc *)vdev;
static char buf[128]; /* XXX device length constant? */
char *cp;
switch(dev->d_type) {
case DEVT_NONE:
strcpy(buf, "(no device)");
break;
case DEVT_DISK:
cp = buf;
cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_kind.biosdisk.unit);
if (dev->d_kind.biosdisk.slice > 0)
cp += sprintf(cp, "s%d", dev->d_kind.biosdisk.slice);
if (dev->d_kind.biosdisk.partition >= 0)
cp += sprintf(cp, "%c", dev->d_kind.biosdisk.partition + 'a');
strcat(cp, ":");
break;
case DEVT_NET:
sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_kind.netif.unit);
break;
}
return(buf);
}
/*
* Set currdev to suit the value being supplied in (value)
*/
int
i386_setcurrdev(struct env_var *ev, int flags, void *value)
{
struct i386_devdesc *ncurr;
int rv;
if ((rv = i386_parsedev(&ncurr, value, NULL)) != 0)
return(rv);
free(ncurr);
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
return(0);
}

View File

@ -0,0 +1,52 @@
/*
* $Id$
* From: $NetBSD: gatea20.c,v 1.2 1997/10/29 00:32:49 fvdl Exp $
*/
/* extracted from freebsd:sys/i386/boot/biosboot/io.c */
#include <sys/types.h>
#include <machine/cpufunc.h>
#include <stand.h>
#include "libi386.h"
#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
#define K_STATUS 0x64 /* keyboard status */
#define K_CMD 0x64 /* keybd ctlr command (write-only) */
#define K_OBUF_FUL 0x01 /* output buffer full */
#define K_IBUF_FUL 0x02 /* input buffer full */
#define KC_CMD_WIN 0xd0 /* read output port */
#define KC_CMD_WOUT 0xd1 /* write output port */
#define KB_A20 0x9f /* enable A20,
reset (!),
enable output buffer full interrupt
enable data line
disable clock line */
/*
* Gate A20 for high memory
*/
static unsigned char x_20 = KB_A20;
void gateA20()
{
__asm("pushfl ; cli");
#ifdef IBM_L40
outb(0x92, 0x2);
#else IBM_L40
while (inb(K_STATUS) & K_IBUF_FUL);
while (inb(K_STATUS) & K_OBUF_FUL)
(void)inb(K_RDWR);
outb(K_CMD, KC_CMD_WOUT);
delay(100);
while (inb(K_STATUS) & K_IBUF_FUL);
outb(K_RDWR, x_20);
delay(100);
while (inb(K_STATUS) & K_IBUF_FUL);
#endif IBM_L40
__asm("popfl");
}

View File

@ -0,0 +1,40 @@
/*
* $Id$
* From: $NetBSD: getsecs.c,v 1.1.1.1 1997/03/14 02:40:32 perry Exp $
*/
/* extracted from netbsd:sys/arch/i386/netboot/misc.c */
#include <sys/types.h>
#include <stand.h>
#include "libi386.h"
extern int biosgetrtc __P((u_long*));
time_t
time(time_t *tloc) {
/*
* Return the current time (of day) in seconds.
* XXX should be extended to do it "more right" perhaps?
* XXX uses undocumented BCD support from libstand.
*/
u_long t;
time_t sec;
if(biosgetrtc(&t))
panic("RTC invalid");
sec = bcd2bin(t & 0xff);
sec *= 60;
t >>= 8;
sec += bcd2bin(t & 0xff);
sec *= 60;
t >>= 8;
sec += bcd2bin(t & 0xff);
if (tloc != NULL)
*tloc = sec;
return(sec);
}

View File

@ -0,0 +1,64 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* i386-specific module functionality.
*
*/
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
#include "libi386.h"
/*
* Look for a method and having found it, boot the kernel module.
*/
int
i386_boot(void)
{
int i;
for (i = 0; module_formats[i] != NULL; i++) {
if (((loaded_modules->m_flags & MF_FORMATMASK) == module_formats[i]->l_format) &&
(module_formats[i]->l_exec != NULL)) {
return((module_formats[i]->l_exec)(loaded_modules));
}
}
}
/*
* Use voodoo to load modules required by current hardware.
*/
int
i386_autoload(void)
{
/* XXX use PnP to locate stuff here */
return(0);
}

View File

@ -0,0 +1,86 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* i386 fully-qualified device descriptor.
* Note, this must match the 'struct devdesc' declaration
* in bootstrap.h.
*/
struct i386_devdesc
{
struct devsw *d_dev;
int d_type;
union
{
struct
{
int unit;
int slice;
int partition;
void *data;
} biosdisk;
struct
{
int unit; /* XXX net layer lives over these? */
} netif;
} d_kind;
};
extern int i386_getdev(void **vdev, char *devspec, char **path);
extern char *i386_fmtdev(void *vdev);
extern int i386_setcurrdev(struct env_var *ev, int flags, void *value);
extern struct devdesc currdev; /* our current device */
#define MAXDEV 31 /* maximum number of distinct devices */
/* exported devices XXX rename? */
extern struct devsw biosdisk;
/* from crt module */
extern void vpbcopy(void*, vm_offset_t, int);
extern void pvbcopy(vm_offset_t, void*, int);
extern void pbzero(vm_offset_t, int);
extern vm_offset_t vtophys(void*);
extern int pread(int, vm_offset_t, int);
extern void startprog(vm_offset_t, int, u_int32_t *, vm_offset_t);
extern void delay(int);
extern int getbasemem(void);
extern int getextmem(void);
extern void reboot(void);
extern void gateA20(void);
extern int i386_boot(void);
extern int i386_autoload(void);
extern int bi_getboothowto(char *kargs);
extern vm_offset_t bi_copyenv(vm_offset_t addr);

View File

@ -0,0 +1,79 @@
/*
* $Id$
* From: $NetBSD: pread.c,v 1.2 1997/03/22 01:48:38 thorpej Exp $
*/
/*
* Copyright (c) 1996
* Matthias Drochner. 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 for the NetBSD Project
* by Matthias Drochner.
* 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.
*
*/
/* read into destination in flat addr space */
#include <stand.h>
#include "libi386.h"
#ifdef SAVE_MEMORY
#define BUFSIZE (1*1024)
#else
#define BUFSIZE (4*1024)
#endif
static char buf[BUFSIZE];
int
pread(fd, dest, size)
int fd;
vm_offset_t dest;
int size;
{
int rsize;
rsize = size;
while (rsize > 0) {
int count, got;
count = (rsize < BUFSIZE ? rsize : BUFSIZE);
got = read(fd, buf, count);
if (got < 0)
return (-1);
/* put to physical space */
vpbcopy(buf, dest, got);
dest += got;
rsize -= got;
if (got < count)
break; /* EOF */
}
return (size - rsize);
}

View File

@ -0,0 +1,120 @@
/* $NetBSD: startprog.S,v 1.1.1.1 1997/03/14 02:40:33 perry Exp $ */
/* starts program in protected mode / flat space
with given stackframe
needs global variables flatcodeseg and flatdataseg
(gdt offsets)
derivied from: NetBSD:sys/arch/i386/boot/asm.S
*/
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <machine/asm.h>
/*
* startprog(phyaddr,argc,argv,stack)
* start the program on protected mode where phyaddr is the entry point
*/
ENTRY(startprog)
pushl %ebp
movl %esp, %ebp
# prepare a new stack
movl $flatdataseg, %ebx
movw %bx, %es # for arg copy
movl 20(%ebp), %eax # stack
subl $4,%eax
movl %eax, %edi
# push some number of args onto the stack
movl 12(%ebp), %ecx # argc
movl %ecx, %eax
decl %eax
shl $2, %eax
addl 16(%ebp), %eax # ptr to last arg
movl %eax, %esi
std # backwards
rep
movsl
cld # LynxOS depends on it
movl 8(%ebp), %ecx # entry
# set new stackptr (movsl decd sp 1 more -> dummy return address)
movw %bx, %ss
movl %edi, %esp
# plug in a return address so that FreeBSD detects we are using
# bootinfo
movl $ourreturn, %eax
movl %eax, (%esp)
# push on our entry address
movl $flatcodeseg, %ebx # segment
pushl %ebx
pushl %ecx #entry
# convert over the other data segs
movl $flatdataseg, %ebx
movl %bx, %ds
movl %bx, %es
# convert the PC (and code seg)
lret
ourreturn:
/* For now there is not much we can do, just lock in a loop */
jmp ourreturn

View File

@ -0,0 +1,199 @@
/*
* Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
* Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
*
* $Id$
*/
#include <stand.h>
#include <machine/cpufunc.h>
#include "bootstrap.h"
/* in vidconsole.S */
extern void vidputc(int c);
extern int kbdgetc(void);
extern int kbdiskey(void);
static int probe_keyboard(void);
static void vidc_probe(struct console *cp);
static int vidc_init(int arg);
static int vidc_in(void);
struct console vidconsole = {
"vidconsole",
"internal video/keyboard",
0,
vidc_probe,
vidc_init,
vidputc,
vidc_in,
kbdiskey
};
static void
vidc_probe(struct console *cp)
{
/* look for a keyboard */
#if 0
if (probe_keyboard()) {
#else
if (1) {
#endif
cp->c_flags |= C_PRESENTIN;
}
/* XXX for now, always assume we can do BIOS screen output */
cp->c_flags |= C_PRESENTOUT;
}
static int
vidc_init(int arg)
{
return(0); /* XXX reinit? */
}
static int
vidc_in(void)
{
if (kbdiskey()) {
return(kbdgetc());
} else {
return(-1);
}
}
#define PROBE_MAXRETRY 5
#define PROBE_MAXWAIT 400
#define IO_DUMMY 0x84
#define IO_KBD 0x060 /* 8042 Keyboard */
/* selected defines from kbdio.h */
#define KBD_STATUS_PORT 4 /* status port, read */
#define KBD_DATA_PORT 0 /* data port, read/write
* also used as keyboard command
* and mouse command port
*/
#define KBDC_ECHO 0x00ee
#define KBDS_ANY_BUFFER_FULL 0x0001
#define KBDS_INPUT_BUFFER_FULL 0x0002
#define KBD_ECHO 0x00ee
/* 7 microsec delay necessary for some keyboard controllers */
static void
delay7(void)
{
/*
* I know this is broken, but no timer is avaiable yet at this stage...
* See also comments in `delay1ms()'.
*/
inb(IO_DUMMY); inb(IO_DUMMY);
inb(IO_DUMMY); inb(IO_DUMMY);
inb(IO_DUMMY); inb(IO_DUMMY);
}
/*
* This routine uses an inb to an unused port, the time to execute that
* inb is approximately 1.25uS. This value is pretty constant across
* all CPU's and all buses, with the exception of some PCI implentations
* that do not forward this I/O adress to the ISA bus as they know it
* is not a valid ISA bus address, those machines execute this inb in
* 60 nS :-(.
*
*/
static void
delay1ms(void)
{
int i = 800;
while (--i >= 0)
(void)inb(0x84);
}
/*
* We use the presence/absence of a keyboard to determine whether the internal
* console can be used for input.
*
* Perform a simple test on the keyboard; issue the ECHO command and see
* if the right answer is returned. We don't do anything as drastic as
* full keyboard reset; it will be too troublesome and take too much time.
*/
static int
probe_keyboard(void)
{
int retry = PROBE_MAXRETRY;
int wait;
int i;
while (--retry >= 0) {
/* flush any noise */
while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
delay7();
inb(IO_KBD + KBD_DATA_PORT);
delay1ms();
}
/* wait until the controller can accept a command */
for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
if (((i = inb(IO_KBD + KBD_STATUS_PORT))
& (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0)
break;
if (i & KBDS_ANY_BUFFER_FULL) {
delay7();
inb(IO_KBD + KBD_DATA_PORT);
}
delay1ms();
}
if (wait <= 0)
continue;
/* send the ECHO command */
outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO);
/* wait for a response */
for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL)
break;
delay1ms();
}
if (wait <= 0)
continue;
delay7();
i = inb(IO_KBD + KBD_DATA_PORT);
#ifdef PROBE_KBD_BEBUG
printf("probe_keyboard: got 0x%x.\n", i);
#endif
if (i == KBD_ECHO) {
/* got the right answer */
return (0);
}
}
return (1);
}

View File

@ -0,0 +1,103 @@
/* $Id$ */
/*
* PC console handling
* originally from: FreeBSD:sys/i386/boot/netboot/start2.S via NetBSD
*/
#include <machine/asm.h>
#define data32 .byte 0x66
.text
/**************************************************************************
PUTC - Print a character
**************************************************************************/
ENTRY(vidputc)
push %ebp
mov %esp,%ebp
push %ecx
push %ebx
push %esi
push %edi
movb 8(%ebp),%cl
call CNAME(prot_to_real) # enter real mode
movb %cl,%al
data32
mov $1,%ebx
movb $0x0e,%ah
int $0x10
data32
call CNAME(real_to_prot) # back to protected mode
pop %edi
pop %esi
pop %ebx
pop %ecx
pop %ebp
ret
/**************************************************************************
GETC - Get a character
**************************************************************************/
ENTRY(kbdgetc)
push %ebp
mov %esp,%ebp
push %ebx
push %esi
push %edi
call CNAME(prot_to_real) # enter real mode
movb $0x0,%ah
int $0x16
movb %al,%bl
data32
call CNAME(real_to_prot) # back to protected mode
xor %eax,%eax
movb %bl,%al
pop %edi
pop %esi
pop %ebx
pop %ebp
ret
/**************************************************************************
ISKEY - Check for keyboard interrupt
**************************************************************************/
ENTRY(kbdiskey)
push %ebp
mov %esp,%ebp
push %ebx
push %esi
push %edi
call CNAME(prot_to_real) # enter real mode
xor %ebx,%ebx
movb $0x1,%ah
int $0x16
data32
jz 1f
movb %al,%bl
1:
data32
call CNAME(real_to_prot) # back to protected mode
xor %eax,%eax
movb %bl,%al
pop %edi
pop %esi
pop %ebx
pop %ebp
ret

View File

@ -0,0 +1,36 @@
# $Id$
# from $NetBSD: Makefile,v 1.12 1998/02/19 14:18:36 drochner Exp $
BASE= loader
PROG= ${BASE}.sym
NOMAN=
NEWVERSWHAT= "bootstrap loader"
# architecture-specific loader code
SRCS+= main.c conf.c
# Always add MI sources
.PATH: ${.CURDIR}/../../common
.include <${.CURDIR}/../../common/Makefile.inc>
CFLAGS+= -I${.CURDIR}/../../common
# Verbose ls causes extra heap usage
CFLAGS+= -DVERBOSE_LS
CLEANFILES+= vers.c vers.o ${BASE}.list
CFLAGS+= -Wall
# i386 standalone support library
LIBI386= ${.OBJDIR}/../libi386/libi386.a
CFLAGS+= -I${.CURDIR}/..
CRT= ${.OBJDIR}/../libi386/crt/bootsect/bscrt.o
vers.o:
sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
${CC} -c vers.c
${BASE}.sym: ${OBJS} ${LIBI386} ${CRT} vers.o
${LD} -o ${BASE}.sym -M -e _start -N -Ttext 0 ${CRT} ${OBJS} \
vers.o -lstand ${LIBI386} -lstand >${.OBJDIR}/${BASE}.list
.include <bsd.prog.mk>

View File

@ -0,0 +1,85 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
#include <stand.h>
#include <bootstrap.h>
#include "libi386/libi386.h"
/*
* We could use linker sets for some or all of these, but
* then we would have to control what ended up linked into
* the bootstrap. So it's easier to conditionalise things
* here.
*
* XXX rename these arrays to be consistent and less namespace-hostile
*
* XXX as libi386 and biosboot merge, some of these can become linker sets.
*/
/* Exported for libstand */
struct devsw *devsw[] = {
&biosdisk,
/* XXX network devices? */
NULL
};
struct fs_ops *file_system[] = {
&ufs_fsops,
#if notyet
&dosfs_fsops,
#endif
&zipfs_fsops,
NULL
};
/* Exported for i386 only */
/*
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct module_format i386_aout;
struct module_format *module_formats[] = {
&i386_aout,
NULL
};
/*
* Consoles
*
* We don't prototype these in libi386.h because they require
* data structures from bootstrap.h as well.
*/
extern struct console vidconsole;
extern struct console comconsole;
struct console *consoles[] = {
&vidconsole,
&comconsole,
NULL
};

156
sys/boot/i386/loader/main.c Normal file
View File

@ -0,0 +1,156 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* MD bootstrap main() and assorted miscellaneous
* commands.
*/
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
#include "libi386/libi386.h"
extern int boot_biosdev; /* from runtime startup */
struct arch_switch archsw; /* MI/MD interface boundary */
/* from vers.c */
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
/* XXX debugging */
#include "libi386/crt/diskbuf.h"
extern char stackbase, stacktop;
extern char end[];
void
main(void)
{
struct i386_devdesc currdev;
int i;
/*
* Initialise the heap as early as possible. Once this is done, alloc() is usable.
* The stack is buried inside us, so this is safe
*/
setheap((void *)end, (void *)(end + 0x80000));
/*
* XXX Chicken-and-egg problem; we want to have console output early, but some
* console attributes may depend on reading from eg. the boot device, which we
* can't do yet.
*
* We can use printf() etc. once this is done.
*/
cons_probe();
/*
* March through the device switch probing for things.
*/
for (i = 0; devsw[i] != NULL; i++)
if (devsw[i]->dv_init != NULL)
(devsw[i]->dv_init)();
printf("\n");
printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
printf("memory: %d/%dkB\n", getbasemem(), getextmem());
#if 0
printf("diskbuf at %p, %d sectors\n", &diskbuf, diskbuf_size);
printf("using %d bytes of stack at %p\n", (&stacktop - &stackbase), &stacktop);
#endif
/* We're booting from a BIOS disk, try to spiff this */
currdev.d_dev = devsw[0]; /* XXX presumes that biosdisk is first in devsw */
currdev.d_type = currdev.d_dev->dv_type;
currdev.d_kind.biosdisk.unit = boot_biosdev;
currdev.d_kind.biosdisk.slice = -1; /* XXX should be able to detect this, default to autoprobe */
currdev.d_kind.biosdisk.partition = 0; /* default to 'a' */
/* Create i386-specific variables */
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&currdev), i386_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&currdev), env_noset, env_nounset);
setenv("LINES", "24", 1); /* optional */
archsw.arch_autoload = i386_autoload;
archsw.arch_boot = i386_boot;
archsw.arch_getdev = i386_getdev;
/*
* XXX should these be in the MI source?
*/
source("/boot/boot.conf");
#if 0
legacy_config(); /* read old /boot.config file */
#endif
printf("\n");
autoboot(10, NULL); /* try to boot automatically */
printf("\nType '?' for a list of commands, 'help' for more detailed help.\n");
setenv("prompt", "$currdev>", 1);
interact(); /* doesn't return */
}
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
static int
command_reboot(int argc, char *argv[])
{
printf("Rebooting...\n");
delay(1000000);
reboot();
/* Note: we shouldn't get to this point! */
panic("Reboot failed!");
exit(0);
}
COMMAND_SET(stack, "stack", "show stack usage", command_stack);
static int
command_stack(int argc, char *argv[])
{
char *cp;
for (cp = &stackbase; cp < &stacktop; cp++)
if (*cp != 0)
break;
printf("%d bytes of stack used\n", &stacktop - cp);
return(CMD_OK);
}
COMMAND_SET(heap, "heap", "show heap usage", command_heap);
static int
command_heap(int argc, char *argv[])
{
printf("heap base at %p, top at %p, used %d\n", end, sbrk(0), sbrk(0) - end);
return(CMD_OK);
}

Some files were not shown because too many files have changed in this diff Show More