xref: /csrg-svn/sys/pmax/stand/boot.c (revision 56638)
152132Smckusick /*
252132Smckusick  * Copyright (c) 1992 Regents of the University of California.
352132Smckusick  * All rights reserved.
452132Smckusick  *
552132Smckusick  * This code is derived from software contributed to Berkeley by
652132Smckusick  * Ralph Campbell.
752132Smckusick  *
852132Smckusick  * %sccs.include.redist.c%
952132Smckusick  *
10*56638Sralph  *	@(#)boot.c	7.5 (Berkeley) 10/24/92
1152132Smckusick  */
1252132Smckusick 
1356526Sbostic #include <sys/param.h>
1456526Sbostic #include <sys/exec.h>
1552132Smckusick 
1652132Smckusick char	line[1024];
1752132Smckusick 
1852132Smckusick /*
1952132Smckusick  * This gets arguments from the PROM, calls other routines to open
2052132Smckusick  * and load the program to boot, and then transfers execution to that
2152132Smckusick  * new program.
2252765Sralph  * Argv[0] should be something like "rz(0,0,0)vmunix" on a DECstation 3100.
2352765Sralph  * Argv[0,1] should be something like "boot 5/rz0/vmunix" on a DECstation 5000.
2452765Sralph  * The argument "-a" means vmunix should do an automatic reboot.
2552132Smckusick  */
2652132Smckusick void
27*56638Sralph main(argc, argv)
2852132Smckusick 	int argc;
2952132Smckusick 	char **argv;
3052132Smckusick {
3152132Smckusick 	register char *cp;
32*56638Sralph 	int ask, entry;
3352765Sralph 	char *boot = "boot";
3452132Smckusick 
3552132Smckusick #ifdef JUSTASK
36*56638Sralph 	ask = 1;
3752132Smckusick #else
38*56638Sralph 	ask = 0;
39*56638Sralph #ifdef DS3100
4052132Smckusick 	for (cp = argv[0]; *cp; cp++) {
4152132Smckusick 		if (*cp == ')' && cp[1]) {
4252132Smckusick 			cp = argv[0];
4352132Smckusick 			goto fnd;
4452132Smckusick 		}
4552132Smckusick 	}
46*56638Sralph #endif
47*56638Sralph #ifdef DS5000
48*56638Sralph 	if (argc > 1) {
49*56638Sralph 		argc--;
50*56638Sralph 		argv++;
51*56638Sralph 		/* look for second '/' as in '5/rz0/vmunix' */
52*56638Sralph 		for (cp = argv[0]; *cp; cp++) {
53*56638Sralph 			if (*cp == '/') {
54*56638Sralph 				while (*++cp) {
55*56638Sralph 					if (*cp == '/' && cp[1]) {
56*56638Sralph 						cp = argv[0];
57*56638Sralph 						goto fnd;
58*56638Sralph 					}
59*56638Sralph 				}
60*56638Sralph 			}
61*56638Sralph 		}
62*56638Sralph 	}
63*56638Sralph #endif
64*56638Sralph 	ask = 1;
6552132Smckusick fnd:
6652132Smckusick 	;
67*56638Sralph #endif /* JUSTASK */
6852132Smckusick 	for (;;) {
69*56638Sralph 		if (ask) {
7052132Smckusick 			printf("Boot: ");
7152132Smckusick 			gets(line);
7252132Smckusick 			if (line[0] == '\0')
7352132Smckusick 				continue;
7452132Smckusick 			cp = line;
7552765Sralph 			argv[0] = cp;
7652765Sralph 			argc = 1;
7752132Smckusick 		} else
7852132Smckusick 			printf("Boot: %s\n", cp);
7952132Smckusick 		entry = loadfile(cp);
8052132Smckusick 		if (entry != -1)
8152132Smckusick 			break;
82*56638Sralph 		ask = 1;
8352132Smckusick 	}
84*56638Sralph 	printf("Starting at 0x%x\n\n", entry);
85*56638Sralph 	((void (*)())entry)(argc, argv);
8652132Smckusick }
8752132Smckusick 
8852132Smckusick /*
8952132Smckusick  * Open 'filename', read in program and return the entry point or -1 if error.
9052132Smckusick  */
9152132Smckusick loadfile(fname)
9252132Smckusick 	register char *fname;
9352132Smckusick {
9452132Smckusick 	register struct devices *dp;
9552132Smckusick 	register int fd, i, n;
9652132Smckusick 	struct exec aout;
9752132Smckusick 
98*56638Sralph 	if ((fd = open(fname, 0)) < 0) {
99*56638Sralph 		printf("Can't open '%s'\n", fname);
10052132Smckusick 		goto err;
101*56638Sralph 	}
10252132Smckusick 
10352132Smckusick 	/* read the COFF header */
104*56638Sralph 	i = read(fd, (char *)&aout, sizeof(aout));
10552132Smckusick 	if (i != sizeof(aout)) {
10652132Smckusick 		printf("No a.out header\n");
10752132Smckusick 		goto cerr;
10852132Smckusick 	} else if (aout.a_magic != OMAGIC) {
10952132Smckusick 		printf("A.out? magic 0%o size %d+%d+%d\n", aout.a_magic,
11052132Smckusick 			aout.a_text, aout.a_data, aout.a_bss);
11152132Smckusick 		goto cerr;
11252132Smckusick 	}
11352132Smckusick 
11452132Smckusick 	/* read the code and initialized data */
11552132Smckusick 	printf("Size: %d+%d", aout.a_text, aout.a_data);
116*56638Sralph 	if (lseek(fd, (off_t)N_TXTOFF(aout), 0) < 0) {
11752132Smckusick 		printf("\nSeek error\n");
11852132Smckusick 		goto cerr;
11952132Smckusick 	}
12052132Smckusick 	i = aout.a_text + aout.a_data;
12152132Smckusick #ifndef TEST
122*56638Sralph 	n = read(fd, (char *)aout.ex_aout.codeStart, i);
12352132Smckusick #else
12452132Smckusick 	n = i;
12552132Smckusick #endif
126*56638Sralph 	(void) close(fd);
12752132Smckusick 	if (n < 0) {
12852132Smckusick 		printf("\nRead error\n");
12952132Smckusick 		goto err;
13052132Smckusick 	} else if (n != i) {
13152132Smckusick 		printf("\nShort read (%d)\n", n);
13252132Smckusick 		goto err;
13352132Smckusick 	}
13452132Smckusick 
13552132Smckusick 	/* kernel will zero out its own bss */
13652132Smckusick 	n = aout.a_bss;
13752132Smckusick 	printf("+%d\n", n);
13852132Smckusick 
13952132Smckusick 	return ((int)aout.a_entry);
14052132Smckusick 
14152132Smckusick cerr:
142*56638Sralph 	(void) close(fd);
14352132Smckusick err:
14452132Smckusick 	return (-1);
14552132Smckusick }
146