xref: /csrg-svn/sys/pmax/stand/boot.c (revision 56526)
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*56526Sbostic  *	@(#)boot.c	7.4 (Berkeley) 10/11/92
1152132Smckusick  */
1252132Smckusick 
13*56526Sbostic #include <sys/param.h>
14*56526Sbostic #include <sys/reboot.h>
15*56526Sbostic #include <sys/exec.h>
1652132Smckusick 
1752132Smckusick #ifndef TEST
1852132Smckusick #define DEF_MONFUNCS
19*56526Sbostic #include <machine/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.
2852765Sralph  * Argv[0] should be something like "rz(0,0,0)vmunix" on a DECstation 3100.
2952765Sralph  * Argv[0,1] should be something like "boot 5/rz0/vmunix" on a DECstation 5000.
3052765Sralph  * 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;
4052765Sralph 	char *boot = "boot";
4152132Smckusick 
4252132Smckusick #ifdef JUSTASK
4352765Sralph 	howto = RB_ASKNAME;
4452132Smckusick #else
4552765Sralph 	if (argc > 0 && strcmp(argv[0], boot) == 0) {
4652765Sralph 		argc--;
4752765Sralph 		argv++;
4852765Sralph 		argv[0] = getenv(boot);
4952765Sralph 	}
5052765Sralph 	howto = 0;
5152132Smckusick 	for (cp = argv[0]; *cp; cp++) {
5252132Smckusick 		if (*cp == ')' && cp[1]) {
5352132Smckusick 			cp = argv[0];
5452132Smckusick 			goto fnd;
5552132Smckusick 		}
5652132Smckusick 	}
5752132Smckusick 	howto |= RB_ASKNAME;
5852132Smckusick fnd:
5952132Smckusick 	;
6052132Smckusick #endif
6152132Smckusick 	for (;;) {
6252132Smckusick 		if (howto & RB_ASKNAME) {
6352132Smckusick 			printf("Boot: ");
6452132Smckusick 			gets(line);
6552132Smckusick 			if (line[0] == '\0')
6652132Smckusick 				continue;
6752132Smckusick 			cp = line;
6852765Sralph 			argv[0] = cp;
6952765Sralph 			argc = 1;
7052132Smckusick 		} else
7152132Smckusick 			printf("Boot: %s\n", cp);
7252132Smckusick 		entry = loadfile(cp);
7352132Smckusick 		if (entry != -1)
7452132Smckusick 			break;
7552765Sralph 		howto = RB_ASKNAME;
7652132Smckusick 	}
7752132Smckusick #ifndef TEST
7852132Smckusick 	Boot_Transfer(argc, argv, argenv, entry);
7952132Smckusick #endif
8052132Smckusick }
8152132Smckusick 
8252132Smckusick /*
8352132Smckusick  * Open 'filename', read in program and return the entry point or -1 if error.
8452132Smckusick  */
8552132Smckusick loadfile(fname)
8652132Smckusick 	register char *fname;
8752132Smckusick {
8852132Smckusick 	register struct devices *dp;
8952132Smckusick 	register int fd, i, n;
9052132Smckusick 	struct exec aout;
9152132Smckusick 
9252132Smckusick 	if ((fd = Open(fname, 0)) < 0)
9352132Smckusick 		goto err;
9452132Smckusick 
9552132Smckusick 	/* read the COFF header */
9652132Smckusick 	i = Read(fd, (char *)&aout, sizeof(aout));
9752132Smckusick 	if (i != sizeof(aout)) {
9852132Smckusick 		printf("No a.out header\n");
9952132Smckusick 		goto cerr;
10052132Smckusick 	} else if (aout.a_magic != OMAGIC) {
10152132Smckusick 		printf("A.out? magic 0%o size %d+%d+%d\n", aout.a_magic,
10252132Smckusick 			aout.a_text, aout.a_data, aout.a_bss);
10352132Smckusick 		goto cerr;
10452132Smckusick 	}
10552132Smckusick 
10652132Smckusick 	/* read the code and initialized data */
10752132Smckusick 	printf("Size: %d+%d", aout.a_text, aout.a_data);
10852132Smckusick 	if (Lseek(fd, N_TXTOFF(aout), 0) < 0) {
10952132Smckusick 		printf("\nSeek error\n");
11052132Smckusick 		goto cerr;
11152132Smckusick 	}
11252132Smckusick 	i = aout.a_text + aout.a_data;
11352132Smckusick #ifndef TEST
11452132Smckusick 	n = Read(fd, (char *)aout.ex_aout.codeStart, i);
11552132Smckusick #else
11652132Smckusick 	n = i;
11752132Smckusick #endif
11852132Smckusick 	(void) Close(fd);
11952132Smckusick 	if (n < 0) {
12052132Smckusick 		printf("\nRead error\n");
12152132Smckusick 		goto err;
12252132Smckusick 	} else if (n != i) {
12352132Smckusick 		printf("\nShort read (%d)\n", n);
12452132Smckusick 		goto err;
12552132Smckusick 	}
12652132Smckusick 
12752132Smckusick 	/* kernel will zero out its own bss */
12852132Smckusick 	n = aout.a_bss;
12952132Smckusick 	printf("+%d\n", n);
13052132Smckusick 
13152132Smckusick 	return ((int)aout.a_entry);
13252132Smckusick 
13352132Smckusick cerr:
13452132Smckusick 	(void) Close(fd);
13552132Smckusick err:
13652132Smckusick 	return (-1);
13752132Smckusick }
138