xref: /csrg-svn/sys/hp300/stand/boot.c (revision 41488)
1*41488Smckusick /*
2*41488Smckusick  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
3*41488Smckusick  * All rights reserved.
4*41488Smckusick  *
5*41488Smckusick  * %sccs.include.redist.c%
6*41488Smckusick  *
7*41488Smckusick  *	@(#)boot.c	7.1 (Berkeley) 05/08/90
8*41488Smckusick  */
9*41488Smckusick 
10*41488Smckusick #include <a.out.h>
11*41488Smckusick #include "saio.h"
12*41488Smckusick #include "../sys/reboot.h"
13*41488Smckusick 
14*41488Smckusick #ifndef INSECURE
15*41488Smckusick #include "../sys/stat.h"
16*41488Smckusick struct stat sb;
17*41488Smckusick #endif
18*41488Smckusick 
19*41488Smckusick #define B_MAKEDEV(a,u,p,t) \
20*41488Smckusick 	(((a) << B_ADAPTORSHIFT) | ((u) << B_UNITSHIFT) | \
21*41488Smckusick 	 ((p) << B_PARTITIONSHIFT) | ((t) << B_TYPESHIFT))
22*41488Smckusick 
23*41488Smckusick /*
24*41488Smckusick  * Boot program... arguments in `devtype' and `howto' determine
25*41488Smckusick  * whether boot stops to ask for system name and which device
26*41488Smckusick  * boot comes from.
27*41488Smckusick  */
28*41488Smckusick 
29*41488Smckusick /* Types in `devtype' specifying major device */
30*41488Smckusick char	devname[][2] = {
31*41488Smckusick 	0,0,		/* 0 = ct */
32*41488Smckusick 	0,0,		/* 1 = fd */
33*41488Smckusick 	'r','d',	/* 2 = rd */
34*41488Smckusick 	0,0,		/* 3 = sw */
35*41488Smckusick 	's','d',	/* 4 = sd */
36*41488Smckusick };
37*41488Smckusick #define	MAXTYPE	(sizeof(devname) / sizeof(devname[0]))
38*41488Smckusick 
39*41488Smckusick #define	UNIX	"vmunix"
40*41488Smckusick char line[100];
41*41488Smckusick 
42*41488Smckusick int	retry = 0;
43*41488Smckusick extern	char *lowram;
44*41488Smckusick extern	int noconsole;
45*41488Smckusick extern	int howto, devtype;
46*41488Smckusick 
47*41488Smckusick #define	MSUS (0xfffffedc)
48*41488Smckusick 
49*41488Smckusick char rom2mdev[] = {
50*41488Smckusick 	0,	/*  0 - none */
51*41488Smckusick 	0,	/*  1 - none */
52*41488Smckusick 	0,	/*  2 - none */
53*41488Smckusick 	0,	/*  3 - none */
54*41488Smckusick 	0,	/*  4 - none */
55*41488Smckusick 	0,	/*  5 - none */
56*41488Smckusick 	0,	/*  6 - none */
57*41488Smckusick 	0,	/*  7 - none */
58*41488Smckusick 	0,	/*  8 - none */
59*41488Smckusick 	0,	/*  9 - none */
60*41488Smckusick 	0,	/* 10 - none */
61*41488Smckusick 	0,	/* 11 - none */
62*41488Smckusick 	0,	/* 12 - none */
63*41488Smckusick 	0,	/* 13 - none */
64*41488Smckusick 	4,	/* 14 - SCSI disk */
65*41488Smckusick 	0,	/* 15 - none */
66*41488Smckusick 	2,	/* 16 - CS/80 device on HPIB */
67*41488Smckusick 	2,	/* 17 - CS/80 device on HPIB */
68*41488Smckusick 	0,	/* 18 - none */
69*41488Smckusick 	0,	/* 19 - none */
70*41488Smckusick 	0,	/* 20 - none */
71*41488Smckusick 	0,	/* 21 - none */
72*41488Smckusick 	0,	/* 22 - none */
73*41488Smckusick 	0,	/* 23 - none */
74*41488Smckusick 	0,	/* 24 - none */
75*41488Smckusick 	0,	/* 25 - none */
76*41488Smckusick 	0,	/* 26 - none */
77*41488Smckusick 	0,	/* 27 - none */
78*41488Smckusick 	0,	/* 28 - none */
79*41488Smckusick 	0,	/* 29 - none */
80*41488Smckusick 	0,	/* 30 - none */
81*41488Smckusick 	0,	/* 31 - none */
82*41488Smckusick };
83*41488Smckusick 
84*41488Smckusick main()
85*41488Smckusick {
86*41488Smckusick 	register type, part, unit, io;
87*41488Smckusick 	register char *cp;
88*41488Smckusick 
89*41488Smckusick 	printf("\nBoot\n");
90*41488Smckusick #ifdef JUSTASK
91*41488Smckusick 	howto = RB_ASKNAME|RB_SINGLE;
92*41488Smckusick #else
93*41488Smckusick 	type = (devtype >> B_TYPESHIFT) & B_TYPEMASK;
94*41488Smckusick 	unit = (devtype >> B_UNITSHIFT) & B_UNITMASK;
95*41488Smckusick 	unit += 8 * ((devtype >> B_ADAPTORSHIFT) & B_ADAPTORMASK);
96*41488Smckusick 	part = (devtype >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
97*41488Smckusick 	if ((howto & RB_ASKNAME) == 0) {
98*41488Smckusick 		if ((devtype & B_MAGICMASK) != B_DEVMAGIC) {
99*41488Smckusick 			/*
100*41488Smckusick 			 * we have to map the ROM device type codes
101*41488Smckusick 			 * to Unix major device numbers.
102*41488Smckusick 			 */
103*41488Smckusick 			type = rom2mdev[*(char *)MSUS & 0x1f];
104*41488Smckusick 			devtype = (devtype &~ (B_TYPEMASK << B_TYPESHIFT))
105*41488Smckusick 				  | (type << B_TYPESHIFT);
106*41488Smckusick 		}
107*41488Smckusick 		if (type >= 0 && type <= MAXTYPE && devname[type][0]) {
108*41488Smckusick 			cp = line;
109*41488Smckusick 			*cp++ = devname[type][0];
110*41488Smckusick 			*cp++ = devname[type][1];
111*41488Smckusick 			*cp++ = '(';
112*41488Smckusick 			if (unit >= 10)
113*41488Smckusick 				*cp++ = unit / 10 + '0';
114*41488Smckusick 			*cp++ = unit % 10 + '0';
115*41488Smckusick 			*cp++ = ',';
116*41488Smckusick 			*cp++ = part + '0';
117*41488Smckusick 			*cp++ = ')';
118*41488Smckusick 			strcpy(cp, UNIX);
119*41488Smckusick 		} else
120*41488Smckusick 			howto = RB_SINGLE|RB_ASKNAME;
121*41488Smckusick 	}
122*41488Smckusick #endif
123*41488Smckusick 	for (;;) {
124*41488Smckusick 		if (!noconsole && (howto & RB_ASKNAME)) {
125*41488Smckusick 			printf(": ");
126*41488Smckusick 			gets(line);
127*41488Smckusick 		} else
128*41488Smckusick 			printf(": %s\n", line);
129*41488Smckusick 		io = open(line, 0);
130*41488Smckusick 		if (io >= 0) {
131*41488Smckusick #ifndef INSECURE
132*41488Smckusick 			(void) fstat(io, &sb);
133*41488Smckusick 			if (sb.st_uid || (sb.st_mode & 2)) {
134*41488Smckusick 				printf("non-secure file, will not load\n");
135*41488Smckusick 				howto = RB_SINGLE|RB_ASKNAME;
136*41488Smckusick 				continue;
137*41488Smckusick 			}
138*41488Smckusick #endif
139*41488Smckusick 			if (howto & RB_ASKNAME) {
140*41488Smckusick 				/*
141*41488Smckusick 				 * Build up devtype register to pass on to
142*41488Smckusick 				 * booted program.
143*41488Smckusick 				 */
144*41488Smckusick 				cp = line;
145*41488Smckusick 				for (type = 0; type <= MAXTYPE; type++)
146*41488Smckusick 					if ((devname[type][0] == cp[0]) &&
147*41488Smckusick 					    (devname[type][1] == cp[1]))
148*41488Smckusick 					    	break;
149*41488Smckusick 				if (type <= MAXTYPE) {
150*41488Smckusick 					cp += 3;
151*41488Smckusick 					unit = *cp++ - '0';
152*41488Smckusick 					if (*cp >= '0' && *cp <= '9')
153*41488Smckusick 						unit = unit * 10 + *cp++ - '0';
154*41488Smckusick 					cp++;
155*41488Smckusick 					part = atol(cp);
156*41488Smckusick 					devtype = B_MAKEDEV(unit >> 3, unit & 7, part, type);
157*41488Smckusick 				}
158*41488Smckusick 			}
159*41488Smckusick 			devtype |= B_DEVMAGIC;
160*41488Smckusick 			copyunix(howto, devtype, io);
161*41488Smckusick 			close(io);
162*41488Smckusick 			howto = RB_SINGLE|RB_ASKNAME;
163*41488Smckusick 		}
164*41488Smckusick 	bad:
165*41488Smckusick 		if (++retry > 2)
166*41488Smckusick 			howto = RB_SINGLE|RB_ASKNAME;
167*41488Smckusick 	}
168*41488Smckusick }
169*41488Smckusick 
170*41488Smckusick /*ARGSUSED*/
171*41488Smckusick copyunix(howto, devtype, io)
172*41488Smckusick 	register howto;		/* d7 contains boot flags */
173*41488Smckusick 	register devtype;	/* d6 contains boot device */
174*41488Smckusick 	register io;
175*41488Smckusick {
176*41488Smckusick 	struct exec x;
177*41488Smckusick 	register int i;
178*41488Smckusick 	register char *load;	/* a5 contains load addr for unix */
179*41488Smckusick 	register char *addr;
180*41488Smckusick 
181*41488Smckusick 	i = read(io, (char *)&x, sizeof x);
182*41488Smckusick 	if (i != sizeof x ||
183*41488Smckusick 	    (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410))
184*41488Smckusick 		_stop("Bad format\n");
185*41488Smckusick 	printf("%d", x.a_text);
186*41488Smckusick 	if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1)
187*41488Smckusick 		goto shread;
188*41488Smckusick 	load = addr = lowram;
189*41488Smckusick 	if (read(io, (char *)addr, x.a_text) != x.a_text)
190*41488Smckusick 		goto shread;
191*41488Smckusick 	addr += x.a_text;
192*41488Smckusick 	if (x.a_magic == 0413 || x.a_magic == 0410)
193*41488Smckusick 		while ((int)addr & CLOFSET)
194*41488Smckusick 			*addr++ = 0;
195*41488Smckusick 	printf("+%d", x.a_data);
196*41488Smckusick 	if (read(io, addr, x.a_data) != x.a_data)
197*41488Smckusick 		goto shread;
198*41488Smckusick 	addr += x.a_data;
199*41488Smckusick 	printf("+%d", x.a_bss);
200*41488Smckusick 	x.a_bss += 128*512;	/* slop */
201*41488Smckusick 	for (i = 0; i < x.a_bss; i++)
202*41488Smckusick 		*addr++ = 0;
203*41488Smckusick 	x.a_entry += (int)lowram;
204*41488Smckusick 	printf(" start 0x%x\n", x.a_entry);
205*41488Smckusick #ifdef __GNUC__
206*41488Smckusick 	asm("	movl %0,d7" : : "m" (howto));
207*41488Smckusick 	asm("	movl %0,d6" : : "m" (devtype));
208*41488Smckusick 	asm("	movl %0,a5" : : "a" (load));
209*41488Smckusick #endif
210*41488Smckusick 	(*((int (*)()) x.a_entry))();
211*41488Smckusick 	exit();
212*41488Smckusick shread:
213*41488Smckusick 	_stop("Short read\n");
214*41488Smckusick }
215