xref: /csrg-svn/sys/i386/stand/bootxx.c (revision 41069)
1*41069Swilliam /*-
2*41069Swilliam  * Copyright (c) 1990 The Regents of the University of California.
3*41069Swilliam  * All rights reserved.
4*41069Swilliam  *
5*41069Swilliam  * This code is derived from software contributed to Berkeley by
6*41069Swilliam  * William Jolitz.
7*41069Swilliam  *
8*41069Swilliam  * %sccs.include.noredist.c%
9*41069Swilliam  *
10*41069Swilliam  *	@(#)bootxx.c	7.1 (Berkeley) 04/24/90
11*41069Swilliam  */
12*41069Swilliam 
13*41069Swilliam #include "../h/param.h"
14*41069Swilliam #include "../h/inode.h"
15*41069Swilliam #include "../h/fs.h"
16*41069Swilliam #include <a.out.h>
17*41069Swilliam #include "saio.h"
18*41069Swilliam #include "../h/reboot.h"
19*41069Swilliam #include "../h/dir.h"
20*41069Swilliam #include "../h/disk.h"
21*41069Swilliam #include "devvm.h"
22*41069Swilliam 
23*41069Swilliam extern	int howto, bootdev, unit, cyloffset, boottype;
24*41069Swilliam extern char bootprog[] ;
25*41069Swilliam /*
26*41069Swilliam  * Boot program... arguments passed in r10 and r11
27*41069Swilliam  * are passed through to the full boot program.
28*41069Swilliam  */
29*41069Swilliam 
30*41069Swilliam main()
31*41069Swilliam {
32*41069Swilliam 	register int io, partition; register char *bp ;
33*41069Swilliam 
34*41069Swilliam #ifdef lint
35*41069Swilliam 	howto = 0; devtype = 0;
36*41069Swilliam #endif
37*41069Swilliam 	extern struct disklabel disklabel;
38*41069Swilliam 
39*41069Swilliam 	/* are we a disk, if so look at disklabel and do things */
40*41069Swilliam 	if (bootdev == 0 || bootdev == 3) {
41*41069Swilliam 	    /*
42*41069Swilliam 	     * Synthesize bootdev from unit, type and partition
43*41069Swilliam 	     * from the ROM monitor.
44*41069Swilliam 	     * It's dirty work, but someone's got to do it, and
45*41069Swilliam 	     * we always seem to get it.
46*41069Swilliam 	     */
47*41069Swilliam 	    for (io = 0; io < 8; io++)
48*41069Swilliam 		if (bootdev > 0) { /* XXX should check dk_type == DTYPE_SCSI */
49*41069Swilliam 			if (disklabel.dk_partition[io].cyloff
50*41069Swilliam 				== cyloffset * disklabel.dk_secpercyl)
51*41069Swilliam 				break;
52*41069Swilliam 		} else {
53*41069Swilliam 
54*41069Swilliam 			if (disklabel.dk_partition[io].cyloff == cyloffset)
55*41069Swilliam 			break;
56*41069Swilliam 		}
57*41069Swilliam 	    if (io == 8) io = 0; /* probably a bad or non-existant disklabel */
58*41069Swilliam 	    bootdev = makedev(bootdev, make_minor(unit, io));
59*41069Swilliam 	} else { io = 0 ; howto = (howto&0x7) | 3 ; }
60*41069Swilliam 	bp = bootprog ;
61*41069Swilliam 	while (*bp != '0') bp++ ;	/* n-char device names instead of 2 */
62*41069Swilliam 	*bp++ = unit % 10 + '0' ;
63*41069Swilliam 	*bp += io % 10 ;
64*41069Swilliam /*	bootprog[3] = unit % 10 + '0';
65*41069Swilliam 	bootprog[4] = io % 10 + 'a';*/
66*41069Swilliam 	printf("loading %s\n", bootprog);
67*41069Swilliam 	io = open(bootprog, 0);
68*41069Swilliam 	if (io >= 0)
69*41069Swilliam 		copyunix(io);
70*41069Swilliam 	_stop("boot failed\n");
71*41069Swilliam }
72*41069Swilliam 
73*41069Swilliam /*ARGSUSED*/
74*41069Swilliam copyunix(io)
75*41069Swilliam 	register io;
76*41069Swilliam {
77*41069Swilliam 	struct exec x;
78*41069Swilliam 	register int i;
79*41069Swilliam 	char *addr;
80*41069Swilliam 
81*41069Swilliam 	i = read(io, (char *)&x, sizeof x);
82*41069Swilliam 	if (i != sizeof x ||
83*41069Swilliam 	    (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410))
84*41069Swilliam 		_stop("Bad format\n");
85*41069Swilliam 	if ((x.a_magic == 0413 || x.a_magic == 0410) &&
86*41069Swilliam 	    lseek(io, 0x400, 0) == -1)
87*41069Swilliam 		goto shread;
88*41069Swilliam 	if (read(io, (char *)0, x.a_text) != x.a_text)
89*41069Swilliam 		goto shread;
90*41069Swilliam 	addr = (char *)x.a_text;
91*41069Swilliam 	if (x.a_magic == 0413 || x.a_magic == 0410)
92*41069Swilliam 		while ((int)addr & CLOFSET)
93*41069Swilliam 			*addr++ = 0;
94*41069Swilliam 	if (read(io, addr, x.a_data) != x.a_data)
95*41069Swilliam 		goto shread;
96*41069Swilliam 	addr += x.a_data;
97*41069Swilliam 	x.a_bss += 128*512;	/* slop */
98*41069Swilliam 	for (i = 0; i < x.a_bss; i++)
99*41069Swilliam 		*addr++ = 0;
100*41069Swilliam 	setregs();
101*41069Swilliam  	(*((int (*)()) x.a_entry))();
102*41069Swilliam 	return;
103*41069Swilliam shread:
104*41069Swilliam 	_stop("Short read\n");
105*41069Swilliam }
106