xref: /original-bsd/sys/i386/stand/bootxx.c (revision 11cb310b)
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