--- Net2/arch/i386/stand/boot.c 2018/04/24 18:04:01 1.1 +++ Net2/arch/i386/stand/boot.c 2018/04/24 18:20:27 1.1.1.4 @@ -34,127 +34,176 @@ * SUCH DAMAGE. */ -#ifndef lint +#ifdef lint char copyright[] = "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ All rights reserved.\n"; #endif /* not lint */ -#ifndef lint -static char sccsid[] = "@(#)boot.c 7.3 (Berkeley) 5/4/91"; +#ifdef lint +/* from: static char sccsid[] = "@(#)boot.c 7.3 (Berkeley) 5/4/91"; */ +static char rcsid[] = "boot.c,v 1.4 1993/05/22 08:02:09 cgd Exp"; #endif /* not lint */ #include "param.h" #include "reboot.h" #include -#include #include "saio.h" +#include "disklabel.h" +#include "dinode.h" /* - * Boot program... arguments from lower-level bootstrap determine - * whether boot stops to ask for system name and which device - * boot comes from. + * Boot program, loaded by boot block from remaing 7.5K of boot area. + * Sifts through disklabel and attempts to load an program image of + * a standalone program off the disk. If keyboard is hit during load, + * or if an error is encounter, try alternate files. */ -char line[100] = UNIX; -extern int opendev, bootdev, cyloffset; +char *files[] = { "netbsd", "onetbsd", "netbsd.old", + "386bsd", "o386bsd", "386bsd.old", + "vmunix", "ovmunix", "vmunix.old", + "boot", 0}; int retry = 0; -extern jmp_buf exception; +extern struct disklabel disklabel; +extern int bootdev, cyloffset; +static unsigned char *biosparams = (char *) 0x9ff00; /* XXX */ -main(howto, dev, off) -{ - int io; +/* + * Boot program... loads /boot out of filesystem indicated by arguements. + * We assume an autoboot unless we detect a misconfiguration. + */ - if((dev&B_MAGICMASK) == B_DEVMAGIC) { - bootdev = dev; - cyloffset = off; - } else goto again; - - if(_setjmp(exception)) { - close(io); - printf("- load aborted\n"); -again: - howto = RB_SINGLE|RB_ASKNAME; - cyloffset = 0; +main(dev, unit, off) +{ + register struct disklabel *lp; + register int io; + register char **bootfile = files; + int howto = 0; + extern int scsisn; /* XXX */ + + + /* are we a disk, if so look at disklabel and do things */ + lp = &disklabel; + if (lp->d_type == DTYPE_SCSI) /* XXX */ + off = htonl(scsisn); /* XXX */ + +/*printf("cyl %x %x hd %x sect %x ", biosparams[0], biosparams[1], biosparams[2], biosparams[0xe]); + printf("dev %x unit %x off %d\n", dev, unit, off);*/ + + if (lp->d_magic == DISKMAGIC) { + /* + * Synthesize bootdev from dev, unit, type and partition + * information from the block 0 bootstrap. + * It's dirty work, but someone's got to do it. + * This will be used by the filesystem primatives, and + * drivers. Ultimately, opendev will be created corresponding + * to which drive to pass to top level bootstrap. + */ + for (io = 0; io < lp->d_npartitions; io++) { + int sn; + + if (lp->d_partitions[io].p_size == 0) + continue; + if (lp->d_type == DTYPE_SCSI) + sn = off; + else + sn = off * lp->d_secpercyl; + if (lp->d_partitions[io].p_offset == sn) + break; + } + + if (io == lp->d_npartitions) goto screwed; + cyloffset = off; + } else { +screwed: + /* probably a bad or non-existant disklabel */ + io = 0 ; + howto |= RB_SINGLE|RB_ASKNAME ; } - - for (;;) { - if (howto & RB_ASKNAME) { - char *cp; - printf("Boot: "); - gets(line); + /* construct bootdev */ + /* currently, PC has no way of booting off alternate controllers */ + bootdev = MAKEBOOTDEV(/*i_dev*/ dev, /*i_adapt*/0, /*i_ctlr*/0, + unit, /*i_part*/io); - /* process additional flags if any */ - if(cp = (char *)index(line, ' ')) { - howto = strtol (cp, 0, 0); - *cp = '\0'; - } - cyloffset = 0; + for (;;) { + +/*printf("namei %s", *bootfile);*/ + io = namei(*bootfile); + if (io > 2) { + copyunix(io, howto, off); } else - printf("Boot: %s\n", line); + printf("File not found"); - if (line[0] == 0) { - strcpy(line, UNIX); - printf("Boot: %s\n", line); - } - - io = open(line, 0); - if (io >= 0) { - copyunix(io, howto); - goto again; - } else if (++retry > 2) - goto again; + printf(" - didn't load %s, ",*bootfile); + if(*++bootfile == 0) bootfile = files; + printf("will try %s\n", *bootfile); + + wait(1<<((retry++) + 10)); } } /*ARGSUSED*/ -copyunix(io, howto) +copyunix(io, howto, cyloff) register io; { struct exec x; int i; char *addr,c; + struct dinode fil; + int off; - i = read(io, (char *)&x, sizeof x); - if (i != sizeof x || - (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) { - printf("Bad format\n"); + fetchi(io, &fil); +/*printf("mode %o ", fil.di_mode);*/ + i = iread(&fil, 0, (char *)&x, sizeof x); + off = sizeof x; + if (i != sizeof x || x.a_magic != 0413) { + printf("Not an executable format"); return; } - printf("%d", x.a_text); - if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) - goto shread; - if (read(io, (char *)0, x.a_text) != x.a_text) + if (roundup(x.a_text, 4096) + x.a_data + x.a_bss > (unsigned)&fil) { + printf("File too big to load"); + return; + } + + off = 4096; + if (iread(&fil, off, (char *)0, x.a_text) != x.a_text) goto shread; + off += x.a_text; addr = (char *)x.a_text; - if (x.a_magic == 0413 || x.a_magic == 0410) - while ((int)addr & CLOFSET) - *addr++ = 0; - printf("+%d", x.a_data); - if (read(io, addr, x.a_data) != x.a_data) + while ((int)addr & CLOFSET) + *addr++ = 0; + + if (iread(&fil, off, addr, x.a_data) != x.a_data) goto shread; addr += x.a_data; - printf("+%d", x.a_bss); - x.a_bss += 128*512; /* slop */ - for (i = 0; i < x.a_bss; i++) - *addr++ = 0; + + if (addr + x.a_bss > (unsigned) &fil) { + printf("Warning: bss overlaps bootstrap"); + x.a_bss = (unsigned)addr - (unsigned)&fil; + } + bzero(addr, x.a_bss); /* mask high order bits corresponding to relocated system base */ - x.a_entry &= 0xfff00000; - printf(" start 0x%x\n", x.a_entry); + x.a_entry &= ~0xfff00000; - if(c=scankbd()) - _longjmp(&exception,1); + /*if (scankbd()) { + printf("Operator abort"); + kbdreset(); + return; + }*/ - i = (*((int (*)()) x.a_entry))(howto, opendev, 0, cyloffset); + /* howto, bootdev, cyl */ + /*printf("entry %x [%x] ", x.a_entry, *(int *) x.a_entry);*/ + bcopy(0x9ff00, 0x300, 0x20); /* XXX */ + i = (*((int (*)()) x.a_entry))(howto, bootdev, off); - if (i) printf("exit %d\n", i) ; + if (i) printf("Program exits with %d", i) ; return; shread: - printf("Short read\n"); + printf("Read of file is incomplete"); return; }