diff --git a/sys/arch/i386/stand/Makefile.booters b/sys/arch/i386/stand/Makefile.booters new file mode 100644 index 000000000000..5ab6e00b5fd5 --- /dev/null +++ b/sys/arch/i386/stand/Makefile.booters @@ -0,0 +1,68 @@ +# $NetBSD: Makefile.booters,v 1.1.1.1 1997/03/14 02:40:29 perry Exp $ + +BINDIR= /usr/mdec +STRIP= +BINMODE=444 + +.PATH: ${.CURDIR}/../lib/crt/bootsect ${.CURDIR}/../lib +BSSTART= start_bootsect.o fraglist.o bootsectmain.o biosdisk_ll.o bios_disk.o +.PATH: ${.CURDIR}/../lib/crt/rom +ROMSTART= start_rom.o +.if exists(${.CURDIR}/../genprom/obj) +GENPROM= ${.CURDIR}/../genprom/obj/genprom +.else +GENPROM= ${.CURDIR}/../genprom/genprom +.endif +.PATH: ${.CURDIR}/../lib/crt/dos +DOSSTART= start_dos.o doscommain.o + +CPPFLAGS += -I$S -I${.CURDIR}/../lib -I$S/lib/libsa + +.include + +### find out what to use for libkern +KERN_AS= library +# XXX only bzero is missing in libkern, but we have to list all we need +KERNMISCMAKEFLAGS= "SRCS=bzero.S bcmp.S strchr.c strncpy.c strcmp.S __main.c" +.include "${S}/lib/libkern/Makefile.inc" +LIBKERN= ${KERNLIB} + +### find out what to use for libz +Z_AS= library +.include "${S}/lib/libz/Makefile.inc" +LIBZ= ${ZLIB} + +### find out what to use for libsa +SA_AS= library +.include "${S}/lib/libsa/Makefile.inc" +LIBSA= ${SALIB} + +### find out what to use for libi386 +I386DIR= ${.CURDIR}/../lib # XXX +.include "${I386DIR}/Makefile.inc" +LIBI386= ${I386LIB} + +${PROG}.sym: ${BSSTART} ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} ${LIBI386} + ${LD} -o ${PROG}.sym -M -e _start -N -Ttext 0 $(BSSTART) $(OBJS) \ + ${LIBI386} ${LIBSA} ${LIBZ} ${LIBSA} ${LIBKERN} >${PROG}.list + +${PROG}.rom: ${GENPROM} ${ROMSTART} ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} ${LIBI386} + ${LD} -o ${PROG}.sym -M -e _start -N -Ttext ${RELOC} $(ROMSTART) $(OBJS) \ + ${LIBI386} ${LIBSA} ${LIBZ} ${LIBSA} ${LIBKERN} >${PROG}.list + cp ${PROG}.sym ${PROG}.bin + strip ${PROG}.bin + dd if=${PROG}.bin ibs=32 skip=1 | ${GENPROM} $(ROM_SIZE) > ${PROG}.rom || (rm ${PROG}.rom; false) + rm -f ${PROG}.bin + +${PROG}.com: ${DOSSTART} ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} ${LIBI386} + ${LD} -o ${PROG}.sym -M -e _start -N -Ttext 0x100 $(DOSSTART) $(OBJS) \ + ${LIBI386} ${LIBSA} ${LIBZ} ${LIBSA} ${LIBKERN} >${PROG}.list + cp ${PROG}.sym ${PROG}.bin + strip ${PROG}.bin + dd if=${PROG}.bin of=${PROG}.com ibs=32 skip=1 obs=1024b + rm -f ${PROG}.bin + +${GENPROM}: + @echo "genprom" missing + @false + diff --git a/sys/arch/i386/stand/README b/sys/arch/i386/stand/README new file mode 100644 index 000000000000..3f189972bed9 --- /dev/null +++ b/sys/arch/i386/stand/README @@ -0,0 +1,69 @@ +$NetBSD: README,v 1.1.1.1 1997/03/14 02:40:29 perry Exp $ + +[This is Matthias Drochner's original README, very lightly edited.] + +libsa-based bootcode for i386 +should work with -current libsa (I used 97/02/06.) + +contents: +./libsa: additions to sys/lib/libsa, not i386 specific +./lib: i386 specific parts +./lib/netif: driver for ethernet adapters +./biosboot: boot sector for hd / fd +./installboot: program to install boot sector +./dosboot: DOS program to boot from DOS or UFS drives +./netboot: ROM image for diskless boot +./genprom: program to create ROM image + +to build: +make, hopefully +perhaps adjust "S" to location of kernel sources + +notes: +-to install bootsect: + mount /dev/XdNa /somewhere + installboot biosboot.sym /dev/rXdNa +-netboot ethernet cards: + select with USE_NETIF + for wd80x3, BASEREG and BASEMEM must be set properly + for pcnet_isapnp, ISAPNPID must be set properly +-text+data+bss+stack <= 64k, heap can be above + +Please report all errors! + +Source taken from FreeBSD (as noted in the file) has the following copyright: + +Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 +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. diff --git a/sys/arch/i386/stand/biosboot/Makefile b/sys/arch/i386/stand/biosboot/Makefile new file mode 100644 index 000000000000..1bf2926059b1 --- /dev/null +++ b/sys/arch/i386/stand/biosboot/Makefile @@ -0,0 +1,35 @@ +# $NetBSD: Makefile,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ + +S= ../../../../ + +PROG= biosboot +NOMAN= + +SRCS= main.c devopen.c conf.c version.c + +CLEANFILES+= ${BSSTART} ${PROG}.sym ${PROG}.list + +CPPFLAGS+= -DCOMPAT_OLDBOOT +#should go into SAMISCCPPFLAGS after system upgrade +CPPFLAGS+= -DHEAP_START=0x10000 -DHEAP_LIMIT=0x40000 +#CPPFLAGS+= -DMAXFLENTRIES=10 + +#CFLAGS= -O2 -fomit-frame-pointer -fno-defer-pop +#needs some cleanup in libsa +#CFLAGS+= -Wall + +# XXX should go into library +SRCS+= ls.c +.PATH: ${.CURDIR}/../libsa + +${PROG}: ${PROG}.sym + @# do nothing + +install: + ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ + ${PROG}.sym ${DESTDIR}${BINDIR} + + +SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_INCLUDE_NET=no + +.include "../Makefile.booters" diff --git a/sys/arch/i386/stand/biosboot/conf.c b/sys/arch/i386/stand/biosboot/conf.c new file mode 100644 index 000000000000..f0a2d1165ff6 --- /dev/null +++ b/sys/arch/i386/stand/biosboot/conf.c @@ -0,0 +1,51 @@ +/* $NetBSD: conf.c,v 1.1.1.1 1997/03/14 02:40:31 perry 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 + +#include +#include + +#include + +struct devsw devsw[] = { + { "disk", biosdiskstrategy, biosdiskopen, biosdiskclose, biosdiskioctl }, +}; +int ndevs = sizeof(devsw)/sizeof(struct devsw); + +struct fs_ops file_system[] = { + { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat }, +}; +int nfsys = sizeof(file_system)/sizeof(struct fs_ops); diff --git a/sys/arch/i386/stand/biosboot/devopen.c b/sys/arch/i386/stand/biosboot/devopen.c new file mode 100644 index 000000000000..fb8e1573b2d1 --- /dev/null +++ b/sys/arch/i386/stand/biosboot/devopen.c @@ -0,0 +1,115 @@ +/* $NetBSD: devopen.c,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ */ + +/* + * Copyright (c) 1996, 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 + +#include + +#include +#include + +static struct { + char *name; + int biosdev; +} biosdevtab[] = { + {"fd", 0}, + {"wd", 0x80}, + {"sd", 0x80}, + {"hd", 0x80} +}; +#define NUMBIOSDEVS (sizeof(biosdevtab) / sizeof(biosdevtab[0])) + +static int +dev2bios(devname, unit, biosdev) +char *devname; +unsigned int unit; +int *biosdev; +{ + int i; + + for(i = 0; i < NUMBIOSDEVS; i++) + if(!strcmp(devname, biosdevtab[i].name)) { + *biosdev = biosdevtab[i].biosdev + unit; + break; + } + if(i == NUMBIOSDEVS) + return(ENXIO); + + if(unit >= 4) /* ??? */ + return(EUNIT); + + return(0); +} + +int +bios2dev(biosdev, devname, unit) +int biosdev; +char **devname; +unsigned int *unit; +{ + if(biosdev & 0x80) /* call it "hd", we don't know better */ + *devname = biosdevtab[3].name; + else + *devname = biosdevtab[0].name; + + *unit = biosdev & 0x7f; + + return(0); +} + +/* + * Open the BIOS disk device + */ +int +devopen(f, fname, file) +struct open_file *f; +const char *fname; +char **file; +{ + char *fsname, *devname; + unsigned int unit, partition; + int biosdev; + int error; + struct devsw *dp; + + if((error = parsebootfile(fname, &fsname, &devname, + &unit, &partition, (const char**)file)) + || (error = dev2bios(devname, unit, &biosdev))) + return(error); + + dp = &devsw[0]; /* must be biosdisk */ + f->f_dev = dp; + return(biosdiskopen(f, biosdev, partition)); +} diff --git a/sys/arch/i386/stand/biosboot/main.c b/sys/arch/i386/stand/biosboot/main.c new file mode 100644 index 000000000000..03395bd058d9 --- /dev/null +++ b/sys/arch/i386/stand/biosboot/main.c @@ -0,0 +1,440 @@ +/* $NetBSD: main.c,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ */ + +/* + * 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 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. + * + */ + + +#include + +#include +#include + +#include + +extern char *strerror __P((int)); /* XXX missing in stand.h */ + +extern void ls __P((char*)); +extern int bios2dev __P((int, char**, int*)); + +int errno; +static char *consdev; +extern int boot_biosdev; + +extern char version[]; + +static char *names[] = { + "netbsd", "netbsd.gz", + "netbsd.old", "netbsd.old.gz", + "onetbsd", "onetbsd.gz", +#ifdef notyet + "netbsd.el", "netbsd.el.gz", +#endif /*notyet*/ +}; + +#define NUMNAMES (sizeof(names)/sizeof(char *)) +#define DEFFILENAME names[0] + +#define MAXDEVNAME 16 + +#define TIMEOUT 5 +#define POLL_FREQ 10 + +static char *default_devname; +static int default_unit, default_partition; +static char *default_filename; + +int +parsebootfile(fname, fsname, devname, unit, partition, file) +const char *fname; +char **fsname; /* out */ +char **devname; /* out */ +unsigned int *unit, *partition; /* out */ +const char **file; /* out */ +{ + const char *col, *help; + + *fsname = "ufs"; + *devname = default_devname; + *unit = default_unit; + *partition = default_partition; + *file = default_filename; + + if(!fname) return(0); + + if((col = strchr(fname, ':'))) { /* device given */ + static char savedevname[MAXDEVNAME+1]; + int devlen; + unsigned int u = 0, p = 0; + int i = 0; + + devlen = col - fname; + if(devlen > MAXDEVNAME) + return(EINVAL); + +#define isvalidname(c) ((c) >= 'a' && (c) <= 'z') + if(!isvalidname(fname[i])) + return(EINVAL); + do { + savedevname[i] = fname[i]; + i++; + } while(isvalidname(fname[i])); + savedevname[i] = '\0'; + +#define isnum(c) ((c) >= '0' && (c) <= '9') + if(i < devlen) { + if(!isnum(fname[i])) + return(EUNIT); + do { + u *= 10; + u += fname[i++] - '0'; + } while(isnum(fname[i])); + } + +#define isvalidpart(c) ((c) >= 'a' && (c) <= 'z') + if(i < devlen) { + if(!isvalidpart(fname[i])) + return(EPART); + p = fname[i++] - 'a'; + } + + if(i != devlen) + return(ENXIO); + + *devname = savedevname; + *unit = u; + *partition = p; + help = col + 1; + } else + help = fname; + + if(*help) *file = help; + + return(0); +} + +static void +print_bootsel(filename) +char *filename; +{ + char *fsname, *devname; + int unit, partition; + const char *file; + + if(!parsebootfile(filename, &fsname, &devname, &unit, &partition, &file)) + printf("booting %s%d%c:%s\n", devname, unit, + 'a' + partition, file); +} + +static void +bootit(filename, howto, tell) +const char *filename; +int howto, tell; +{ + if(tell) + print_bootsel(filename); + + if(exec_netbsd(filename, 0, howto, 0, consdev) < 0) + printf("boot: %s\n", strerror(errno)); + else + printf("boot returned\n"); +} + +static void helpme() +{ + printf("commands are:\n" + "boot [xdNx:][filename] [-adrs]\n" + " (ex. \"sd0a:netbsd.old -s\"\n" + "xd[N[x]]:\n" + "ls [path]\n" + "help|?\n" + "quit\n"); +} + +/* + * chops the head from the arguments and returns the arguments if any, + * or possibly an empty string. + */ +static char * +gettrailer(arg) +char *arg; +{ + char *options; + + if ((options = strchr(arg, ' ')) == NULL) + options = ""; + else + *options++ = '\0'; + /* trim leading blanks */ + while (*options && *options == ' ') + options++; + + return(options); +} + + +static int +parseopts(opts, howto) +char *opts; +int *howto; +{ + int tmpopt = 0; + + opts++; /* skip - */ + while (*opts && *opts != ' ') { + tmpopt |= netbsd_opt(*opts); + if(tmpopt == -1) { + printf("-%c: unknown flag\n", *opts); + helpme(); + return(0); + } + opts++; + } + *howto = tmpopt; + return(1); +} + +static int +parseboot(arg, filename, howto) +char *arg; +char **filename; +int *howto; +{ + char *opts = NULL; + + *filename = 0; + *howto = 0; + + /* if there were no arguments */ + if (!*arg) + return(1); + + /* format is... */ + /*[[xxNx:]filename] [-adrs]*/ + + /* check for just args */ + if (arg[0] == '-'){ + opts = arg; + } else { /* at least a file name */ + *filename = arg; + + opts = gettrailer(arg); + if (!*opts) + opts = NULL; + else if (*opts != '-') { + printf("invalid arguments\n"); + helpme(); + return(0); + } + } + /* at this point, we have dealt with filenames. */ + + /* now, deal with options */ + if (opts) { + if (!parseopts(opts, howto)) + return(0); + } + + return(1); +} + +static void +docommand(arg) +char *arg; +{ + char *options; + + options = gettrailer(arg); + + if ((strcmp("help", arg) == 0) || + (strcmp("?", arg) == 0)) { + helpme(); + return; + } + if (strcmp("ls", arg) == 0){ + char *help = default_filename; + default_filename = "/"; + ls(options); + default_filename = help; + return; + } + if (strcmp("quit", arg) == 0){ + printf("Exiting... goodbye...\n"); + exit(0); + } + if (strcmp("boot", arg) == 0){ + char *filename; + int howto; + if(parseboot(options, &filename, &howto)) + bootit(filename, howto, 1); + return; + } +#ifdef MATTHIAS + if (strchr(arg, ':')) { /* DOS-like(!) change drive */ + static char savedevname[MAXDEVNAME + 1]; + char *fsname, *devname; + const char *file; /* dummy */ + if(!parsebootfile(arg, &fsname, &devname, &default_unit, + &default_partition, &file)) { + /* put to own static storage */ + strncpy(savedevname, devname, MAXDEVNAME + 1); + default_devname = savedevname; + return; + } + } +#endif + printf("unknown command\n"); + helpme(); +} + +void bootmenu() +{ + printf("\ntype \"?\" or \"help\" for help.\n"); + for(;;) { + char input[80]; + + input[0] = '\0'; + printf("> "); + gets(input); + + docommand(input); + } +} + +static int +awaitkey(timeout, tell) +int timeout, tell; +{ + int i; + + i = timeout * POLL_FREQ; + + while (i--) { + if(iskey()) { + /* flush input buffer */ + while(iskey()) + getchar(); + + return(1); + } + delay(1000000 / POLL_FREQ); + if (tell && !(i % POLL_FREQ)) + printf("%d\b", i/POLL_FREQ); + } + if (tell) printf("0\n"); + return(0); +} + +static void +print_banner(void) +{ + printf("\n" + ">> NetBSD BOOT: %d/%d k [%s]\n" +#ifndef MATTHIAS + "use hd1a:netbsd to boot sd0 when wd0 is also installed\n" + "press any key for boot menu\n", +#else + "use hd1a:netbsd to boot sd0 when wd0 is also installed\n", +#endif + getbasemem(), + getextmem(), + version); +} + + +/* + * note: normally, void main() wouldn't be legal, but this isn't a + * hosted environment... + */ +void +main(void) +{ + int currname; + + consdev = initio(CONSDEV_PC); + gateA20(); + + print_banner(); + + /* try to set default device to what BIOS tells us */ + bios2dev(boot_biosdev, &default_devname, &default_unit); + default_partition = 0; + + /* if the user types "boot" without filename */ + default_filename = DEFFILENAME; + + currname = 0; + for(;;) { +#ifndef MATTHIAS + print_bootsel(0); + printf("starting in %d\b", TIMEOUT); + + if(awaitkey(TIMEOUT, 1)) + bootmenu(); /* does not return */ + + /* + * try pairs of names[] entries, foo and foo.gz + */ + /* don't print "booting..." again for first try */ + bootit(names[currname], 0, currname != 0); + /* since it failed, try switching bootfile. */ + currname = ++currname % NUMNAMES; + + /* now try the second of a pair, presumably the .gz + version. */ + /* XXX duped code sucks. */ + /* don't print "booting..." again for first try */ + bootit(names[currname], 0, currname != 0); + /* since it failed, try switching bootfile. */ + currname = ++currname % NUMNAMES; +#else + print_bootsel(0); + printf("press any key for boot menu\n" + "starting in %d\b", TIMEOUT); + + if(awaitkey(TIMEOUT, 1)) + bootmenu(); /* does not return */ + + /* try every names[] entry once */ + do { + /* dont't print "booting..." again for first try */ + bootit(names[currname], 0, currname != 0); + + /* since it failed, try switching bootfile. */ + currname = ++currname % NUMNAMES; + } while(currname); +#endif + } +} diff --git a/sys/arch/i386/stand/biosboot/version.c b/sys/arch/i386/stand/biosboot/version.c new file mode 100644 index 000000000000..5efb03f774ca --- /dev/null +++ b/sys/arch/i386/stand/biosboot/version.c @@ -0,0 +1,65 @@ +/* $NetBSD: version.c,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ */ + +char version[] = "2.0Beta"; + +/* + * NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. + * + * 1.29 -> 2.0 + * Change over to Matthias Drochner's two stage boot + * system. All code is completely new. + * + * 1.28 -> 1.29 + * various code cleanup. (mycroft) + * + * 1.27 -> 1.28 + * fix gets to use real timeout instead of loop and do + * a little cleanup, and add some prototypes. A lot more + * needs to be done here. (perry) + * + * 1.26 -> 1.27 + * size reduction and code cleanup. (mycroft) + * + * 1.25 -> 1.26 + * size reduction and code cleanup. (mycroft) + * + * 1.24 -> 1.25 + * add support for serial consoles. (mycroft) + * + * 1.23 -> 1.24 + * change RCS ID format. NOW NEED TO UPDATE STRING BELOW + * BY HAND. + * + * 1.22 -> 1.23, 1.21.2.2 + * fix problem with empty symbol tables. (mycroft) + * + * 1.21 -> 1.22, 1.21.2.1 + * fix compatibility with pre-4.4 file systems. (mycroft) + * + * 1.20 -> 1.21 + * update for 4.4-Lite file system includes and macros (cgd) + * + * 1.19 -> 1.20 + * display options in std. format, more changes for size (cgd) + * + * 1.18 -> 1.19 + * add a '-r' option, to specify RB_DFLTROOT (cgd) + * + * 1.17 -> 1.18 + * removed some more code we don't need for BDB. (mycroft) + * + * 1.16 -> 1.17 + * removed with prejudice the extra buffer for xread(), changes + * to make the code smaller, and general cleanup. (mycroft) + * + * 1.15 -> 1.16 + * reduce BUFSIZE to 4k, because that's fixed the + * boot problems, for some. (cgd) + * + * 1.14 -> 1.15 + * seperated 'version' out from boot.c (cgd) + * + * 1.1 -> 1.14 + * look in boot.c revision logs + */ + diff --git a/sys/arch/i386/stand/genprom/Makefile b/sys/arch/i386/stand/genprom/Makefile new file mode 100644 index 000000000000..ef7d531bf79e --- /dev/null +++ b/sys/arch/i386/stand/genprom/Makefile @@ -0,0 +1,8 @@ +# $NetBSD: Makefile,v 1.1.1.1 1997/03/14 02:40:30 perry Exp $ + +PROG= genprom +NOMAN= + +CFLAGS+= -Wall + +.include diff --git a/sys/arch/i386/stand/genprom/genprom.c b/sys/arch/i386/stand/genprom/genprom.c new file mode 100644 index 000000000000..7f850aea256e --- /dev/null +++ b/sys/arch/i386/stand/genprom/genprom.c @@ -0,0 +1,59 @@ +/* $NetBSD: genprom.c,v 1.1.1.1 1997/03/14 02:40:30 perry Exp $ */ +/* + * mainly from netbsd:sys/arch/i386/netboot/genprom.c + */ + +/* + * Read a binary image of a bios extension, generate the + * appropriate block count and checksum and write them + * into the rom image (replacing 2nd and 5th bytes) + * The binary image should be sized before being filtered + * through this routine. + */ + +#include +#include +#include + +#define PROM_SIZE 0x10000 /* max */ + +int +main(argc,argv) +int argc; +char **argv; +{ + char w[PROM_SIZE], ck; + int i, sum; + int romsize; + + if(argc>1){ + if(sscanf(argv[1], "%d", &romsize)!=1){ + errx(1, "bad arg"); + } + }else{ + errx(1, "arg: romsize / bytes\n"); + } + + memset(w, 0x0, PROM_SIZE); + i = fread(w, 1, PROM_SIZE, stdin); + + fprintf(stderr, "bios extension size: %d (0x%x), read %d bytes\n", + romsize, romsize, i); + + if(i > romsize) + errx(1, "read longer than expected"); + + w[2] = romsize / 512; + for (sum = 0, i = 0; i < romsize; i++) { + sum += w[i]; + } + w[5] = -sum; + for (ck = 0, i = 0; i < romsize; i++) { + ck += w[i]; + } + if(ck){ + errx(1, "crc???\n"); + } + fwrite(w, 1, romsize , stdout); + return(0); +} diff --git a/sys/arch/i386/stand/libsa/getopt.c b/sys/arch/i386/stand/libsa/getopt.c new file mode 100644 index 000000000000..b751f584c304 --- /dev/null +++ b/sys/arch/i386/stand/libsa/getopt.c @@ -0,0 +1,113 @@ +/* $NetBSD: getopt.c,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ */ + +/* + * Copyright (c) 1987, 1993, 1994 + * 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. + */ + +/* from: netbsd:lib/libc/stdlib/getopt.c */ + +#include +#include "stand.h" + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + printf("illegal option -- %c\n", optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + printf("option requires an argument -- %c\n", + optopt); + return (BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} diff --git a/sys/arch/i386/stand/libsa/ls.c b/sys/arch/i386/stand/libsa/ls.c new file mode 100644 index 000000000000..aaa80aa9ad22 --- /dev/null +++ b/sys/arch/i386/stand/libsa/ls.c @@ -0,0 +1,118 @@ +/* $NetBSD: ls.c,v 1.1.1.1 1997/03/14 02:40:31 perry 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 +#include +#include + +#include "stand.h" + +extern char *strerror __P((int)); /* XXX for now */ + +static char *typestr[] = { + "unknown", + "FIFO", + "CHR", + 0, + "DIR", + 0, + "BLK", + 0, + "REG", + 0, + "LNK", + 0, + "SOCK", + 0, + "WHT" +}; + +void ls(path) +char *path; +{ + int fd; + struct stat sb; + size_t size; + char dirbuf[DIRBLKSIZ]; + + fd = open(path, 0); + if(fd < 0) { + printf("ls: %s\n", strerror(errno)); + return; + } + + if(fstat(fd, &sb) < 0) { + printf("stat: %s\n", strerror(errno)); + goto out; + } + if((sb.st_mode & IFMT) != IFDIR) { + printf("%s: %s\n", path, strerror(ENOTDIR)); + 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) { + char *t; + + if((dp->d_namlen > MAXNAMLEN+1) || + (dp->d_type > sizeof(typestr) / sizeof(char*) - 1) || + !(t = typestr[dp->d_type])){ + /* 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... */ + printf("bad dir entry\n"); + goto out; + } + + printf("%d: %s (%s)\n", dp->d_ino, dp->d_name, t); + } + + dp = (struct direct *)((char *)dp + dp->d_reclen); + } + } +out: + close(fd); +} diff --git a/sys/arch/i386/stand/libsa/nfswrapper.c b/sys/arch/i386/stand/libsa/nfswrapper.c new file mode 100644 index 000000000000..8fc61dd35713 --- /dev/null +++ b/sys/arch/i386/stand/libsa/nfswrapper.c @@ -0,0 +1,72 @@ +/* $NetBSD: nfswrapper.c,v 1.1.1.1 1997/03/14 02:40:31 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. + * + */ + +/* Makes the (filesystem dependant) mount + part of open. Necessary for interoperation with + tftp filesystem on same net device layer. + Assumes: + - socket descriptor (int) at open_file->f_devdata + - server host IP in global rootip + - path to mount in globel rootpath + */ + +#include +#include +#include + +#include "stand.h" +#include "net.h" +#include "nfs.h" + +#include "nfswrapper.h" + +int nfs_mountandopen(path, f) +char *path; +struct open_file *f; +{ + int sock; + + if(!rootpath[0]){ + printf("no rootpath, no nfs\n"); + return(ENXIO); + } + + sock= *(int*)(f->f_devdata); + + if(nfs_mount(sock , rootip, rootpath)){ + printf("mount failed\n"); + return(ENXIO); + } + return(nfs_open(path, f)); +} diff --git a/sys/arch/i386/stand/libsa/nfswrapper.h b/sys/arch/i386/stand/libsa/nfswrapper.h new file mode 100644 index 000000000000..f00f0d9b155a --- /dev/null +++ b/sys/arch/i386/stand/libsa/nfswrapper.h @@ -0,0 +1,43 @@ +/* $NetBSD: nfswrapper.h,v 1.1.1.1 1997/03/14 02:40:31 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. + * + */ + + +int nfs_mountandopen __P((char *path, struct open_file *f)); +int nfs_close __P((struct open_file *f)); +int nfs_read __P((struct open_file *f, void *buf, + size_t size, size_t *resid)); +int nfs_write __P((struct open_file *f, void *buf, + size_t size, size_t *resid)); +off_t nfs_seek __P((struct open_file *f, off_t offset, int where)); +int nfs_stat __P((struct open_file *f, struct stat *sb)); diff --git a/sys/arch/i386/stand/libsa/tftp.c b/sys/arch/i386/stand/libsa/tftp.c new file mode 100644 index 000000000000..762c02703324 --- /dev/null +++ b/sys/arch/i386/stand/libsa/tftp.c @@ -0,0 +1,359 @@ +/* $NetBSD: tftp.c,v 1.1.1.1 1997/03/14 02:40:31 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. + * + */ + +/* Simple TFTP implementation for libsa. + Assumes: + - socket descriptor (int) at open_file->f_devdata + - server host IP in global rootip + Restrictions: + - read only + - lseek only with SEEK_SET or SEEK_CUR + - no big time differences between transfers ( +#include +#include +#include +#include +#include + +#include "stand.h" +#include "net.h" +#include "netif.h" + +#include "tftp.h" + +static int tftpport = 2000; + +#define RSPACE 520 /* max data packet, rounded up */ + +struct tftp_handle{ + struct iodesc *iodesc; + int currblock; /* contents of lastdata */ + int islastblock; /* flag */ + int validsize; + int off; + char *path; /* saved for re-requests */ + struct{ + u_char header[HEADER_SIZE]; + struct tftphdr t; + u_char space[RSPACE]; + }lastdata; +}; + +static int tftperrors[8] = { + 0, /* ??? */ + ENOENT, + EPERM, + ENOSPC, + EINVAL, /* ??? */ + EINVAL, /* ??? */ + EEXIST, + EINVAL /* ??? */ +}; + +static ssize_t recvtftp(d, pkt, len, tleft) +register struct iodesc *d; +register void *pkt; +register ssize_t len; +time_t tleft; +{ + struct tftphdr *t; + + len = readudp(d, pkt, len, tleft); + + if(len < 8) return(-1); + + t = (struct tftphdr *)pkt; + switch(ntohs(t->th_opcode)) { + case DATA: { + int got; + if(htons(t->th_block) != d->xid) { /* expected block? */ + return(-1); + } + if(d->xid == 1){ /* first data packet, from new port */ + register struct udphdr *uh; + uh = (struct udphdr*)pkt - 1; + d->destport = htons(uh->uh_sport); /* XXXXXX in net.c geswappt! */ + } /* else check uh_sport has not changed??? */ + got = len - (t->th_data - (char*)t); + return got; + } + case ERROR: + if((unsigned)ntohs(t->th_code) >= 8) { + printf("illegal tftp error %d\n", ntohs(t->th_code)); + errno = EIO; + } else { +#ifdef DEBUG + printf("tftp-error %d\n", ntohs(t->th_code)); +#endif + errno = tftperrors[ntohs(t->th_code)]; + } + return(-1); + default: +#ifdef DEBUG + printf("tftp type %d not handled\n", ntohs(t->th_opcode)); +#endif + return(-1); + } +} + +/* send request, expect first block (or error) */ +static int tftp_makereq(h) +struct tftp_handle *h; +{ + struct{ + u_char header[HEADER_SIZE]; + struct tftphdr t; + u_char space[FNAME_SIZE+6]; + }wbuf; + char *wtail; + int l; + ssize_t res; + struct tftphdr *t; + + wbuf.t.th_opcode = htons((u_short)RRQ); + wtail = wbuf.t.th_stuff; + l = strlen(h->path); + bcopy(h->path,wtail, l + 1); + wtail += l + 1; + bcopy("octet", wtail, 6); + wtail += 6; + + t= &h->lastdata.t; + +/* h->iodesc->myport = htons(--tftpport); */ + h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff)); + h->iodesc->destport = htons(IPPORT_TFTP); + h->iodesc->xid = 1; /* expected block */ + + res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail-(char*)&wbuf.t, + recvtftp, t, sizeof(*t) + RSPACE); + + if(res == -1) + return(errno); + + h->currblock = 1; + h->validsize = res; + h->islastblock = 0; + if(res < SEGSIZE) h->islastblock = 1; /* very short file */ + return(0); +} + +/* ack block, expect next */ +static int tftp_getnextblock(h) +struct tftp_handle *h; +{ + struct{ + u_char header[HEADER_SIZE]; + struct tftphdr t; + }wbuf; + char *wtail; + int res; + struct tftphdr *t; + + wbuf.t.th_opcode = htons((u_short)ACK); + wtail = (char*)&wbuf.t.th_block; + wbuf.t.th_block = htons((u_short)h->currblock); + wtail += 2; + + t = &h->lastdata.t; + + h->iodesc->xid = h->currblock + 1; /* expected block */ + + res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char*)&wbuf.t, + recvtftp, t, sizeof(*t) + RSPACE); + + if(res == -1) /* 0 is OK! */ + return(errno); + + h->currblock++; + h->validsize = res; + if(res < SEGSIZE) h->islastblock = 1; /* EOF */ + return(0); +} + +int tftp_open(path, f) +char *path; +struct open_file *f; +{ + struct tftp_handle *tftpfile; + struct iodesc *io; + int res; + + tftpfile = (struct tftp_handle*)alloc(sizeof(*tftpfile)); + if(!tftpfile) return(ENOMEM); + + tftpfile->iodesc = io = socktodesc(*(int*)(f->f_devdata)); + io->destip = rootip; + tftpfile->off = 0; + tftpfile->path = path; /* XXXXXXX we hope it's static */ + + res = tftp_makereq(tftpfile, path); + + if(res) { + free(tftpfile, sizeof(*tftpfile)); + return(res); + } + + f->f_fsdata = (void*)tftpfile; + return(0); +} + +int tftp_read(f, addr, size, resid) +struct open_file *f; +void *addr; +size_t size; +size_t *resid; /* out */ +{ + struct tftp_handle *tftpfile; + static int tc = 0; + tftpfile = (struct tftp_handle*)f->f_fsdata; + + while(size > 0){ + int needblock, count; + + if(!(tc++ % 16)) twiddle(); + + needblock = tftpfile->off / SEGSIZE + 1; + + if(tftpfile->currblock > needblock) /* seek backwards */ + tftp_makereq(tftpfile); /* no error check, it worked for open */ + + while(tftpfile->currblock < needblock){ + int res; + + res = tftp_getnextblock(tftpfile); + if(res){ /* no answer */ +#ifdef DEBUG + printf("tftp: read error\n"); +#endif + return(res); + } + if(tftpfile->islastblock) break; + } + + if(tftpfile->currblock == needblock){ + int offinblock, inbuffer; + + offinblock = tftpfile->off % SEGSIZE; + + inbuffer = tftpfile->validsize - offinblock; + if(inbuffer < 0){ +#ifdef DEBUG + printf("tftp: invalid offset %d\n", tftpfile->off); +#endif + return(EINVAL); + } + + count = (size < inbuffer ? size : inbuffer); + bcopy(tftpfile->lastdata.t.th_data + offinblock, addr, count); + + addr += count; + tftpfile->off += count; + size -= count; + + if((tftpfile->islastblock) && (count == inbuffer)) break; /* EOF */ + } else { +#ifdef DEBUG + printf("tftp: block %d not found\n", needblock); +#endif + return(EINVAL); + } + + } + + if(resid) + *resid = size; + return(0); +} + +int tftp_close(f) +struct open_file *f; +{ + struct tftp_handle *tftpfile; + tftpfile = (struct tftp_handle*)f->f_fsdata; + + /* let it time out ... */ + + if(tftpfile) free(tftpfile, sizeof(*tftpfile)); + return(0); +} + +int tftp_write(f, start, size, resid) +struct open_file *f; +void *start; +size_t size; +size_t *resid; /* out */ +{ + return(EROFS); +} + +int tftp_stat(f, sb) +struct open_file *f; +struct stat *sb; +{ + struct tftp_handle *tftpfile; + tftpfile = (struct tftp_handle*)f->f_fsdata; + + sb->st_mode = 0444; + sb->st_nlink = 1; + sb->st_uid = 0; + sb->st_gid = 0; + sb->st_size = -1; + return(0); +} + +off_t tftp_seek(f, offset, where) +struct open_file *f; +off_t offset; +int where; +{ + struct tftp_handle *tftpfile; + tftpfile = (struct tftp_handle*)f->f_fsdata; + + switch (where) { + case SEEK_SET: + tftpfile->off = offset; + break; + case SEEK_CUR: + tftpfile->off += offset; + break; + default: + errno = EOFFSET; + return(-1); + } + return(tftpfile->off); +} diff --git a/sys/arch/i386/stand/libsa/tftp.h b/sys/arch/i386/stand/libsa/tftp.h new file mode 100644 index 000000000000..b22a620fa76d --- /dev/null +++ b/sys/arch/i386/stand/libsa/tftp.h @@ -0,0 +1,45 @@ +/* $NetBSD: tftp.h,v 1.1.1.1 1997/03/14 02:40:31 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. + * + */ + + +int tftp_open __P((char *path, struct open_file *f)); +int tftp_read __P((struct open_file *f, void *addr, + size_t size, size_t *resid)); +int tftp_close __P((struct open_file *f)); +int tftp_write __P((struct open_file *f, void *addr, + size_t size, size_t *resid)); +int tftp_stat __P((struct open_file *f, struct stat *sb)); +off_t tftp_seek __P((struct open_file *f, off_t offset, int where)); + +#define IPPORT_TFTP 69 diff --git a/sys/arch/i386/stand/netboot/Makefile b/sys/arch/i386/stand/netboot/Makefile new file mode 100644 index 000000000000..ff45983ae73b --- /dev/null +++ b/sys/arch/i386/stand/netboot/Makefile @@ -0,0 +1,62 @@ +# $NetBSD: Makefile,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ + +S= ../../../../ + +PROG= netboot +NOMAN= + +SRCS= main.c devopen.c conf.c dev_net.c version.c + +CLEANFILES+= ${ROMSTART} ${PROG}.rom ${PROG}.sym ${PROG}.list + +#CPPFLAGS+= -DCOMPAT_OLDBOOT +#CPPFLAGS+= -DDEBUG +#should go into SAMISCCPPFLAGS after system upgrade +CPPFLAGS+= -DHEAP_START=0x10000 -DHEAP_LIMIT=0x40000 +CPPFLAGS+= -DNFS_NOSYMLINK +#CPPFLAGS+= -DSUPPORT_BOOTP -DSUPPORT_TFTP +CPPFLAGS+= -DSUPPORT_RARP -DSUPPORT_BOOTPARAM -DSUPPORT_NFS + +#CFLAGS= -O2 -fomit-frame-pointer -fno-defer-pop +#needs some cleanup in libsa +#CFLAGS+= -Wall + +# XXX should go into library +.PATH: ${.CURDIR}/../libsa +#SRCS+= tftp.c +SRCS+= nfswrapper.c +CPPFLAGS+= -I${.CURDIR}/../libsa + +${PROG}: ${PROG}.rom + @# do nothing + +install: + ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ + ${PROG}.rom ${DESTDIR}${BINDIR} + +#ROM_SIZE= 16384 +ROM_SIZE= 32768 + +RELOC= 90000 +CPPFLAGS+= -DBOOTROM -DRELOC=0x$(RELOC) + +.PATH: ${.CURDIR}/../lib/netif + +#USE_NETIF= 3c509 +#USE_NETIF= 3c590 +USE_NETIF= pcnet_pci +#USE_NETIF= pcnet_isapnp +#USE_NETIF= wd80x3 + +.include "../lib/netif/Makefile.inc" + +#use SAMISCCPPFLAGS after system upgrade +#SAMISCCPPFLAGS+= -DHEAP_START=0x10000 -DHEAP_LIMIT=0x40000 +#SAMISCCPPFLAGS+= -DNFS_NOSYMLINK +SAMISCMAKEFLAGS= SA_USE_CREAD=yes +#I386MISCCPPFLAGS+= -DDISK_DEBUG +I386MISCMAKEFLAGS= I386_INCLUDE_DISK=no I386_INCLUDE_BUS=yes + +.include "../Makefile.booters" + +conf.o dev_net.o: Makefile diff --git a/sys/arch/i386/stand/netboot/conf.c b/sys/arch/i386/stand/netboot/conf.c new file mode 100644 index 000000000000..f5de6f093343 --- /dev/null +++ b/sys/arch/i386/stand/netboot/conf.c @@ -0,0 +1,59 @@ +/* $NetBSD: conf.c,v 1.1.1.1 1997/03/14 02:40:30 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. + * + */ + + +#include +#include + +#include + +#include "dev_net.h" + +#include +#include + +struct devsw devsw[] = { + { "net", net_strategy, net_open, net_close, net_ioctl }, +}; +int ndevs = sizeof(devsw)/sizeof(struct devsw); + +struct fs_ops file_system[] = { +#ifdef SUPPORT_NFS + { nfs_mountandopen, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat }, +#endif +#ifdef SUPPORT_TFTP + { tftp_open, tftp_close, tftp_read, tftp_write, tftp_seek, tftp_stat }, +#endif +}; +int nfsys = sizeof(file_system)/sizeof(struct fs_ops); diff --git a/sys/arch/i386/stand/netboot/dev_net.c b/sys/arch/i386/stand/netboot/dev_net.c new file mode 100644 index 000000000000..00c18fa7aa7c --- /dev/null +++ b/sys/arch/i386/stand/netboot/dev_net.c @@ -0,0 +1,194 @@ +/* $NetBSD: dev_net.c,v 1.1.1.1 1997/03/14 02:40:30 perry Exp $ */ + +/* + * Copyright (c) 1995 Gordon W. Ross + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 4. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Gordon W. Ross + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* network device for libsa + supports BOOTP, RARP and BOOTPARAM + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#ifdef SUPPORT_BOOTP +void bootp __P((int)); +#endif + +struct in_addr myip; /* init'ed as INADDR_ANY */ +struct in_addr rootip, gateip, swapip, nameip; +n_long netmask; + +char rootpath[FNAME_SIZE]; +char bootfile[FNAME_SIZE]; + +char hostname[FNAME_SIZE]; /* our hostname */ +int hostnamelen; + +#if defined(SUPPORT_BOOTP) || defined (SUPPORT_BOOTPARAM) +char domainname[FNAME_SIZE]; /* our DNS domain, not used */ +int domainnamelen; +#endif + +u_char bcea[6] = BA; + +static int netdev_sock; +static int open_count; + +int no_bootp = 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. + */ +int +net_open(f, devname) +struct open_file *f; +char *devname; /* Device part of file name (or NULL). */ +{ + int error = 0; + /* On first open, do netif open */ + if (open_count == 0) { + + /* Find network interface. */ + if ((netdev_sock = netif_open(devname)) < 0) + return (ENXIO); + +#ifdef SUPPORT_BOOTP + if(!no_bootp){ + printf("configure network...trying bootp\n"); + /* Get boot info using BOOTP way. (RFC951, RFC1048) */ + bootp(netdev_sock); + } +#endif + + if(myip.s_addr != INADDR_ANY){ /* got bootp reply or manually set*/ + +#ifdef TFTP_HACK + int num, i; + /* XXX (some) tftp servers don't like leading "/" */ + for(num = 0; bootfile[num] == '/'; num++); + for(i=0; bootfile[i] = bootfile[i + num]; i++); +#endif + + printf("boot: client IP address: %s\n", inet_ntoa(myip)); + printf("boot: client name: %s\n", hostname); + } else { + +#ifdef SUPPORT_RARP + /* no answer, + Get boot info using RARP and Sun bootparams. */ + printf("configure network...trying rarp\n"); + + /* Get our IP address. (rarp.c) */ + if (rarp_getipaddress(netdev_sock)){ + error=EIO; + goto bad; + } + printf("boot: client IP address: %s\n", inet_ntoa(myip)); + +#ifdef SUPPORT_BOOTPARAM + /* Get our hostname, server IP address. */ + if (!bp_whoami(netdev_sock)){ + printf("boot: client name: %s\n", hostname); + + /* Get the root pathname. */ + bp_getfile(netdev_sock, "root", &rootip, rootpath); + } +#else + /* else + fallback: use rarp server address */ +#endif + +#else /* no SUPPORT_RARP */ + error=EIO; + goto bad; +#endif + + } + printf("boot: server: %s, rootpath: %s, bootfile: %s\n", + inet_ntoa(rootip), rootpath, bootfile); + } + open_count++; + f->f_devdata = &netdev_sock; + return (error); + + bad: + printf("net_open failed\n"); + netif_close(netdev_sock); + return(error); +} + +int +net_close(f) +struct open_file *f; +{ + /* On last close, do netif close, etc. */ + if (--open_count == 0) + netif_close(netdev_sock); +#ifdef DEBUG + if(open_count < 0) panic("net_close"); +#endif + f->f_devdata = NULL; + + return(0); +} + +int +net_ioctl(f, c, d) +struct open_file *f; +u_long c; +void *d; +{ + return EIO; +} + +int +net_strategy(d, f, b, s, buf, r) +void *d; +int f; +daddr_t b; +size_t s; +void *buf; +size_t *r; +{ + return EIO; +} diff --git a/sys/arch/i386/stand/netboot/dev_net.h b/sys/arch/i386/stand/netboot/dev_net.h new file mode 100644 index 000000000000..1d134402ef76 --- /dev/null +++ b/sys/arch/i386/stand/netboot/dev_net.h @@ -0,0 +1,39 @@ +/* $NetBSD: dev_net.h,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ */ + +/* + * Copyright (c) 1995 Gordon W. Ross + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 4. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Gordon W. Ross + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +int net_open __P((struct open_file*, ...)); +int net_close __P((struct open_file*)); +int net_ioctl __P((struct open_file*, u_long, void*)); +int net_strategy __P((void*, int, daddr_t, size_t, void*, size_t*)); diff --git a/sys/arch/i386/stand/netboot/devopen.c b/sys/arch/i386/stand/netboot/devopen.c new file mode 100644 index 000000000000..b1ab8a51981d --- /dev/null +++ b/sys/arch/i386/stand/netboot/devopen.c @@ -0,0 +1,66 @@ +/* $NetBSD: devopen.c,v 1.1.1.1 1997/03/14 02:40:31 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. + * + */ + +/* bootfile from tftp overrides! + TODO: pass (net) device to net_open + */ + +#include +#include +#include + +#include +#include /* global "bootfile" */ + +int +devopen(f, fname, file) +struct open_file *f; +const char *fname; +char **file; +{ + struct devsw *dp; + int error=0; + + dp = &devsw[0]; + f->f_dev = dp; + + error = (*dp->dv_open)(f, 0); + + if(bootfile[0]) + *file = bootfile; + else + *file = (char*)fname; + + return (error); +} diff --git a/sys/arch/i386/stand/netboot/main.c b/sys/arch/i386/stand/netboot/main.c new file mode 100644 index 000000000000..af19ae8062ba --- /dev/null +++ b/sys/arch/i386/stand/netboot/main.c @@ -0,0 +1,281 @@ +/* $NetBSD: main.c,v 1.1.1.1 1997/03/14 02:40:31 perry 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. + * + */ + + +#include + +#include + +#include + +extern char *strerror __P((int)); /* XXX missing in stand.h */ + +int errno; +static char *consdev; + +extern char version[]; +extern char etherdev[]; + +#ifdef SUPPORT_NFS /* XXX */ +int debug = 0; +#endif + +#define TIMEOUT 5 +#define POLL_FREQ 10 + +#define MAXBOOTFILE 20 + +#ifdef COMPAT_OLDBOOT +int +parsebootfile(fname, fsname, devname, unit, partition, file) +const char *fname; +char **fsname; /* out */ +char **devname; /* out */ +unsigned int *unit, *partition; /* out */ +const char **file; /* out */ +{ + return(EINVAL); +} + +int biosdisk_gettype(f) +struct open_file *f; +{ + return(0); +} +#endif + +int bootit(filename, howto) +const char *filename; +int howto; +{ + if(exec_netbsd(filename, 0, howto, etherdev, "pc") < 0) + printf("boot: %s\n", strerror(errno)); + else + printf("boot returned\n"); + return(-1); +} + +static void helpme() +{ + printf("commands are:\n" + "boot [filename] [-adrs]\n" + " (ex. \"netbsd.old -s\"\n" + "help|?\n" + "quit\n"); +} + +/* + * chops the head from the arguments and returns the arguments if any, + * or possibly an empty string. + */ +static char * +gettrailer(arg) +char *arg; +{ + char *options; + + if ((options = strchr(arg, ' ')) == NULL) + options = ""; + else + *options++ = '\0'; + /* trim leading blanks */ + while (*options && *options == ' ') + options++; + + return(options); +} + +static int +parseopts(opts, howto) +char *opts; +int *howto; +{ + int tmpopt = 0; + + opts++; /* skip - */ + while (*opts && *opts != ' ') { + tmpopt |= netbsd_opt(*opts); + if(tmpopt == -1) { + printf("-%c: unknown flag\n", *opts); + helpme(); + return(0); + } + opts++; + } + *howto = tmpopt; + return(1); +} + +static int +parseboot(arg, filename, howto) +char *arg; +char **filename; +int *howto; +{ + char *opts = NULL; + + *filename = 0; + *howto = 0; + + /* if there were no arguments */ + if (!*arg) + return(1); + + /* format is... */ + /*[[xxNx:]filename] [-adrs]*/ + + /* check for just args */ + if (arg[0] == '-'){ + opts = arg; + } else { /* at least a file name */ + *filename = arg; + + opts = gettrailer(arg); + if (!*opts) + opts = NULL; + else if (*opts != '-') { + printf("invalid arguments\n"); + helpme(); + return(0); + } + } + /* at this point, we have dealt with filenames. */ + + /* now, deal with options */ + if (opts) { + if (!parseopts(opts, howto)) + return(0); + } + + return(1); +} + +static void +docommand(arg) +char *arg; +{ + char *options; + + options = gettrailer(arg); + + if ((strcmp("help", arg) == 0) || + (strcmp("?", arg) == 0)) { + helpme(); + return; + } + if (strcmp("quit", arg) == 0){ + printf("Exiting... goodbye...\n"); + exit(0); + } + if (strcmp("boot", arg) == 0){ + char *filename; + int howto; + if(parseboot(options, &filename, &howto)) + bootit(filename, howto); + return; + } + printf("unknown command\n"); + helpme(); +} + +void bootmenu() +{ + printf("\ntype \"?\" or \"help\" for help.\n"); + for(;;) { + char input[80]; + + input[0] = '\0'; + printf("> "); + gets(input); + + docommand(input); + } +} + +static int +awaitkey(void) +{ + int i; + + i = TIMEOUT * POLL_FREQ; + + while (i--) { + if(iskey()) { + /* flush input buffer */ + while(iskey()) + getchar(); + + return(1); + } + delay(1000000 / POLL_FREQ); + if (!(i % POLL_FREQ)) + printf("%d\b", i/POLL_FREQ); + } + printf("0\n"); + return(0); +} + +static void +print_banner(void) +{ + printf("\n" + ">> NetBSD BOOT: %d/%d k [%s]\n", + getbasemem(), + getextmem(), + version); +} + +int +main() +{ + consdev = initio(CONSDEV_AUTO); + gateA20(); + + print_banner(); + + printf("press any key for boot menu\n" + "starting in %d\b", TIMEOUT); + + if(awaitkey()) + bootmenu(); /* does not return */ + + bootit("netbsd", 0); + + /* if that fails, let BIOS look for boot device */ + return(1); +} diff --git a/sys/arch/i386/stand/netboot/version.c b/sys/arch/i386/stand/netboot/version.c new file mode 100644 index 000000000000..b2064501645f --- /dev/null +++ b/sys/arch/i386/stand/netboot/version.c @@ -0,0 +1,3 @@ +/* $NetBSD: version.c,v 1.1.1.1 1997/03/14 02:40:30 perry Exp $ */ + +char version[] = "1.0Beta";