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