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 * 848813Swilliam * %sccs.include.redist.c% 941069Swilliam * 10*56514Sbostic * @(#)bootxx.c 7.3 (Berkeley) 10/11/92 1141069Swilliam */ 1241069Swilliam 13*56514Sbostic #include <sys/param.h> 14*56514Sbostic #include <sys/reboot.h> 15*56514Sbostic #include <sys/disklabel.h> 16*56514Sbostic 1741069Swilliam #include <a.out.h> 18*56514Sbostic #include <stand/saio.h> 1941069Swilliam 2048813Swilliam char *bootprog = "/boot"; 2148813Swilliam extern int opendev, bootdev, cyloffset; 2248813Swilliam extern struct disklabel disklabel; 2348813Swilliam 2441069Swilliam /* 2548813Swilliam * Boot program... loads /boot out of filesystem indicated by arguements. 2648813Swilliam * We assume an autoboot unless we detect a misconfiguration. 2741069Swilliam */ 2841069Swilliam 2948813Swilliam main(dev, unit, off) 3041069Swilliam { 3148813Swilliam register struct disklabel *lp; 3248813Swilliam register int io, partition, howto; 3341069Swilliam 3441069Swilliam 3541069Swilliam /* are we a disk, if so look at disklabel and do things */ 3648813Swilliam lp = &disklabel; 3748813Swilliam if (lp->d_magic == DISKMAGIC) { 3841069Swilliam /* 3948813Swilliam * Synthesize bootdev from dev, unit, type and partition 4048813Swilliam * information from the block 0 bootstrap. 4148813Swilliam * It's dirty work, but someone's got to do it. 4248813Swilliam * This will be used by the filesystem primatives, and 4348813Swilliam * drivers. Ultimately, opendev will be created corresponding 4448813Swilliam * to which drive to pass to top level bootstrap. 4541069Swilliam */ 4641069Swilliam for (io = 0; io < 8; io++) 4748813Swilliam #ifdef notyetSCSI 4848813Swilliam if (lp->d_type == DTYPE_SCSI) { 4948813Swilliam if (lp->d_partitions[io].p_offset == off) 5041069Swilliam break; 5148813Swilliam } else 5248813Swilliam #endif 5348813Swilliam if (lp->d_partitions[io].p_offset == off*lp->d_secpercyl) 5441069Swilliam break; 5548813Swilliam 5648813Swilliam if (io == 8) goto screwed; 5748813Swilliam cyloffset = off; 5848813Swilliam } else { 5948813Swilliam screwed: 6048813Swilliam /* probably a bad or non-existant disklabel */ 6148813Swilliam io = 0 ; 6248813Swilliam howto |= RB_SINGLE|RB_ASKNAME ; 6348813Swilliam } 6448813Swilliam 6548813Swilliam /* construct bootdev */ 6648813Swilliam /* currently, PC has no way of booting off alternate controllers */ 6748813Swilliam bootdev = MAKEBOOTDEV(/*i_dev*/ dev, /*i_adapt*/0, /*i_ctlr*/0, 6848813Swilliam unit, /*i_part*/io); 6948813Swilliam 7041069Swilliam printf("loading %s\n", bootprog); 7141069Swilliam io = open(bootprog, 0); 7241069Swilliam if (io >= 0) 7348813Swilliam copyunix(io, howto); 7441069Swilliam _stop("boot failed\n"); 7541069Swilliam } 7641069Swilliam 7741069Swilliam /*ARGSUSED*/ 7848813Swilliam copyunix(io, howto) 7941069Swilliam register io; 8041069Swilliam { 8141069Swilliam struct exec x; 8241069Swilliam register int i; 8341069Swilliam char *addr; 8441069Swilliam 8541069Swilliam i = read(io, (char *)&x, sizeof x); 8641069Swilliam if (i != sizeof x || 8741069Swilliam (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 8841069Swilliam _stop("Bad format\n"); 8948813Swilliam 9041069Swilliam if ((x.a_magic == 0413 || x.a_magic == 0410) && 9141069Swilliam lseek(io, 0x400, 0) == -1) 9241069Swilliam goto shread; 9348813Swilliam 9441069Swilliam if (read(io, (char *)0, x.a_text) != x.a_text) 9541069Swilliam goto shread; 9648813Swilliam 9741069Swilliam addr = (char *)x.a_text; 9841069Swilliam if (x.a_magic == 0413 || x.a_magic == 0410) 9941069Swilliam while ((int)addr & CLOFSET) 10041069Swilliam *addr++ = 0; 10148813Swilliam 10241069Swilliam if (read(io, addr, x.a_data) != x.a_data) 10341069Swilliam goto shread; 10448813Swilliam 10541069Swilliam addr += x.a_data; 10641069Swilliam for (i = 0; i < x.a_bss; i++) 10741069Swilliam *addr++ = 0; 10848813Swilliam 10948813Swilliam (*((int (*)()) x.a_entry))(howto, opendev, cyloffset); 11041069Swilliam return; 11141069Swilliam shread: 11241069Swilliam _stop("Short read\n"); 11341069Swilliam } 114