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