xref: /csrg-svn/sys/i386/stand/bootxx.c (revision 63368)
141069Swilliam /*-
2*63368Sbostic  * Copyright (c) 1990, 1993
3*63368Sbostic  *	The Regents of the University of California.  All rights reserved.
441069Swilliam  *
541069Swilliam  * This code is derived from software contributed to Berkeley by
641069Swilliam  * William Jolitz.
741069Swilliam  *
848813Swilliam  * %sccs.include.redist.c%
941069Swilliam  *
10*63368Sbostic  *	@(#)bootxx.c	8.1 (Berkeley) 06/11/93
1141069Swilliam  */
1241069Swilliam 
1356514Sbostic #include <sys/param.h>
1456514Sbostic #include <sys/reboot.h>
1556514Sbostic #include <sys/disklabel.h>
1656514Sbostic 
1741069Swilliam #include <a.out.h>
1856514Sbostic #include <stand/saio.h>
1941069Swilliam 
2048813Swilliam char *bootprog = "/boot";
2148813Swilliam extern int opendev, bootdev, cyloffset;
2248813Swilliam extern struct disklabel disklabel;
2348813Swilliam 
2441069Swilliam /*
2548813Swilliam  * Boot program... loads /boot out of filesystem indicated by arguements.
2648813Swilliam  * We assume an autoboot unless we detect a misconfiguration.
2741069Swilliam  */
2841069Swilliam 
main(dev,unit,off)2948813Swilliam main(dev, unit, off)
3041069Swilliam {
3148813Swilliam 	register struct disklabel *lp;
3248813Swilliam 	register int io, partition, howto;
3341069Swilliam 
3441069Swilliam 
3541069Swilliam 	/* are we a disk, if so look at disklabel and do things */
3648813Swilliam 	lp = &disklabel;
3748813Swilliam 	if (lp->d_magic == DISKMAGIC) {
3841069Swilliam 	    /*
3948813Swilliam 	     * Synthesize bootdev from dev, unit, type and partition
4048813Swilliam 	     * information from the block 0 bootstrap.
4148813Swilliam 	     * It's dirty work, but someone's got to do it.
4248813Swilliam 	     * This will be used by the filesystem primatives, and
4348813Swilliam 	     * drivers. Ultimately, opendev will be created corresponding
4448813Swilliam 	     * to which drive to pass to top level bootstrap.
4541069Swilliam 	     */
4641069Swilliam 	    for (io = 0; io < 8; io++)
4748813Swilliam #ifdef notyetSCSI
4848813Swilliam 		if (lp->d_type == DTYPE_SCSI) {
4948813Swilliam 			if (lp->d_partitions[io].p_offset == off)
5041069Swilliam 				break;
5148813Swilliam 		} else
5248813Swilliam #endif
5348813Swilliam 		if (lp->d_partitions[io].p_offset == off*lp->d_secpercyl)
5441069Swilliam 			break;
5548813Swilliam 
5648813Swilliam 	    if (io == 8) goto screwed;
5748813Swilliam             cyloffset = off;
5848813Swilliam 	} else {
5948813Swilliam screwed:
6048813Swilliam 		/* probably a bad or non-existant disklabel */
6148813Swilliam 		io = 0 ;
6248813Swilliam 		howto |= RB_SINGLE|RB_ASKNAME ;
6348813Swilliam 	}
6448813Swilliam 
6548813Swilliam 	/* construct bootdev */
6648813Swilliam 	/* currently, PC has no way of booting off alternate controllers */
6748813Swilliam 	bootdev = MAKEBOOTDEV(/*i_dev*/ dev, /*i_adapt*/0, /*i_ctlr*/0,
6848813Swilliam 	    unit, /*i_part*/io);
6948813Swilliam 
7041069Swilliam 	printf("loading %s\n", bootprog);
7141069Swilliam 	io = open(bootprog, 0);
7241069Swilliam 	if (io >= 0)
7348813Swilliam 		copyunix(io, howto);
7441069Swilliam 	_stop("boot failed\n");
7541069Swilliam }
7641069Swilliam 
7741069Swilliam /*ARGSUSED*/
copyunix(io,howto)7848813Swilliam copyunix(io, howto)
7941069Swilliam 	register io;
8041069Swilliam {
8141069Swilliam 	struct exec x;
8241069Swilliam 	register int i;
8341069Swilliam 	char *addr;
8441069Swilliam 
8541069Swilliam 	i = read(io, (char *)&x, sizeof x);
8641069Swilliam 	if (i != sizeof x ||
8741069Swilliam 	    (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410))
8841069Swilliam 		_stop("Bad format\n");
8948813Swilliam 
9041069Swilliam 	if ((x.a_magic == 0413 || x.a_magic == 0410) &&
9141069Swilliam 	    lseek(io, 0x400, 0) == -1)
9241069Swilliam 		goto shread;
9348813Swilliam 
9441069Swilliam 	if (read(io, (char *)0, x.a_text) != x.a_text)
9541069Swilliam 		goto shread;
9648813Swilliam 
9741069Swilliam 	addr = (char *)x.a_text;
9841069Swilliam 	if (x.a_magic == 0413 || x.a_magic == 0410)
9941069Swilliam 		while ((int)addr & CLOFSET)
10041069Swilliam 			*addr++ = 0;
10148813Swilliam 
10241069Swilliam 	if (read(io, addr, x.a_data) != x.a_data)
10341069Swilliam 		goto shread;
10448813Swilliam 
10541069Swilliam 	addr += x.a_data;
10641069Swilliam 	for (i = 0; i < x.a_bss; i++)
10741069Swilliam 		*addr++ = 0;
10848813Swilliam 
10948813Swilliam  	(*((int (*)()) x.a_entry))(howto, opendev, cyloffset);
11041069Swilliam 	return;
11141069Swilliam shread:
11241069Swilliam 	_stop("Short read\n");
11341069Swilliam }
114