141069Swilliam /*- 241069Swilliam * Copyright (c) 1990 The Regents of the University of California. 341069Swilliam * All rights reserved. 441069Swilliam * 541069Swilliam * This code is derived from software contributed to Berkeley by 641069Swilliam * William Jolitz. 741069Swilliam * 8*48813Swilliam * %sccs.include.redist.c% 941069Swilliam * 10*48813Swilliam * @(#)bootxx.c 7.2 (Berkeley) 04/28/91 1141069Swilliam */ 1241069Swilliam 13*48813Swilliam #include "param.h" 1441069Swilliam #include <a.out.h> 1541069Swilliam #include "saio.h" 16*48813Swilliam #include "reboot.h" 17*48813Swilliam #include "disklabel.h" 1841069Swilliam 19*48813Swilliam char *bootprog = "/boot"; 20*48813Swilliam extern int opendev, bootdev, cyloffset; 21*48813Swilliam extern struct disklabel disklabel; 22*48813Swilliam 2341069Swilliam /* 24*48813Swilliam * Boot program... loads /boot out of filesystem indicated by arguements. 25*48813Swilliam * We assume an autoboot unless we detect a misconfiguration. 2641069Swilliam */ 2741069Swilliam 28*48813Swilliam main(dev, unit, off) 2941069Swilliam { 30*48813Swilliam register struct disklabel *lp; 31*48813Swilliam register int io, partition, howto; 3241069Swilliam 3341069Swilliam 3441069Swilliam /* are we a disk, if so look at disklabel and do things */ 35*48813Swilliam lp = &disklabel; 36*48813Swilliam if (lp->d_magic == DISKMAGIC) { 3741069Swilliam /* 38*48813Swilliam * Synthesize bootdev from dev, unit, type and partition 39*48813Swilliam * information from the block 0 bootstrap. 40*48813Swilliam * It's dirty work, but someone's got to do it. 41*48813Swilliam * This will be used by the filesystem primatives, and 42*48813Swilliam * drivers. Ultimately, opendev will be created corresponding 43*48813Swilliam * to which drive to pass to top level bootstrap. 4441069Swilliam */ 4541069Swilliam for (io = 0; io < 8; io++) 46*48813Swilliam #ifdef notyetSCSI 47*48813Swilliam if (lp->d_type == DTYPE_SCSI) { 48*48813Swilliam if (lp->d_partitions[io].p_offset == off) 4941069Swilliam break; 50*48813Swilliam } else 51*48813Swilliam #endif 52*48813Swilliam if (lp->d_partitions[io].p_offset == off*lp->d_secpercyl) 5341069Swilliam break; 54*48813Swilliam 55*48813Swilliam if (io == 8) goto screwed; 56*48813Swilliam cyloffset = off; 57*48813Swilliam } else { 58*48813Swilliam screwed: 59*48813Swilliam /* probably a bad or non-existant disklabel */ 60*48813Swilliam io = 0 ; 61*48813Swilliam howto |= RB_SINGLE|RB_ASKNAME ; 62*48813Swilliam } 63*48813Swilliam 64*48813Swilliam /* construct bootdev */ 65*48813Swilliam /* currently, PC has no way of booting off alternate controllers */ 66*48813Swilliam bootdev = MAKEBOOTDEV(/*i_dev*/ dev, /*i_adapt*/0, /*i_ctlr*/0, 67*48813Swilliam unit, /*i_part*/io); 68*48813Swilliam 6941069Swilliam printf("loading %s\n", bootprog); 7041069Swilliam io = open(bootprog, 0); 7141069Swilliam if (io >= 0) 72*48813Swilliam copyunix(io, howto); 7341069Swilliam _stop("boot failed\n"); 7441069Swilliam } 7541069Swilliam 7641069Swilliam /*ARGSUSED*/ 77*48813Swilliam copyunix(io, howto) 7841069Swilliam register io; 7941069Swilliam { 8041069Swilliam struct exec x; 8141069Swilliam register int i; 8241069Swilliam char *addr; 8341069Swilliam 8441069Swilliam i = read(io, (char *)&x, sizeof x); 8541069Swilliam if (i != sizeof x || 8641069Swilliam (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 8741069Swilliam _stop("Bad format\n"); 88*48813Swilliam 8941069Swilliam if ((x.a_magic == 0413 || x.a_magic == 0410) && 9041069Swilliam lseek(io, 0x400, 0) == -1) 9141069Swilliam goto shread; 92*48813Swilliam 9341069Swilliam if (read(io, (char *)0, x.a_text) != x.a_text) 9441069Swilliam goto shread; 95*48813Swilliam 9641069Swilliam addr = (char *)x.a_text; 9741069Swilliam if (x.a_magic == 0413 || x.a_magic == 0410) 9841069Swilliam while ((int)addr & CLOFSET) 9941069Swilliam *addr++ = 0; 100*48813Swilliam 10141069Swilliam if (read(io, addr, x.a_data) != x.a_data) 10241069Swilliam goto shread; 103*48813Swilliam 10441069Swilliam addr += x.a_data; 10541069Swilliam for (i = 0; i < x.a_bss; i++) 10641069Swilliam *addr++ = 0; 107*48813Swilliam 108*48813Swilliam (*((int (*)()) x.a_entry))(howto, opendev, cyloffset); 10941069Swilliam return; 11041069Swilliam shread: 11141069Swilliam _stop("Short read\n"); 11241069Swilliam } 113