xref: /csrg-svn/sys/i386/stand/bootxx.c (revision 48813)
141069Swilliam /*-
241069Swilliam  * Copyright (c) 1990 The Regents of the University of California.
341069Swilliam  * All rights reserved.
441069Swilliam  *
541069Swilliam  * This code is derived from software contributed to Berkeley by
641069Swilliam  * William Jolitz.
741069Swilliam  *
8*48813Swilliam  * %sccs.include.redist.c%
941069Swilliam  *
10*48813Swilliam  *	@(#)bootxx.c	7.2 (Berkeley) 04/28/91
1141069Swilliam  */
1241069Swilliam 
13*48813Swilliam #include "param.h"
1441069Swilliam #include <a.out.h>
1541069Swilliam #include "saio.h"
16*48813Swilliam #include "reboot.h"
17*48813Swilliam #include "disklabel.h"
1841069Swilliam 
19*48813Swilliam char *bootprog = "/boot";
20*48813Swilliam extern int opendev, bootdev, cyloffset;
21*48813Swilliam extern struct disklabel disklabel;
22*48813Swilliam 
2341069Swilliam /*
24*48813Swilliam  * Boot program... loads /boot out of filesystem indicated by arguements.
25*48813Swilliam  * We assume an autoboot unless we detect a misconfiguration.
2641069Swilliam  */
2741069Swilliam 
28*48813Swilliam main(dev, unit, off)
2941069Swilliam {
30*48813Swilliam 	register struct disklabel *lp;
31*48813Swilliam 	register int io, partition, howto;
3241069Swilliam 
3341069Swilliam 
3441069Swilliam 	/* are we a disk, if so look at disklabel and do things */
35*48813Swilliam 	lp = &disklabel;
36*48813Swilliam 	if (lp->d_magic == DISKMAGIC) {
3741069Swilliam 	    /*
38*48813Swilliam 	     * Synthesize bootdev from dev, unit, type and partition
39*48813Swilliam 	     * information from the block 0 bootstrap.
40*48813Swilliam 	     * It's dirty work, but someone's got to do it.
41*48813Swilliam 	     * This will be used by the filesystem primatives, and
42*48813Swilliam 	     * drivers. Ultimately, opendev will be created corresponding
43*48813Swilliam 	     * to which drive to pass to top level bootstrap.
4441069Swilliam 	     */
4541069Swilliam 	    for (io = 0; io < 8; io++)
46*48813Swilliam #ifdef notyetSCSI
47*48813Swilliam 		if (lp->d_type == DTYPE_SCSI) {
48*48813Swilliam 			if (lp->d_partitions[io].p_offset == off)
4941069Swilliam 				break;
50*48813Swilliam 		} else
51*48813Swilliam #endif
52*48813Swilliam 		if (lp->d_partitions[io].p_offset == off*lp->d_secpercyl)
5341069Swilliam 			break;
54*48813Swilliam 
55*48813Swilliam 	    if (io == 8) goto screwed;
56*48813Swilliam             cyloffset = off;
57*48813Swilliam 	} else {
58*48813Swilliam screwed:
59*48813Swilliam 		/* probably a bad or non-existant disklabel */
60*48813Swilliam 		io = 0 ;
61*48813Swilliam 		howto |= RB_SINGLE|RB_ASKNAME ;
62*48813Swilliam 	}
63*48813Swilliam 
64*48813Swilliam 	/* construct bootdev */
65*48813Swilliam 	/* currently, PC has no way of booting off alternate controllers */
66*48813Swilliam 	bootdev = MAKEBOOTDEV(/*i_dev*/ dev, /*i_adapt*/0, /*i_ctlr*/0,
67*48813Swilliam 	    unit, /*i_part*/io);
68*48813Swilliam 
6941069Swilliam 	printf("loading %s\n", bootprog);
7041069Swilliam 	io = open(bootprog, 0);
7141069Swilliam 	if (io >= 0)
72*48813Swilliam 		copyunix(io, howto);
7341069Swilliam 	_stop("boot failed\n");
7441069Swilliam }
7541069Swilliam 
7641069Swilliam /*ARGSUSED*/
77*48813Swilliam copyunix(io, howto)
7841069Swilliam 	register io;
7941069Swilliam {
8041069Swilliam 	struct exec x;
8141069Swilliam 	register int i;
8241069Swilliam 	char *addr;
8341069Swilliam 
8441069Swilliam 	i = read(io, (char *)&x, sizeof x);
8541069Swilliam 	if (i != sizeof x ||
8641069Swilliam 	    (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410))
8741069Swilliam 		_stop("Bad format\n");
88*48813Swilliam 
8941069Swilliam 	if ((x.a_magic == 0413 || x.a_magic == 0410) &&
9041069Swilliam 	    lseek(io, 0x400, 0) == -1)
9141069Swilliam 		goto shread;
92*48813Swilliam 
9341069Swilliam 	if (read(io, (char *)0, x.a_text) != x.a_text)
9441069Swilliam 		goto shread;
95*48813Swilliam 
9641069Swilliam 	addr = (char *)x.a_text;
9741069Swilliam 	if (x.a_magic == 0413 || x.a_magic == 0410)
9841069Swilliam 		while ((int)addr & CLOFSET)
9941069Swilliam 			*addr++ = 0;
100*48813Swilliam 
10141069Swilliam 	if (read(io, addr, x.a_data) != x.a_data)
10241069Swilliam 		goto shread;
103*48813Swilliam 
10441069Swilliam 	addr += x.a_data;
10541069Swilliam 	for (i = 0; i < x.a_bss; i++)
10641069Swilliam 		*addr++ = 0;
107*48813Swilliam 
108*48813Swilliam  	(*((int (*)()) x.a_entry))(howto, opendev, cyloffset);
10941069Swilliam 	return;
11041069Swilliam shread:
11141069Swilliam 	_stop("Short read\n");
11241069Swilliam }
113