xref: /original-bsd/sys/luna68k/stand/boot.c (revision 0cb8b4c6)
1 /*
2  * Copyright (c) 1992 OMRON Corporation.
3  * Copyright (c) 1992 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * OMRON Corporation.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)boot.c	7.3 (Berkeley) 05/12/93
12  */
13 
14 /*
15  * boot.c -- boot program
16  * by A.Fujita, MAR-01-1992
17  */
18 
19 #include <sys/param.h>
20 #include <sys/reboot.h>
21 #include <sys/exec.h>
22 #include <machine/stinger.h>
23 #include <luna68k/stand/saio.h>
24 #include <luna68k/stand/status.h>
25 
26 extern struct KernInter	*kiff;
27 
28 int howto;
29 int devtype = MAKEBOOTDEV(4, 0, 6, 0, 0);
30 
31 char *copyunix();
32 
33 struct exec header;
34 char default_file[] = "sd(0,0)vmunix";
35 
36 char *how_to_info[] = {
37 "RB_ASKNAME	ask for file name to reboot from",
38 "RB_SINGLE	reboot to single user only",
39 "RB_NOSYNC	dont sync before reboot",
40 "RB_HALT	don't reboot, just halt",
41 "RB_INITNAME	name given for /etc/init (unused)",
42 "RB_DFLTROOT	use compiled-in rootdev",
43 "RB_KDB		give control to kernel debugger",
44 "RB_RDONLY	mount root fs read-only"
45 };
46 
47 #define TAPE
48 #ifdef TAPE /* A.Kojima */
49 extern dev_t  rst0;
50 extern dev_t nrst0;
51 char *stcopyunix();
52 #endif
53 
54 int
55 how_to_boot(argc, argv)
56 	int   argc;
57 	char *argv[];
58 {
59 	int i, h = howto;
60 
61 	if (argc < 2) {
62 		printf("howto: 0x%s\n\n", hexstr(howto, 2));
63 
64 		if (h == 0) {
65 			printf("\t%s\n", "RB_AUTOBOOT	flags for system auto-booting itself");
66 		} else {
67 			for (i = 0; i < 8; i++, h >>= 1) {
68 				if (h & 0x01) {
69 					printf("\t%s\n", how_to_info[i]);
70 				}
71 			}
72 		}
73 
74 		printf("\n");
75 	}
76 }
77 
78 int
79 get_boot_device(s)
80 	char *s;
81 {
82 	register int unit = 0;
83 	register int part = 0;
84 	register char *p = s;
85 
86 	while (*p != '(') {
87 		if (*p == '\0')
88 			goto error;
89 		p++;
90 	}
91 
92 	while (*++p != ',') {
93 		if (*p == '\0')
94 			goto error;
95 		if (*p >= '0' && *p <= '9')
96 			unit = (unit * 10) + (*p - '0');
97 	}
98 
99 	while (*++p != ')') {
100 		if (*p == '\0')
101 			goto error;
102 		if (*p >= '0' && *p <= '9')
103 			part = (part * 10) + (*p - '0');
104 	}
105 
106 	return(MAKEBOOTDEV(4, 0, (6 - unit), unit, part));
107 
108 error:
109 	return(MAKEBOOTDEV(4, 0, 6, 0, 0));
110 }
111 
112 int
113 boot(argc, argv)
114 	int   argc;
115 	char *argv[];
116 {
117 	register int io;
118 	char *line;
119 
120 	if (argc < 2)
121 		line = default_file;
122 	else
123 		line = argv[1];
124 
125 	devtype = get_boot_device(line);
126 
127 	printf("Booting %s\n", line);
128 
129 #ifdef TAPE /* A.Kojima */
130 	if (!strcmp("st", argv[1])) {
131 		io = argc < 3 ? 0 : *argv[2] - '0';
132 		printf("boot tape file number:%d\n", io);
133 		stbootunix(howto, devtype, io);
134 		return;
135 	}
136 #endif
137 	io = open(line, 0);
138 	if (io >= 0) {
139 		bootunix(howto, devtype, io);
140 		close(io);
141 	}
142 }
143 
144 int
145 load(argc, argv)
146 	int   argc;
147 	char *argv[];
148 {
149 	register int io;
150 	char *line;
151 
152 	if (argc < 2)
153 		line = default_file;
154 	else
155 		line = argv[1];
156 
157 	printf("loading %s\n", line);
158 
159 	io = open(line, 0);
160 	if (io >= 0) {
161 		copyunix(io);
162 		printf("\n");
163 		close(io);
164 	}
165 }
166 
167 int
168 bootunix(howto, devtype, io)
169 	register howto;		/* d7 contains boot flags */
170 	register devtype;	/* d6 contains boot device */
171 	register io;
172 {
173 	register char *load;	/* a5 contains load addr for unix */
174 
175 	load = copyunix(io);
176 
177 	printf(" start 0x%x\n", load);
178 	asm("	movl %0,d7" : : "d" (howto));
179 	asm("	movl %0,d6" : : "d" (devtype));
180 	asm("	movl %0,a5" : : "a" (kiff));
181 	(*((int (*)()) load))();
182 }
183 
184 char *
185 copyunix(io)
186 	register io;
187 {
188 
189 	register int i;
190 	register char *load;	/* a5 contains load addr for unix */
191 	register char *addr;
192 
193 	/*
194 	 * Read a.out file header
195 	 */
196 
197 	i = read(io, (char *)&header, sizeof(struct exec));
198 	if (i != sizeof(struct exec) ||
199 	    (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
200 		printf("illegal magic number ... 0x%x\n");
201 		printf("Bad format\n");
202 		return(0);
203 	}
204 
205 	load = addr = (char *) (header.a_entry & 0x00FFFFFF);
206 
207 	printf("%d", header.a_text);
208 	if (header.a_magic == 0413 && lseek(io, 0x400, 0) == -1)
209 		goto shread;
210 
211 	/*
212 	 * Load TEXT Segment
213 	 */
214 
215 	if (read(io, (char *)addr, header.a_text) != header.a_text)
216 		goto shread;
217 	addr += header.a_text;
218 	if (header.a_magic == 0413 || header.a_magic == 0410)
219 		while ((int)addr & CLOFSET)
220 			*addr++ = 0;
221 
222 	/*
223 	 * Load DATA Segment
224 	 */
225 
226 	printf("+%d", header.a_data);
227 	if (read(io, addr, header.a_data) != header.a_data)
228 		goto shread;
229 
230 	/*
231 	 * Clear BSS Segment
232 	 */
233 
234 	addr += header.a_data;
235 	printf("+%d", header.a_bss);
236 	header.a_bss += 128*512;	/* slop */
237 	for (i = 0; i < header.a_bss; i++)
238 		*addr++ = 0;
239 
240 	return(load);
241 
242 shread:
243 	printf("   Short read\n");
244 	return(0);
245 }
246 
247 #ifdef TAPE /* A.Kojima */
248 int
249 stbootunix(howto, devtype, skip)
250 	register howto;		/* d7 contains boot flags */
251 	register devtype;	/* d6 contains boot device */
252 	register skip;		/* tape skip */
253 {
254 	register int i;
255 	register char *load;	/* a5 contains load addr for unix */
256 
257 	/*
258 	 * Tape rewind and skip
259 	 */
260 	st_rewind(rst0);
261 	for (i = 0; i < skip; i++) {
262 		st_skip(rst0);
263 	}
264 
265 	load = stcopyunix();
266 
267 	st_rewind(rst0);
268 
269 	printf(" start 0x%x\n", load);
270 	asm("	movl %0,d7" : : "d" (howto));
271 	asm("	movl %0,d6" : : "d" (devtype));
272 	asm("	movl %0,a5" : : "a" (kiff));
273 	(*((int (*)()) load))();
274 }
275 
276 char *
277 stcopyunix()
278 {
279 
280 	register int i;
281 	register char *load;	/* a5 contains load addr for unix */
282 	register char *addr;
283 	u_char buf[0x400];
284 
285 	/*
286 	 * Read a.out file header
287 	 */
288 
289 	i = tread(/*io,*/ (char *)&header, sizeof(struct exec));
290 	if (i != sizeof(struct exec) ||
291 	    (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
292 		printf("illegal magic number ... 0x%x\n");
293 		printf("Bad format\n");
294 		return(0);
295 	}
296 
297 	load = addr = (char *) (header.a_entry & 0x00FFFFFF);
298 
299 	printf("%d", header.a_text);
300 
301 	i = 0x400 - i;
302 	if (header.a_magic == 0413 && tread(buf, i) != i) { /* easy seek */
303 		goto shread;
304 	}
305 
306 	/*
307 	 * Load TEXT Segment
308 	 */
309 
310 	if (tread(/*io,*/ (char *)addr, header.a_text) != header.a_text)
311 		goto shread;
312 	addr += header.a_text;
313 	if (header.a_magic == 0413 || header.a_magic == 0410)
314 		while ((int)addr & CLOFSET)
315 			*addr++ = 0;
316 
317 	/*
318 	 * Load DATA Segment
319 	 */
320 
321 	printf("+%d", header.a_data);
322 	if (tread(/*io,*/ addr, header.a_data) != header.a_data)
323 		goto shread;
324 
325 	/*
326 	 * Clear BSS Segment
327 	 */
328 
329 	addr += header.a_data;
330 	printf("+%d", header.a_bss);
331 	header.a_bss += 128*512;	/* slop */
332 	for (i = 0; i < header.a_bss; i++)
333 		*addr++ = 0;
334 
335 	return(load);
336 
337 shread:
338 	printf("   Short read\n");
339 	return(0);
340 }
341 
342 int
343 tread(addr, size)
344 	int	addr;
345 	int	size;
346 {
347 	static u_char	buf[512];
348 	static int	head = 512;
349 	static int	tail = 512;
350 	int             req_size = size;
351 	int		rest = tail - head;
352 
353 	if (rest > 0) {
354 		if (size <= rest) {
355 			bcopy(&buf[head], addr, size);
356 			head += size;
357 			return size;
358 		} else { /* size > rest */
359 			bcopy(&buf[head], addr, rest);
360 			addr += rest;
361 			size -= rest;
362 			if (tail != 512) {
363 				head = 512;
364 				tail = 512;
365 				printf("tread() EOF 0\n");
366 				return rest;
367 			}
368 		}
369 	}
370 
371 	/* head = 0; */
372 
373 	while (size > 512) {
374 		if ((tail = stread(rst0, addr, 512)) == 512) {
375 			addr += 512;
376 			size -= 512;
377 		} else { /* eof ( tail < 512 ) */
378 			size -= tail;
379 			head = tail;
380 			printf("tread() EOF 1\n");
381 			return req_size - size;
382 		}
383 	}
384 	tail = stread(rst0, buf, 512);
385 	if (tail >= size) {
386 		bcopy(buf, addr, size);
387 		head = size;
388 		return req_size;
389 	} else {
390 		bcopy(buf, addr, tail);
391 		head = tail;
392 		printf("tread() EOF 2\n");
393 		return req_size - size;
394 	}
395 }
396 
397 #endif
398 
399