xref: /csrg-svn/sys/pmax/stand/boot.c (revision 58835)
1 /*
2  * Copyright (c) 1992 Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Ralph Campbell.
7  *
8  * %sccs.include.redist.c%
9  *
10  *	@(#)boot.c	7.7 (Berkeley) 03/27/93
11  */
12 
13 #include <sys/param.h>
14 #include <sys/exec.h>
15 
16 char	line[1024];
17 
18 /*
19  * This gets arguments from the PROM, calls other routines to open
20  * and load the program to boot, and then transfers execution to that
21  * new program.
22  * Argv[0] should be something like "rz(0,0,0)vmunix" on a DECstation 3100.
23  * Argv[0,1] should be something like "boot 5/rz0/vmunix" on a DECstation 5000.
24  * The argument "-a" means vmunix should do an automatic reboot.
25  */
26 void
27 main(argc, argv)
28 	int argc;
29 	char **argv;
30 {
31 	register char *cp;
32 	int ask, entry;
33 
34 #ifdef JUSTASK
35 	ask = 1;
36 #else
37 	ask = 0;
38 #ifdef DS3100
39 	for (cp = argv[0]; *cp; cp++) {
40 		if (*cp == ')' && cp[1]) {
41 			cp = argv[0];
42 			goto fnd;
43 		}
44 	}
45 #endif
46 #ifdef DS5000
47 	if (argc > 1) {
48 		argc--;
49 		argv++;
50 		/* look for second '/' as in '5/rz0/vmunix' */
51 		for (cp = argv[0]; *cp; cp++) {
52 			if (*cp == '/') {
53 				while (*++cp) {
54 					if (*cp == '/' && cp[1]) {
55 						cp = argv[0];
56 						goto fnd;
57 					}
58 				}
59 			}
60 		}
61 	}
62 #endif
63 	ask = 1;
64 fnd:
65 	;
66 #endif /* JUSTASK */
67 	for (;;) {
68 		if (ask) {
69 			printf("Boot: ");
70 			gets(line);
71 			if (line[0] == '\0')
72 				continue;
73 			cp = line;
74 			argv[0] = cp;
75 			argc = 1;
76 		} else
77 			printf("Boot: %s\n", cp);
78 		entry = loadfile(cp);
79 		if (entry != -1)
80 			break;
81 		ask = 1;
82 	}
83 	printf("Starting at 0x%x\n\n", entry);
84 	((void (*)())entry)(argc, argv);
85 }
86 
87 /*
88  * Open 'filename', read in program and return the entry point or -1 if error.
89  */
90 loadfile(fname)
91 	register char *fname;
92 {
93 	register struct devices *dp;
94 	register int fd, i, n;
95 	struct exec aout;
96 
97 	if ((fd = open(fname, 0)) < 0) {
98 		goto err;
99 	}
100 
101 	/* read the exec header */
102 	i = read(fd, (char *)&aout, sizeof(aout));
103 	if (i != sizeof(aout)) {
104 		goto cerr;
105 	} else if (aout.a_magic != OMAGIC) {
106 		goto cerr;
107 	}
108 
109 	/* read the code and initialized data */
110 	printf("Size: %d+%d", aout.a_text, aout.a_data);
111 	if (lseek(fd, (off_t)N_TXTOFF(aout), 0) < 0) {
112 		goto cerr;
113 	}
114 	i = aout.a_text + aout.a_data;
115 	n = read(fd, (char *)aout.a_entry, i);
116 #ifndef SMALL
117 	(void) close(fd);
118 #endif
119 	if (n < 0) {
120 		goto err;
121 	} else if (n != i) {
122 		goto err;
123 	}
124 
125 	/* kernel will zero out its own bss */
126 	n = aout.a_bss;
127 	printf("+%d\n", n);
128 
129 	return ((int)aout.a_entry);
130 
131 cerr:
132 #ifndef SMALL
133 	(void) close(fd);
134 #endif
135 err:
136 	printf("Can't boot '%s'\n", fname);
137 	return (-1);
138 }
139