1 /*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)bootxx.c 8.1 (Berkeley) 06/11/93 11 */ 12 13 #include <sys/param.h> 14 #include <sys/reboot.h> 15 #include <sys/disklabel.h> 16 17 #include <a.out.h> 18 #include <stand/saio.h> 19 20 char *bootprog = "/boot"; 21 extern int opendev, bootdev, cyloffset; 22 extern struct disklabel disklabel; 23 24 /* 25 * Boot program... loads /boot out of filesystem indicated by arguements. 26 * We assume an autoboot unless we detect a misconfiguration. 27 */ 28 29 main(dev, unit, off) 30 { 31 register struct disklabel *lp; 32 register int io, partition, howto; 33 34 35 /* are we a disk, if so look at disklabel and do things */ 36 lp = &disklabel; 37 if (lp->d_magic == DISKMAGIC) { 38 /* 39 * Synthesize bootdev from dev, unit, type and partition 40 * information from the block 0 bootstrap. 41 * It's dirty work, but someone's got to do it. 42 * This will be used by the filesystem primatives, and 43 * drivers. Ultimately, opendev will be created corresponding 44 * to which drive to pass to top level bootstrap. 45 */ 46 for (io = 0; io < 8; io++) 47 #ifdef notyetSCSI 48 if (lp->d_type == DTYPE_SCSI) { 49 if (lp->d_partitions[io].p_offset == off) 50 break; 51 } else 52 #endif 53 if (lp->d_partitions[io].p_offset == off*lp->d_secpercyl) 54 break; 55 56 if (io == 8) goto screwed; 57 cyloffset = off; 58 } else { 59 screwed: 60 /* probably a bad or non-existant disklabel */ 61 io = 0 ; 62 howto |= RB_SINGLE|RB_ASKNAME ; 63 } 64 65 /* construct bootdev */ 66 /* currently, PC has no way of booting off alternate controllers */ 67 bootdev = MAKEBOOTDEV(/*i_dev*/ dev, /*i_adapt*/0, /*i_ctlr*/0, 68 unit, /*i_part*/io); 69 70 printf("loading %s\n", bootprog); 71 io = open(bootprog, 0); 72 if (io >= 0) 73 copyunix(io, howto); 74 _stop("boot failed\n"); 75 } 76 77 /*ARGSUSED*/ 78 copyunix(io, howto) 79 register io; 80 { 81 struct exec x; 82 register int i; 83 char *addr; 84 85 i = read(io, (char *)&x, sizeof x); 86 if (i != sizeof x || 87 (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 88 _stop("Bad format\n"); 89 90 if ((x.a_magic == 0413 || x.a_magic == 0410) && 91 lseek(io, 0x400, 0) == -1) 92 goto shread; 93 94 if (read(io, (char *)0, x.a_text) != x.a_text) 95 goto shread; 96 97 addr = (char *)x.a_text; 98 if (x.a_magic == 0413 || x.a_magic == 0410) 99 while ((int)addr & CLOFSET) 100 *addr++ = 0; 101 102 if (read(io, addr, x.a_data) != x.a_data) 103 goto shread; 104 105 addr += x.a_data; 106 for (i = 0; i < x.a_bss; i++) 107 *addr++ = 0; 108 109 (*((int (*)()) x.a_entry))(howto, opendev, cyloffset); 110 return; 111 shread: 112 _stop("Short read\n"); 113 } 114