xref: /csrg-svn/sys/luna68k/stand/boot.c (revision 59955)
157081Sakito /*
257081Sakito  * Copyright (c) 1992 OMRON Corporation.
357081Sakito  * Copyright (c) 1992 The Regents of the University of California.
457081Sakito  * All rights reserved.
557081Sakito  *
657081Sakito  * This code is derived from software contributed to Berkeley by
757081Sakito  * OMRON Corporation.
857081Sakito  *
957081Sakito  * %sccs.include.redist.c%
1057081Sakito  *
11*59955Sakito  *	@(#)boot.c	7.3 (Berkeley) 05/12/93
1257081Sakito  */
1357081Sakito 
1457081Sakito /*
1557081Sakito  * boot.c -- boot program
1657081Sakito  * by A.Fujita, MAR-01-1992
1757081Sakito  */
1857081Sakito 
1957081Sakito #include <sys/param.h>
2057081Sakito #include <sys/reboot.h>
2157081Sakito #include <sys/exec.h>
2257081Sakito #include <machine/stinger.h>
2357081Sakito #include <luna68k/stand/saio.h>
2457081Sakito #include <luna68k/stand/status.h>
2557081Sakito 
2657081Sakito extern struct KernInter	*kiff;
2757081Sakito 
2857081Sakito int howto;
2957518Sakito int devtype = MAKEBOOTDEV(4, 0, 6, 0, 0);
3057081Sakito 
3157081Sakito char *copyunix();
3257081Sakito 
3357081Sakito struct exec header;
3457081Sakito char default_file[] = "sd(0,0)vmunix";
3557081Sakito 
3657081Sakito char *how_to_info[] = {
3757081Sakito "RB_ASKNAME	ask for file name to reboot from",
3857081Sakito "RB_SINGLE	reboot to single user only",
3957081Sakito "RB_NOSYNC	dont sync before reboot",
4057081Sakito "RB_HALT	don't reboot, just halt",
4157081Sakito "RB_INITNAME	name given for /etc/init (unused)",
4257081Sakito "RB_DFLTROOT	use compiled-in rootdev",
4357081Sakito "RB_KDB		give control to kernel debugger",
4457081Sakito "RB_RDONLY	mount root fs read-only"
4557081Sakito };
4657081Sakito 
47*59955Sakito #define TAPE
48*59955Sakito #ifdef TAPE /* A.Kojima */
49*59955Sakito extern dev_t  rst0;
50*59955Sakito extern dev_t nrst0;
51*59955Sakito char *stcopyunix();
52*59955Sakito #endif
53*59955Sakito 
5457081Sakito int
5557081Sakito how_to_boot(argc, argv)
5657081Sakito 	int   argc;
5757081Sakito 	char *argv[];
5857081Sakito {
5957081Sakito 	int i, h = howto;
6057081Sakito 
6157081Sakito 	if (argc < 2) {
6257081Sakito 		printf("howto: 0x%s\n\n", hexstr(howto, 2));
6357081Sakito 
6457081Sakito 		if (h == 0) {
6557081Sakito 			printf("\t%s\n", "RB_AUTOBOOT	flags for system auto-booting itself");
6657081Sakito 		} else {
6757081Sakito 			for (i = 0; i < 8; i++, h >>= 1) {
6857081Sakito 				if (h & 0x01) {
6957081Sakito 					printf("\t%s\n", how_to_info[i]);
7057081Sakito 				}
7157081Sakito 			}
7257081Sakito 		}
7357081Sakito 
7457081Sakito 		printf("\n");
7557081Sakito 	}
7657081Sakito }
7757081Sakito 
7857081Sakito int
7957518Sakito get_boot_device(s)
8057518Sakito 	char *s;
8157518Sakito {
8257518Sakito 	register int unit = 0;
8357518Sakito 	register int part = 0;
8457518Sakito 	register char *p = s;
8557518Sakito 
8657518Sakito 	while (*p != '(') {
8757518Sakito 		if (*p == '\0')
8857518Sakito 			goto error;
8957518Sakito 		p++;
9057518Sakito 	}
9157518Sakito 
9257518Sakito 	while (*++p != ',') {
9357518Sakito 		if (*p == '\0')
9457518Sakito 			goto error;
9557518Sakito 		if (*p >= '0' && *p <= '9')
9657518Sakito 			unit = (unit * 10) + (*p - '0');
9757518Sakito 	}
9857518Sakito 
9957518Sakito 	while (*++p != ')') {
10057518Sakito 		if (*p == '\0')
10157518Sakito 			goto error;
10257518Sakito 		if (*p >= '0' && *p <= '9')
10357518Sakito 			part = (part * 10) + (*p - '0');
10457518Sakito 	}
10557518Sakito 
10657518Sakito 	return(MAKEBOOTDEV(4, 0, (6 - unit), unit, part));
10757518Sakito 
10857518Sakito error:
10957518Sakito 	return(MAKEBOOTDEV(4, 0, 6, 0, 0));
11057518Sakito }
11157518Sakito 
11257518Sakito int
11357081Sakito boot(argc, argv)
11457081Sakito 	int   argc;
11557081Sakito 	char *argv[];
11657081Sakito {
11757081Sakito 	register int io;
11857081Sakito 	char *line;
11957081Sakito 
12057081Sakito 	if (argc < 2)
12157081Sakito 		line = default_file;
12257081Sakito 	else
12357081Sakito 		line = argv[1];
12457081Sakito 
12557518Sakito 	devtype = get_boot_device(line);
12657518Sakito 
12757081Sakito 	printf("Booting %s\n", line);
12857081Sakito 
129*59955Sakito #ifdef TAPE /* A.Kojima */
130*59955Sakito 	if (!strcmp("st", argv[1])) {
131*59955Sakito 		io = argc < 3 ? 0 : *argv[2] - '0';
132*59955Sakito 		printf("boot tape file number:%d\n", io);
133*59955Sakito 		stbootunix(howto, devtype, io);
134*59955Sakito 		return;
135*59955Sakito 	}
136*59955Sakito #endif
13757081Sakito 	io = open(line, 0);
13857081Sakito 	if (io >= 0) {
13957081Sakito 		bootunix(howto, devtype, io);
14057081Sakito 		close(io);
14157081Sakito 	}
14257081Sakito }
14357081Sakito 
14457081Sakito int
14557081Sakito load(argc, argv)
14657081Sakito 	int   argc;
14757081Sakito 	char *argv[];
14857081Sakito {
14957081Sakito 	register int io;
15057081Sakito 	char *line;
15157081Sakito 
15257081Sakito 	if (argc < 2)
15357081Sakito 		line = default_file;
15457081Sakito 	else
15557081Sakito 		line = argv[1];
15657081Sakito 
15757081Sakito 	printf("loading %s\n", line);
15857081Sakito 
15957081Sakito 	io = open(line, 0);
16057081Sakito 	if (io >= 0) {
16157081Sakito 		copyunix(io);
16257081Sakito 		printf("\n");
16357081Sakito 		close(io);
16457081Sakito 	}
16557081Sakito }
16657081Sakito 
16757081Sakito int
16857081Sakito bootunix(howto, devtype, io)
16957081Sakito 	register howto;		/* d7 contains boot flags */
17057081Sakito 	register devtype;	/* d6 contains boot device */
17157081Sakito 	register io;
17257081Sakito {
17357081Sakito 	register char *load;	/* a5 contains load addr for unix */
17457081Sakito 
17557081Sakito 	load = copyunix(io);
17657081Sakito 
17757081Sakito 	printf(" start 0x%x\n", load);
17857081Sakito 	asm("	movl %0,d7" : : "d" (howto));
17957081Sakito 	asm("	movl %0,d6" : : "d" (devtype));
18057081Sakito 	asm("	movl %0,a5" : : "a" (kiff));
18157081Sakito 	(*((int (*)()) load))();
18257081Sakito }
18357081Sakito 
18457081Sakito char *
18557081Sakito copyunix(io)
18657081Sakito 	register io;
18757081Sakito {
18857081Sakito 
18957081Sakito 	register int i;
19057081Sakito 	register char *load;	/* a5 contains load addr for unix */
19157081Sakito 	register char *addr;
19257081Sakito 
19357081Sakito 	/*
19457081Sakito 	 * Read a.out file header
19557081Sakito 	 */
19657081Sakito 
19757081Sakito 	i = read(io, (char *)&header, sizeof(struct exec));
19857081Sakito 	if (i != sizeof(struct exec) ||
19957081Sakito 	    (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
20057081Sakito 		printf("illegal magic number ... 0x%x\n");
20157081Sakito 		printf("Bad format\n");
20257081Sakito 		return(0);
20357081Sakito 	}
20457081Sakito 
20557081Sakito 	load = addr = (char *) (header.a_entry & 0x00FFFFFF);
20657081Sakito 
20757081Sakito 	printf("%d", header.a_text);
20857081Sakito 	if (header.a_magic == 0413 && lseek(io, 0x400, 0) == -1)
20957081Sakito 		goto shread;
21057081Sakito 
21157081Sakito 	/*
21257081Sakito 	 * Load TEXT Segment
21357081Sakito 	 */
21457081Sakito 
21557081Sakito 	if (read(io, (char *)addr, header.a_text) != header.a_text)
21657081Sakito 		goto shread;
21757081Sakito 	addr += header.a_text;
21857081Sakito 	if (header.a_magic == 0413 || header.a_magic == 0410)
21957081Sakito 		while ((int)addr & CLOFSET)
22057081Sakito 			*addr++ = 0;
22157081Sakito 
22257081Sakito 	/*
22357081Sakito 	 * Load DATA Segment
22457081Sakito 	 */
22557081Sakito 
22657081Sakito 	printf("+%d", header.a_data);
22757081Sakito 	if (read(io, addr, header.a_data) != header.a_data)
22857081Sakito 		goto shread;
22957081Sakito 
23057081Sakito 	/*
23157081Sakito 	 * Clear BSS Segment
23257081Sakito 	 */
23357081Sakito 
23457081Sakito 	addr += header.a_data;
23557081Sakito 	printf("+%d", header.a_bss);
23657081Sakito 	header.a_bss += 128*512;	/* slop */
23757081Sakito 	for (i = 0; i < header.a_bss; i++)
23857081Sakito 		*addr++ = 0;
23957081Sakito 
24057081Sakito 	return(load);
24157081Sakito 
24257081Sakito shread:
24357081Sakito 	printf("   Short read\n");
24457081Sakito 	return(0);
24557081Sakito }
24657081Sakito 
247*59955Sakito #ifdef TAPE /* A.Kojima */
248*59955Sakito int
249*59955Sakito stbootunix(howto, devtype, skip)
250*59955Sakito 	register howto;		/* d7 contains boot flags */
251*59955Sakito 	register devtype;	/* d6 contains boot device */
252*59955Sakito 	register skip;		/* tape skip */
253*59955Sakito {
254*59955Sakito 	register int i;
255*59955Sakito 	register char *load;	/* a5 contains load addr for unix */
256*59955Sakito 
257*59955Sakito 	/*
258*59955Sakito 	 * Tape rewind and skip
259*59955Sakito 	 */
260*59955Sakito 	st_rewind(rst0);
261*59955Sakito 	for (i = 0; i < skip; i++) {
262*59955Sakito 		st_skip(rst0);
263*59955Sakito 	}
264*59955Sakito 
265*59955Sakito 	load = stcopyunix();
266*59955Sakito 
267*59955Sakito 	st_rewind(rst0);
268*59955Sakito 
269*59955Sakito 	printf(" start 0x%x\n", load);
270*59955Sakito 	asm("	movl %0,d7" : : "d" (howto));
271*59955Sakito 	asm("	movl %0,d6" : : "d" (devtype));
272*59955Sakito 	asm("	movl %0,a5" : : "a" (kiff));
273*59955Sakito 	(*((int (*)()) load))();
274*59955Sakito }
275*59955Sakito 
276*59955Sakito char *
277*59955Sakito stcopyunix()
278*59955Sakito {
279*59955Sakito 
280*59955Sakito 	register int i;
281*59955Sakito 	register char *load;	/* a5 contains load addr for unix */
282*59955Sakito 	register char *addr;
283*59955Sakito 	u_char buf[0x400];
284*59955Sakito 
285*59955Sakito 	/*
286*59955Sakito 	 * Read a.out file header
287*59955Sakito 	 */
288*59955Sakito 
289*59955Sakito 	i = tread(/*io,*/ (char *)&header, sizeof(struct exec));
290*59955Sakito 	if (i != sizeof(struct exec) ||
291*59955Sakito 	    (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
292*59955Sakito 		printf("illegal magic number ... 0x%x\n");
293*59955Sakito 		printf("Bad format\n");
294*59955Sakito 		return(0);
295*59955Sakito 	}
296*59955Sakito 
297*59955Sakito 	load = addr = (char *) (header.a_entry & 0x00FFFFFF);
298*59955Sakito 
299*59955Sakito 	printf("%d", header.a_text);
300*59955Sakito 
301*59955Sakito 	i = 0x400 - i;
302*59955Sakito 	if (header.a_magic == 0413 && tread(buf, i) != i) { /* easy seek */
303*59955Sakito 		goto shread;
304*59955Sakito 	}
305*59955Sakito 
306*59955Sakito 	/*
307*59955Sakito 	 * Load TEXT Segment
308*59955Sakito 	 */
309*59955Sakito 
310*59955Sakito 	if (tread(/*io,*/ (char *)addr, header.a_text) != header.a_text)
311*59955Sakito 		goto shread;
312*59955Sakito 	addr += header.a_text;
313*59955Sakito 	if (header.a_magic == 0413 || header.a_magic == 0410)
314*59955Sakito 		while ((int)addr & CLOFSET)
315*59955Sakito 			*addr++ = 0;
316*59955Sakito 
317*59955Sakito 	/*
318*59955Sakito 	 * Load DATA Segment
319*59955Sakito 	 */
320*59955Sakito 
321*59955Sakito 	printf("+%d", header.a_data);
322*59955Sakito 	if (tread(/*io,*/ addr, header.a_data) != header.a_data)
323*59955Sakito 		goto shread;
324*59955Sakito 
325*59955Sakito 	/*
326*59955Sakito 	 * Clear BSS Segment
327*59955Sakito 	 */
328*59955Sakito 
329*59955Sakito 	addr += header.a_data;
330*59955Sakito 	printf("+%d", header.a_bss);
331*59955Sakito 	header.a_bss += 128*512;	/* slop */
332*59955Sakito 	for (i = 0; i < header.a_bss; i++)
333*59955Sakito 		*addr++ = 0;
334*59955Sakito 
335*59955Sakito 	return(load);
336*59955Sakito 
337*59955Sakito shread:
338*59955Sakito 	printf("   Short read\n");
339*59955Sakito 	return(0);
340*59955Sakito }
341*59955Sakito 
342*59955Sakito int
343*59955Sakito tread(addr, size)
344*59955Sakito 	int	addr;
345*59955Sakito 	int	size;
346*59955Sakito {
347*59955Sakito 	static u_char	buf[512];
348*59955Sakito 	static int	head = 512;
349*59955Sakito 	static int	tail = 512;
350*59955Sakito 	int             req_size = size;
351*59955Sakito 	int		rest = tail - head;
352*59955Sakito 
353*59955Sakito 	if (rest > 0) {
354*59955Sakito 		if (size <= rest) {
355*59955Sakito 			bcopy(&buf[head], addr, size);
356*59955Sakito 			head += size;
357*59955Sakito 			return size;
358*59955Sakito 		} else { /* size > rest */
359*59955Sakito 			bcopy(&buf[head], addr, rest);
360*59955Sakito 			addr += rest;
361*59955Sakito 			size -= rest;
362*59955Sakito 			if (tail != 512) {
363*59955Sakito 				head = 512;
364*59955Sakito 				tail = 512;
365*59955Sakito 				printf("tread() EOF 0\n");
366*59955Sakito 				return rest;
367*59955Sakito 			}
368*59955Sakito 		}
369*59955Sakito 	}
370*59955Sakito 
371*59955Sakito 	/* head = 0; */
372*59955Sakito 
373*59955Sakito 	while (size > 512) {
374*59955Sakito 		if ((tail = stread(rst0, addr, 512)) == 512) {
375*59955Sakito 			addr += 512;
376*59955Sakito 			size -= 512;
377*59955Sakito 		} else { /* eof ( tail < 512 ) */
378*59955Sakito 			size -= tail;
379*59955Sakito 			head = tail;
380*59955Sakito 			printf("tread() EOF 1\n");
381*59955Sakito 			return req_size - size;
382*59955Sakito 		}
383*59955Sakito 	}
384*59955Sakito 	tail = stread(rst0, buf, 512);
385*59955Sakito 	if (tail >= size) {
386*59955Sakito 		bcopy(buf, addr, size);
387*59955Sakito 		head = size;
388*59955Sakito 		return req_size;
389*59955Sakito 	} else {
390*59955Sakito 		bcopy(buf, addr, tail);
391*59955Sakito 		head = tail;
392*59955Sakito 		printf("tread() EOF 2\n");
393*59955Sakito 		return req_size - size;
394*59955Sakito 	}
395*59955Sakito }
396*59955Sakito 
397*59955Sakito #endif
398*59955Sakito 
399