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:
parent
2bd323977f
commit
c2f9d95de5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MSMITH/; revision=38465
4
sys/boot/Makefile
Normal file
4
sys/boot/Makefile
Normal 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
6
sys/boot/alpha/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $Id$
|
||||
|
||||
SUBDIR= libalpha
|
||||
SUBDIR+= boot1 boot2 netboot
|
||||
|
||||
.include <bsd.subdir.mk>
|
6
sys/boot/alpha/Makefile.inc
Normal file
6
sys/boot/alpha/Makefile.inc
Normal 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
|
47
sys/boot/alpha/boot1/Makefile
Normal file
47
sys/boot/alpha/boot1/Makefile
Normal 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
|
||||
|
188
sys/boot/alpha/boot1/boot1.c
Normal file
188
sys/boot/alpha/boot1/boot1.c
Normal 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
187
sys/boot/alpha/boot1/sys.c
Normal 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;
|
||||
}
|
69
sys/boot/alpha/boot2/Makefile
Normal file
69
sys/boot/alpha/boot2/Makefile
Normal 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 $<
|
||||
|
1000
sys/boot/alpha/boot2/boot2.list
Normal file
1000
sys/boot/alpha/boot2/boot2.list
Normal file
File diff suppressed because it is too large
Load Diff
83
sys/boot/alpha/boot2/conf.c
Normal file
83
sys/boot/alpha/boot2/conf.c
Normal 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
|
||||
};
|
44
sys/boot/alpha/boot2/newvers.sh
Normal file
44
sys/boot/alpha/boot2/newvers.sh
Normal 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
|
2
sys/boot/alpha/boot2/setdefs.h
Normal file
2
sys/boot/alpha/boot2/setdefs.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* $Id$ */
|
||||
DEFINE_SET(Xcommand_set, 15);
|
4
sys/boot/alpha/boot2/vers.c
Normal file
4
sys/boot/alpha/boot2/vers.c
Normal 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";
|
7
sys/boot/alpha/boot2/version
Normal file
7
sys/boot/alpha/boot2/version
Normal 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.
|
313
sys/boot/alpha/common/gensetdefs.c
Normal file
313
sys/boot/alpha/common/gensetdefs.c
Normal 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));
|
||||
}
|
178
sys/boot/alpha/common/main.c
Normal file
178
sys/boot/alpha/common/main.c
Normal 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);
|
||||
}
|
49
sys/boot/alpha/common/setdef0.c
Normal file
49
sys/boot/alpha/common/setdef0.c
Normal 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__ */
|
41
sys/boot/alpha/common/setdef1.c
Normal file
41
sys/boot/alpha/common/setdef1.c
Normal 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__ */
|
23
sys/boot/alpha/libalpha/Makefile
Normal file
23
sys/boot/alpha/libalpha/Makefile
Normal 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>
|
71
sys/boot/alpha/libalpha/OSFpal.c
Normal file
71
sys/boot/alpha/libalpha/OSFpal.c
Normal 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");
|
||||
}
|
||||
|
64
sys/boot/alpha/libalpha/alpha_module.c
Normal file
64
sys/boot/alpha/libalpha/alpha_module.c
Normal 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);
|
||||
}
|
57
sys/boot/alpha/libalpha/bbinfo.h
Normal file
57
sys/boot/alpha/libalpha/bbinfo.h
Normal 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;
|
||||
};
|
11
sys/boot/alpha/libalpha/common.h
Normal file
11
sys/boot/alpha/libalpha/common.h
Normal 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));
|
40
sys/boot/alpha/libalpha/delay.c
Normal file
40
sys/boot/alpha/libalpha/delay.c
Normal 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)
|
||||
;
|
||||
}
|
232
sys/boot/alpha/libalpha/devicename.c
Normal file
232
sys/boot/alpha/libalpha/devicename.c
Normal 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);
|
||||
}
|
||||
|
316
sys/boot/alpha/libalpha/elf_freebsd.c
Normal file
316
sys/boot/alpha/libalpha/elf_freebsd.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
37
sys/boot/alpha/libalpha/getsecs.c
Normal file
37
sys/boot/alpha/libalpha/getsecs.c
Normal 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);
|
||||
}
|
107
sys/boot/alpha/libalpha/libalpha.h
Normal file
107
sys/boot/alpha/libalpha/libalpha.h
Normal 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);
|
351
sys/boot/alpha/libalpha/pal.S
Normal file
351
sys/boot/alpha/libalpha/pal.S
Normal 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)
|
165
sys/boot/alpha/libalpha/prom.c
Normal file
165
sys/boot/alpha/libalpha/prom.c
Normal 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);
|
||||
}
|
118
sys/boot/alpha/libalpha/prom_disp.S
Normal file
118
sys/boot/alpha/libalpha/prom_disp.S
Normal 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
|
139
sys/boot/alpha/libalpha/prom_swpal.S
Normal file
139
sys/boot/alpha/libalpha/prom_swpal.S
Normal 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
|
48
sys/boot/alpha/libalpha/reboot.c
Normal file
48
sys/boot/alpha/libalpha/reboot.c
Normal 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();
|
||||
}
|
334
sys/boot/alpha/libalpha/srmdisk.c
Normal file
334
sys/boot/alpha/libalpha/srmdisk.c
Normal 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);
|
||||
}
|
||||
|
257
sys/boot/alpha/libalpha/srmnet.c
Normal file
257
sys/boot/alpha/libalpha/srmnet.c
Normal 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);
|
||||
}
|
85
sys/boot/alpha/libalpha/start.S
Normal file
85
sys/boot/alpha/libalpha/start.S
Normal 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)
|
43
sys/boot/alpha/libalpha/time.c
Normal file
43
sys/boot/alpha/libalpha/time.c
Normal 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;
|
||||
}
|
72
sys/boot/alpha/netboot/Makefile
Normal file
72
sys/boot/alpha/netboot/Makefile
Normal 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 $<
|
||||
|
89
sys/boot/alpha/netboot/conf.c
Normal file
89
sys/boot/alpha/netboot/conf.c
Normal 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
|
||||
};
|
1177
sys/boot/alpha/netboot/netboot.list
Normal file
1177
sys/boot/alpha/netboot/netboot.list
Normal file
File diff suppressed because it is too large
Load Diff
44
sys/boot/alpha/netboot/newvers.sh
Normal file
44
sys/boot/alpha/netboot/newvers.sh
Normal 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
|
2
sys/boot/alpha/netboot/setdefs.h
Normal file
2
sys/boot/alpha/netboot/setdefs.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* $Id$ */
|
||||
DEFINE_SET(Xcommand_set, 15);
|
4
sys/boot/alpha/netboot/vers.c
Normal file
4
sys/boot/alpha/netboot/vers.c
Normal 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";
|
7
sys/boot/alpha/netboot/version
Normal file
7
sys/boot/alpha/netboot/version
Normal 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.
|
4
sys/boot/common/Makefile.inc
Normal file
4
sys/boot/common/Makefile.inc
Normal 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
229
sys/boot/common/boot.c
Normal 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
226
sys/boot/common/bootstrap.h
Normal 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
155
sys/boot/common/commands.c
Normal 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
142
sys/boot/common/console.c
Normal 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
275
sys/boot/common/dev_net.c
Normal 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
30
sys/boot/common/dev_net.h
Normal 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
61
sys/boot/common/devopen.c
Normal 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
207
sys/boot/common/interp.c
Normal 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
101
sys/boot/common/load.c
Normal 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
160
sys/boot/common/ls.c
Normal 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
55
sys/boot/common/misc.c
Normal 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
129
sys/boot/common/module.c
Normal 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
56
sys/boot/common/panic.c
Normal 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
3
sys/boot/i386/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
SUBDIR= installboot libi386 loader
|
||||
|
||||
.include <bsd.subdir.mk>
|
16
sys/boot/i386/installboot/Makefile
Normal file
16
sys/boot/i386/installboot/Makefile
Normal 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>
|
146
sys/boot/i386/installboot/bootblks.c
Normal file
146
sys/boot/i386/installboot/bootblks.c
Normal 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);
|
||||
}
|
156
sys/boot/i386/installboot/getmount.c
Normal file
156
sys/boot/i386/installboot/getmount.c
Normal 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;
|
||||
}
|
||||
}
|
150
sys/boot/i386/installboot/installboot.8
Normal file
150
sys/boot/i386/installboot/installboot.8
Normal 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 .
|
433
sys/boot/i386/installboot/installboot.c
Normal file
433
sys/boot/i386/installboot/installboot.c
Normal 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);
|
||||
}
|
9
sys/boot/i386/installboot/installboot.h
Normal file
9
sys/boot/i386/installboot/installboot.h
Normal 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;
|
21
sys/boot/i386/libi386/Makefile
Normal file
21
sys/boot/i386/libi386/Makefile
Normal 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>
|
274
sys/boot/i386/libi386/aout_freebsd.c
Normal file
274
sys/boot/i386/libi386/aout_freebsd.c
Normal 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");
|
||||
}
|
79
sys/boot/i386/libi386/biosdelay.S
Normal file
79
sys/boot/i386/libi386/biosdelay.S
Normal 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
|
408
sys/boot/i386/libi386/biosdisk.c
Normal file
408
sys/boot/i386/libi386/biosdisk.c
Normal 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);
|
||||
}
|
114
sys/boot/i386/libi386/biosdisk_support.S
Normal file
114
sys/boot/i386/libi386/biosdisk_support.S
Normal 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
|
||||
|
77
sys/boot/i386/libi386/biosgetrtc.S
Normal file
77
sys/boot/i386/libi386/biosgetrtc.S
Normal 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
|
99
sys/boot/i386/libi386/biosmem.S
Normal file
99
sys/boot/i386/libi386/biosmem.S
Normal 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
|
||||
|
66
sys/boot/i386/libi386/biosreboot.S
Normal file
66
sys/boot/i386/libi386/biosreboot.S
Normal 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
|
197
sys/boot/i386/libi386/bootinfo.c
Normal file
197
sys/boot/i386/libi386/bootinfo.c
Normal 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);
|
||||
}
|
197
sys/boot/i386/libi386/bootinfo32.c
Normal file
197
sys/boot/i386/libi386/bootinfo32.c
Normal 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);
|
||||
}
|
197
sys/boot/i386/libi386/bootinfo64.c
Normal file
197
sys/boot/i386/libi386/bootinfo64.c
Normal 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);
|
||||
}
|
78
sys/boot/i386/libi386/comconsole.c
Normal file
78
sys/boot/i386/libi386/comconsole.c
Normal 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);
|
||||
}
|
||||
}
|
147
sys/boot/i386/libi386/comconsole_support.S
Normal file
147
sys/boot/i386/libi386/comconsole_support.S
Normal 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
|
3
sys/boot/i386/libi386/crt/Makefile
Normal file
3
sys/boot/i386/libi386/crt/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
SUBDIR= bootsect
|
||||
|
||||
.include <bsd.subdir.mk>
|
176
sys/boot/i386/libi386/crt/bios_disk.S
Normal file
176
sys/boot/i386/libi386/crt/bios_disk.S
Normal 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
|
148
sys/boot/i386/libi386/crt/biosdisk_ll.c
Normal file
148
sys/boot/i386/libi386/crt/biosdisk_ll.c
Normal 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);
|
||||
}
|
54
sys/boot/i386/libi386/crt/biosdisk_ll.h
Normal file
54
sys/boot/i386/libi386/crt/biosdisk_ll.h
Normal 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);
|
25
sys/boot/i386/libi386/crt/bootsect/Makefile
Normal file
25
sys/boot/i386/libi386/crt/bootsect/Makefile
Normal 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>
|
64
sys/boot/i386/libi386/crt/bootsect/bbinfo.h
Normal file
64
sys/boot/i386/libi386/crt/bootsect/bbinfo.h
Normal 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
|
88
sys/boot/i386/libi386/crt/bootsect/bootsectmain.c
Normal file
88
sys/boot/i386/libi386/crt/bootsect/bootsectmain.c
Normal 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(); */
|
||||
}
|
49
sys/boot/i386/libi386/crt/bootsect/fraglist.S
Normal file
49
sys/boot/i386/libi386/crt/bootsect/fraglist.S
Normal 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
|
540
sys/boot/i386/libi386/crt/bootsect/start_bootsect.S
Normal file
540
sys/boot/i386/libi386/crt/bootsect/start_bootsect.S
Normal 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
|
27
sys/boot/i386/libi386/crt/buffers.S
Normal file
27
sys/boot/i386/libi386/crt/buffers.S
Normal 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
|
42
sys/boot/i386/libi386/crt/diskbuf.h
Normal file
42
sys/boot/i386/libi386/crt/diskbuf.h
Normal 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 */
|
234
sys/boot/i386/libi386/devicename.c
Normal file
234
sys/boot/i386/libi386/devicename.c
Normal 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);
|
||||
}
|
||||
|
52
sys/boot/i386/libi386/gatea20.c
Normal file
52
sys/boot/i386/libi386/gatea20.c
Normal 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");
|
||||
}
|
40
sys/boot/i386/libi386/getsecs.c
Normal file
40
sys/boot/i386/libi386/getsecs.c
Normal 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);
|
||||
}
|
64
sys/boot/i386/libi386/i386_module.c
Normal file
64
sys/boot/i386/libi386/i386_module.c
Normal 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);
|
||||
}
|
86
sys/boot/i386/libi386/libi386.h
Normal file
86
sys/boot/i386/libi386/libi386.h
Normal 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);
|
79
sys/boot/i386/libi386/pread.c
Normal file
79
sys/boot/i386/libi386/pread.c
Normal 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);
|
||||
}
|
120
sys/boot/i386/libi386/startprog.S
Normal file
120
sys/boot/i386/libi386/startprog.S
Normal 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
|
||||
|
199
sys/boot/i386/libi386/vidconsole.c
Normal file
199
sys/boot/i386/libi386/vidconsole.c
Normal 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);
|
||||
}
|
103
sys/boot/i386/libi386/vidconsole_support.S
Normal file
103
sys/boot/i386/libi386/vidconsole_support.S
Normal 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
|
36
sys/boot/i386/loader/Makefile
Normal file
36
sys/boot/i386/loader/Makefile
Normal 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>
|
85
sys/boot/i386/loader/conf.c
Normal file
85
sys/boot/i386/loader/conf.c
Normal 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
156
sys/boot/i386/loader/main.c
Normal 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
Loading…
Reference in New Issue
Block a user