xref: /csrg-svn/sys/hp300/stand/boot.c (revision 49113)
1*49113Sbostic /*-
241488Smckusick  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
341488Smckusick  * All rights reserved.
441488Smckusick  *
541488Smckusick  * %sccs.include.redist.c%
641488Smckusick  *
7*49113Sbostic  *	@(#)boot.c	7.3 (Berkeley) 05/04/91
841488Smckusick  */
941488Smckusick 
1041488Smckusick #include <a.out.h>
1141488Smckusick #include "saio.h"
1245790Sbostic #include "sys/reboot.h"
1341488Smckusick 
1441488Smckusick #ifndef INSECURE
1545790Sbostic #include "sys/stat.h"
1641488Smckusick struct stat sb;
1741488Smckusick #endif
1841488Smckusick 
1941488Smckusick #define B_MAKEDEV(a,u,p,t) \
2041488Smckusick 	(((a) << B_ADAPTORSHIFT) | ((u) << B_UNITSHIFT) | \
2141488Smckusick 	 ((p) << B_PARTITIONSHIFT) | ((t) << B_TYPESHIFT))
2241488Smckusick 
2341488Smckusick /*
2441488Smckusick  * Boot program... arguments in `devtype' and `howto' determine
2541488Smckusick  * whether boot stops to ask for system name and which device
2641488Smckusick  * boot comes from.
2741488Smckusick  */
2841488Smckusick 
2941488Smckusick /* Types in `devtype' specifying major device */
3041488Smckusick char	devname[][2] = {
3141488Smckusick 	0,0,		/* 0 = ct */
3241488Smckusick 	0,0,		/* 1 = fd */
3341488Smckusick 	'r','d',	/* 2 = rd */
3441488Smckusick 	0,0,		/* 3 = sw */
3541488Smckusick 	's','d',	/* 4 = sd */
3641488Smckusick };
3741488Smckusick #define	MAXTYPE	(sizeof(devname) / sizeof(devname[0]))
3841488Smckusick 
3941488Smckusick #define	UNIX	"vmunix"
4041488Smckusick char line[100];
4141488Smckusick 
4241488Smckusick int	retry = 0;
4341488Smckusick extern	char *lowram;
4441488Smckusick extern	int noconsole;
4541488Smckusick extern	int howto, devtype;
4641488Smckusick 
4741488Smckusick #define	MSUS (0xfffffedc)
4841488Smckusick 
4941488Smckusick char rom2mdev[] = {
5041488Smckusick 	0,	/*  0 - none */
5141488Smckusick 	0,	/*  1 - none */
5241488Smckusick 	0,	/*  2 - none */
5341488Smckusick 	0,	/*  3 - none */
5441488Smckusick 	0,	/*  4 - none */
5541488Smckusick 	0,	/*  5 - none */
5641488Smckusick 	0,	/*  6 - none */
5741488Smckusick 	0,	/*  7 - none */
5841488Smckusick 	0,	/*  8 - none */
5941488Smckusick 	0,	/*  9 - none */
6041488Smckusick 	0,	/* 10 - none */
6141488Smckusick 	0,	/* 11 - none */
6241488Smckusick 	0,	/* 12 - none */
6341488Smckusick 	0,	/* 13 - none */
6441488Smckusick 	4,	/* 14 - SCSI disk */
6541488Smckusick 	0,	/* 15 - none */
6641488Smckusick 	2,	/* 16 - CS/80 device on HPIB */
6741488Smckusick 	2,	/* 17 - CS/80 device on HPIB */
6841488Smckusick 	0,	/* 18 - none */
6941488Smckusick 	0,	/* 19 - none */
7041488Smckusick 	0,	/* 20 - none */
7141488Smckusick 	0,	/* 21 - none */
7241488Smckusick 	0,	/* 22 - none */
7341488Smckusick 	0,	/* 23 - none */
7441488Smckusick 	0,	/* 24 - none */
7541488Smckusick 	0,	/* 25 - none */
7641488Smckusick 	0,	/* 26 - none */
7741488Smckusick 	0,	/* 27 - none */
7841488Smckusick 	0,	/* 28 - none */
7941488Smckusick 	0,	/* 29 - none */
8041488Smckusick 	0,	/* 30 - none */
8141488Smckusick 	0,	/* 31 - none */
8241488Smckusick };
8341488Smckusick 
8441488Smckusick main()
8541488Smckusick {
8641488Smckusick 	register type, part, unit, io;
8741488Smckusick 	register char *cp;
8841488Smckusick 
8941488Smckusick 	printf("\nBoot\n");
9041488Smckusick #ifdef JUSTASK
9141488Smckusick 	howto = RB_ASKNAME|RB_SINGLE;
9241488Smckusick #else
9341488Smckusick 	type = (devtype >> B_TYPESHIFT) & B_TYPEMASK;
9441488Smckusick 	unit = (devtype >> B_UNITSHIFT) & B_UNITMASK;
9541488Smckusick 	unit += 8 * ((devtype >> B_ADAPTORSHIFT) & B_ADAPTORMASK);
9641488Smckusick 	part = (devtype >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
9741488Smckusick 	if ((howto & RB_ASKNAME) == 0) {
9841488Smckusick 		if ((devtype & B_MAGICMASK) != B_DEVMAGIC) {
9941488Smckusick 			/*
10041488Smckusick 			 * we have to map the ROM device type codes
10141488Smckusick 			 * to Unix major device numbers.
10241488Smckusick 			 */
10341488Smckusick 			type = rom2mdev[*(char *)MSUS & 0x1f];
10441488Smckusick 			devtype = (devtype &~ (B_TYPEMASK << B_TYPESHIFT))
10541488Smckusick 				  | (type << B_TYPESHIFT);
10641488Smckusick 		}
10741488Smckusick 		if (type >= 0 && type <= MAXTYPE && devname[type][0]) {
10841488Smckusick 			cp = line;
10941488Smckusick 			*cp++ = devname[type][0];
11041488Smckusick 			*cp++ = devname[type][1];
11141488Smckusick 			*cp++ = '(';
11241488Smckusick 			if (unit >= 10)
11341488Smckusick 				*cp++ = unit / 10 + '0';
11441488Smckusick 			*cp++ = unit % 10 + '0';
11541488Smckusick 			*cp++ = ',';
11641488Smckusick 			*cp++ = part + '0';
11741488Smckusick 			*cp++ = ')';
11841488Smckusick 			strcpy(cp, UNIX);
11941488Smckusick 		} else
12041488Smckusick 			howto = RB_SINGLE|RB_ASKNAME;
12141488Smckusick 	}
12241488Smckusick #endif
12341488Smckusick 	for (;;) {
12441488Smckusick 		if (!noconsole && (howto & RB_ASKNAME)) {
12541488Smckusick 			printf(": ");
12641488Smckusick 			gets(line);
12741488Smckusick 		} else
12841488Smckusick 			printf(": %s\n", line);
12941488Smckusick 		io = open(line, 0);
13041488Smckusick 		if (io >= 0) {
13141488Smckusick #ifndef INSECURE
13241488Smckusick 			(void) fstat(io, &sb);
13341488Smckusick 			if (sb.st_uid || (sb.st_mode & 2)) {
13441488Smckusick 				printf("non-secure file, will not load\n");
13541488Smckusick 				howto = RB_SINGLE|RB_ASKNAME;
13641488Smckusick 				continue;
13741488Smckusick 			}
13841488Smckusick #endif
13941488Smckusick 			if (howto & RB_ASKNAME) {
14041488Smckusick 				/*
14141488Smckusick 				 * Build up devtype register to pass on to
14241488Smckusick 				 * booted program.
14341488Smckusick 				 */
14441488Smckusick 				cp = line;
14541488Smckusick 				for (type = 0; type <= MAXTYPE; type++)
14641488Smckusick 					if ((devname[type][0] == cp[0]) &&
14741488Smckusick 					    (devname[type][1] == cp[1]))
14841488Smckusick 					    	break;
14941488Smckusick 				if (type <= MAXTYPE) {
15041488Smckusick 					cp += 3;
15141488Smckusick 					unit = *cp++ - '0';
15241488Smckusick 					if (*cp >= '0' && *cp <= '9')
15341488Smckusick 						unit = unit * 10 + *cp++ - '0';
15441488Smckusick 					cp++;
15541488Smckusick 					part = atol(cp);
15641488Smckusick 					devtype = B_MAKEDEV(unit >> 3, unit & 7, part, type);
15741488Smckusick 				}
15841488Smckusick 			}
15941488Smckusick 			devtype |= B_DEVMAGIC;
16041488Smckusick 			copyunix(howto, devtype, io);
16141488Smckusick 			close(io);
16241488Smckusick 			howto = RB_SINGLE|RB_ASKNAME;
16341488Smckusick 		}
16441488Smckusick 	bad:
16541488Smckusick 		if (++retry > 2)
16641488Smckusick 			howto = RB_SINGLE|RB_ASKNAME;
16741488Smckusick 	}
16841488Smckusick }
16941488Smckusick 
17041488Smckusick /*ARGSUSED*/
17141488Smckusick copyunix(howto, devtype, io)
17241488Smckusick 	register howto;		/* d7 contains boot flags */
17341488Smckusick 	register devtype;	/* d6 contains boot device */
17441488Smckusick 	register io;
17541488Smckusick {
17641488Smckusick 	struct exec x;
17741488Smckusick 	register int i;
17841488Smckusick 	register char *load;	/* a5 contains load addr for unix */
17941488Smckusick 	register char *addr;
18041488Smckusick 
18141488Smckusick 	i = read(io, (char *)&x, sizeof x);
18241488Smckusick 	if (i != sizeof x ||
18341488Smckusick 	    (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410))
18441488Smckusick 		_stop("Bad format\n");
18541488Smckusick 	printf("%d", x.a_text);
18641488Smckusick 	if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1)
18741488Smckusick 		goto shread;
18841488Smckusick 	load = addr = lowram;
18941488Smckusick 	if (read(io, (char *)addr, x.a_text) != x.a_text)
19041488Smckusick 		goto shread;
19141488Smckusick 	addr += x.a_text;
19241488Smckusick 	if (x.a_magic == 0413 || x.a_magic == 0410)
19341488Smckusick 		while ((int)addr & CLOFSET)
19441488Smckusick 			*addr++ = 0;
19541488Smckusick 	printf("+%d", x.a_data);
19641488Smckusick 	if (read(io, addr, x.a_data) != x.a_data)
19741488Smckusick 		goto shread;
19841488Smckusick 	addr += x.a_data;
19941488Smckusick 	printf("+%d", x.a_bss);
20041488Smckusick 	x.a_bss += 128*512;	/* slop */
20141488Smckusick 	for (i = 0; i < x.a_bss; i++)
20241488Smckusick 		*addr++ = 0;
20341488Smckusick 	x.a_entry += (int)lowram;
20441488Smckusick 	printf(" start 0x%x\n", x.a_entry);
20541488Smckusick #ifdef __GNUC__
20641488Smckusick 	asm("	movl %0,d7" : : "m" (howto));
20741488Smckusick 	asm("	movl %0,d6" : : "m" (devtype));
20841488Smckusick 	asm("	movl %0,a5" : : "a" (load));
20941488Smckusick #endif
21041488Smckusick 	(*((int (*)()) x.a_entry))();
21141488Smckusick 	exit();
21241488Smckusick shread:
21341488Smckusick 	_stop("Short read\n");
21441488Smckusick }
215