xref: /csrg-svn/sys/luna68k/stand/boot.c (revision 63199)
157081Sakito /*
257081Sakito  * Copyright (c) 1992 OMRON Corporation.
3*63199Sbostic  * Copyright (c) 1992, 1993
4*63199Sbostic  *	The Regents of the University of California.  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*63199Sbostic  *	@(#)boot.c	8.1 (Berkeley) 06/10/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 
4759955Sakito #define TAPE
4859955Sakito #ifdef TAPE /* A.Kojima */
4959955Sakito extern dev_t  rst0;
5059955Sakito extern dev_t nrst0;
5159955Sakito char *stcopyunix();
5259955Sakito #endif
5359955Sakito 
5457081Sakito int
how_to_boot(argc,argv)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
get_boot_device(s)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
boot(argc,argv)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 
12959955Sakito #ifdef TAPE /* A.Kojima */
13059955Sakito 	if (!strcmp("st", argv[1])) {
13159955Sakito 		io = argc < 3 ? 0 : *argv[2] - '0';
13259955Sakito 		printf("boot tape file number:%d\n", io);
13359955Sakito 		stbootunix(howto, devtype, io);
13459955Sakito 		return;
13559955Sakito 	}
13659955Sakito #endif
13757081Sakito 	io = open(line, 0);
13857081Sakito 	if (io >= 0) {
13957081Sakito 		bootunix(howto, devtype, io);
14057081Sakito 		close(io);
14157081Sakito 	}
14257081Sakito }
14357081Sakito 
14457081Sakito int
load(argc,argv)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
bootunix(howto,devtype,io)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 *
copyunix(io)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 
24759955Sakito #ifdef TAPE /* A.Kojima */
24859955Sakito int
stbootunix(howto,devtype,skip)24959955Sakito stbootunix(howto, devtype, skip)
25059955Sakito 	register howto;		/* d7 contains boot flags */
25159955Sakito 	register devtype;	/* d6 contains boot device */
25259955Sakito 	register skip;		/* tape skip */
25359955Sakito {
25459955Sakito 	register int i;
25559955Sakito 	register char *load;	/* a5 contains load addr for unix */
25659955Sakito 
25759955Sakito 	/*
25859955Sakito 	 * Tape rewind and skip
25959955Sakito 	 */
26059955Sakito 	st_rewind(rst0);
26159955Sakito 	for (i = 0; i < skip; i++) {
26259955Sakito 		st_skip(rst0);
26359955Sakito 	}
26459955Sakito 
26559955Sakito 	load = stcopyunix();
26659955Sakito 
26759955Sakito 	st_rewind(rst0);
26859955Sakito 
26959955Sakito 	printf(" start 0x%x\n", load);
27059955Sakito 	asm("	movl %0,d7" : : "d" (howto));
27159955Sakito 	asm("	movl %0,d6" : : "d" (devtype));
27259955Sakito 	asm("	movl %0,a5" : : "a" (kiff));
27359955Sakito 	(*((int (*)()) load))();
27459955Sakito }
27559955Sakito 
27659955Sakito char *
stcopyunix()27759955Sakito stcopyunix()
27859955Sakito {
27959955Sakito 
28059955Sakito 	register int i;
28159955Sakito 	register char *load;	/* a5 contains load addr for unix */
28259955Sakito 	register char *addr;
28359955Sakito 	u_char buf[0x400];
28459955Sakito 
28559955Sakito 	/*
28659955Sakito 	 * Read a.out file header
28759955Sakito 	 */
28859955Sakito 
28959955Sakito 	i = tread(/*io,*/ (char *)&header, sizeof(struct exec));
29059955Sakito 	if (i != sizeof(struct exec) ||
29159955Sakito 	    (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
29259955Sakito 		printf("illegal magic number ... 0x%x\n");
29359955Sakito 		printf("Bad format\n");
29459955Sakito 		return(0);
29559955Sakito 	}
29659955Sakito 
29759955Sakito 	load = addr = (char *) (header.a_entry & 0x00FFFFFF);
29859955Sakito 
29959955Sakito 	printf("%d", header.a_text);
30059955Sakito 
30159955Sakito 	i = 0x400 - i;
30259955Sakito 	if (header.a_magic == 0413 && tread(buf, i) != i) { /* easy seek */
30359955Sakito 		goto shread;
30459955Sakito 	}
30559955Sakito 
30659955Sakito 	/*
30759955Sakito 	 * Load TEXT Segment
30859955Sakito 	 */
30959955Sakito 
31059955Sakito 	if (tread(/*io,*/ (char *)addr, header.a_text) != header.a_text)
31159955Sakito 		goto shread;
31259955Sakito 	addr += header.a_text;
31359955Sakito 	if (header.a_magic == 0413 || header.a_magic == 0410)
31459955Sakito 		while ((int)addr & CLOFSET)
31559955Sakito 			*addr++ = 0;
31659955Sakito 
31759955Sakito 	/*
31859955Sakito 	 * Load DATA Segment
31959955Sakito 	 */
32059955Sakito 
32159955Sakito 	printf("+%d", header.a_data);
32259955Sakito 	if (tread(/*io,*/ addr, header.a_data) != header.a_data)
32359955Sakito 		goto shread;
32459955Sakito 
32559955Sakito 	/*
32659955Sakito 	 * Clear BSS Segment
32759955Sakito 	 */
32859955Sakito 
32959955Sakito 	addr += header.a_data;
33059955Sakito 	printf("+%d", header.a_bss);
33159955Sakito 	header.a_bss += 128*512;	/* slop */
33259955Sakito 	for (i = 0; i < header.a_bss; i++)
33359955Sakito 		*addr++ = 0;
33459955Sakito 
33559955Sakito 	return(load);
33659955Sakito 
33759955Sakito shread:
33859955Sakito 	printf("   Short read\n");
33959955Sakito 	return(0);
34059955Sakito }
34159955Sakito 
34259955Sakito int
tread(addr,size)34359955Sakito tread(addr, size)
34459955Sakito 	int	addr;
34559955Sakito 	int	size;
34659955Sakito {
34759955Sakito 	static u_char	buf[512];
34859955Sakito 	static int	head = 512;
34959955Sakito 	static int	tail = 512;
35059955Sakito 	int             req_size = size;
35159955Sakito 	int		rest = tail - head;
35259955Sakito 
35359955Sakito 	if (rest > 0) {
35459955Sakito 		if (size <= rest) {
35559955Sakito 			bcopy(&buf[head], addr, size);
35659955Sakito 			head += size;
35759955Sakito 			return size;
35859955Sakito 		} else { /* size > rest */
35959955Sakito 			bcopy(&buf[head], addr, rest);
36059955Sakito 			addr += rest;
36159955Sakito 			size -= rest;
36259955Sakito 			if (tail != 512) {
36359955Sakito 				head = 512;
36459955Sakito 				tail = 512;
36559955Sakito 				printf("tread() EOF 0\n");
36659955Sakito 				return rest;
36759955Sakito 			}
36859955Sakito 		}
36959955Sakito 	}
37059955Sakito 
37159955Sakito 	/* head = 0; */
37259955Sakito 
37359955Sakito 	while (size > 512) {
37459955Sakito 		if ((tail = stread(rst0, addr, 512)) == 512) {
37559955Sakito 			addr += 512;
37659955Sakito 			size -= 512;
37759955Sakito 		} else { /* eof ( tail < 512 ) */
37859955Sakito 			size -= tail;
37959955Sakito 			head = tail;
38059955Sakito 			printf("tread() EOF 1\n");
38159955Sakito 			return req_size - size;
38259955Sakito 		}
38359955Sakito 	}
38459955Sakito 	tail = stread(rst0, buf, 512);
38559955Sakito 	if (tail >= size) {
38659955Sakito 		bcopy(buf, addr, size);
38759955Sakito 		head = size;
38859955Sakito 		return req_size;
38959955Sakito 	} else {
39059955Sakito 		bcopy(buf, addr, tail);
39159955Sakito 		head = tail;
39259955Sakito 		printf("tread() EOF 2\n");
39359955Sakito 		return req_size - size;
39459955Sakito 	}
39559955Sakito }
39659955Sakito 
39759955Sakito #endif
39859955Sakito 
399