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