xref: /csrg-svn/sys/pmax/stand/boot.c (revision 52765)
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*52765Sralph  *	@(#)boot.c	7.2 (Berkeley) 03/01/92
1152132Smckusick  */
1252132Smckusick 
13*52765Sralph #include "param.h"
1452132Smckusick #include "reboot.h"
1552132Smckusick #include "exec.h"
1652132Smckusick 
1752132Smckusick #ifndef TEST
1852132Smckusick #define DEF_MONFUNCS
1952132Smckusick #include "../include/machMon.h"
2052132Smckusick #endif
2152132Smckusick 
2252132Smckusick char	line[1024];
2352132Smckusick 
2452132Smckusick /*
2552132Smckusick  * This gets arguments from the PROM, calls other routines to open
2652132Smckusick  * and load the program to boot, and then transfers execution to that
2752132Smckusick  * new program.
28*52765Sralph  * Argv[0] should be something like "rz(0,0,0)vmunix" on a DECstation 3100.
29*52765Sralph  * Argv[0,1] should be something like "boot 5/rz0/vmunix" on a DECstation 5000.
30*52765Sralph  * The argument "-a" means vmunix should do an automatic reboot.
3152132Smckusick  */
3252132Smckusick void
3352132Smckusick main(argc, argv, argenv)
3452132Smckusick 	int argc;
3552132Smckusick 	char **argv;
3652132Smckusick 	char **argenv;
3752132Smckusick {
3852132Smckusick 	register char *cp;
3952132Smckusick 	int howto, entry;
40*52765Sralph 	char *boot = "boot";
4152132Smckusick 
4252132Smckusick #ifdef JUSTASK
43*52765Sralph 	howto = RB_ASKNAME;
4452132Smckusick #else
45*52765Sralph 	if (argc > 0 && strcmp(argv[0], boot) == 0) {
46*52765Sralph 		argc--;
47*52765Sralph 		argv++;
48*52765Sralph 		argv[0] = getenv(boot);
49*52765Sralph 		printf("boot '%s'\n", argv[0]); /* XXX */
50*52765Sralph 	}
51*52765Sralph 	howto = 0;
5252132Smckusick 	for (cp = argv[0]; *cp; cp++) {
5352132Smckusick 		if (*cp == ')' && cp[1]) {
5452132Smckusick 			cp = argv[0];
5552132Smckusick 			goto fnd;
5652132Smckusick 		}
5752132Smckusick 	}
5852132Smckusick 	howto |= RB_ASKNAME;
5952132Smckusick fnd:
6052132Smckusick 	;
6152132Smckusick #endif
6252132Smckusick 	for (;;) {
6352132Smckusick 		if (howto & RB_ASKNAME) {
6452132Smckusick 			printf("Boot: ");
6552132Smckusick 			gets(line);
6652132Smckusick 			if (line[0] == '\0')
6752132Smckusick 				continue;
6852132Smckusick 			cp = line;
69*52765Sralph 			argv[0] = cp;
70*52765Sralph 			argc = 1;
7152132Smckusick 		} else
7252132Smckusick 			printf("Boot: %s\n", cp);
7352132Smckusick 		entry = loadfile(cp);
7452132Smckusick 		if (entry != -1)
7552132Smckusick 			break;
76*52765Sralph 		howto = RB_ASKNAME;
7752132Smckusick 	}
7852132Smckusick #ifndef TEST
7952132Smckusick 	Boot_Transfer(argc, argv, argenv, entry);
8052132Smckusick #endif
8152132Smckusick }
8252132Smckusick 
8352132Smckusick /*
8452132Smckusick  * Open 'filename', read in program and return the entry point or -1 if error.
8552132Smckusick  */
8652132Smckusick loadfile(fname)
8752132Smckusick 	register char *fname;
8852132Smckusick {
8952132Smckusick 	register struct devices *dp;
9052132Smckusick 	register int fd, i, n;
9152132Smckusick 	struct exec aout;
9252132Smckusick 
9352132Smckusick 	if ((fd = Open(fname, 0)) < 0)
9452132Smckusick 		goto err;
9552132Smckusick 
9652132Smckusick 	/* read the COFF header */
9752132Smckusick 	i = Read(fd, (char *)&aout, sizeof(aout));
9852132Smckusick 	if (i != sizeof(aout)) {
9952132Smckusick 		printf("No a.out header\n");
10052132Smckusick 		goto cerr;
10152132Smckusick 	} else if (aout.a_magic != OMAGIC) {
10252132Smckusick 		printf("A.out? magic 0%o size %d+%d+%d\n", aout.a_magic,
10352132Smckusick 			aout.a_text, aout.a_data, aout.a_bss);
10452132Smckusick 		goto cerr;
10552132Smckusick 	}
10652132Smckusick 
10752132Smckusick 	/* read the code and initialized data */
10852132Smckusick 	printf("Size: %d+%d", aout.a_text, aout.a_data);
10952132Smckusick 	if (Lseek(fd, N_TXTOFF(aout), 0) < 0) {
11052132Smckusick 		printf("\nSeek error\n");
11152132Smckusick 		goto cerr;
11252132Smckusick 	}
11352132Smckusick 	i = aout.a_text + aout.a_data;
11452132Smckusick #ifndef TEST
11552132Smckusick 	n = Read(fd, (char *)aout.ex_aout.codeStart, i);
11652132Smckusick #else
11752132Smckusick 	n = i;
11852132Smckusick #endif
11952132Smckusick 	(void) Close(fd);
12052132Smckusick 	if (n < 0) {
12152132Smckusick 		printf("\nRead error\n");
12252132Smckusick 		goto err;
12352132Smckusick 	} else if (n != i) {
12452132Smckusick 		printf("\nShort read (%d)\n", n);
12552132Smckusick 		goto err;
12652132Smckusick 	}
12752132Smckusick 
12852132Smckusick 	/* kernel will zero out its own bss */
12952132Smckusick 	n = aout.a_bss;
13052132Smckusick 	printf("+%d\n", n);
13152132Smckusick 
13252132Smckusick 	return ((int)aout.a_entry);
13352132Smckusick 
13452132Smckusick cerr:
13552132Smckusick 	(void) Close(fd);
13652132Smckusick err:
13752132Smckusick 	return (-1);
13852132Smckusick }
139