xref: /original-bsd/sys/pmax/stand/boot.c (revision 5ec50ca3)
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.5 (Berkeley) 10/24/92
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 	char *boot = "boot";
34 
35 #ifdef JUSTASK
36 	ask = 1;
37 #else
38 	ask = 0;
39 #ifdef DS3100
40 	for (cp = argv[0]; *cp; cp++) {
41 		if (*cp == ')' && cp[1]) {
42 			cp = argv[0];
43 			goto fnd;
44 		}
45 	}
46 #endif
47 #ifdef DS5000
48 	if (argc > 1) {
49 		argc--;
50 		argv++;
51 		/* look for second '/' as in '5/rz0/vmunix' */
52 		for (cp = argv[0]; *cp; cp++) {
53 			if (*cp == '/') {
54 				while (*++cp) {
55 					if (*cp == '/' && cp[1]) {
56 						cp = argv[0];
57 						goto fnd;
58 					}
59 				}
60 			}
61 		}
62 	}
63 #endif
64 	ask = 1;
65 fnd:
66 	;
67 #endif /* JUSTASK */
68 	for (;;) {
69 		if (ask) {
70 			printf("Boot: ");
71 			gets(line);
72 			if (line[0] == '\0')
73 				continue;
74 			cp = line;
75 			argv[0] = cp;
76 			argc = 1;
77 		} else
78 			printf("Boot: %s\n", cp);
79 		entry = loadfile(cp);
80 		if (entry != -1)
81 			break;
82 		ask = 1;
83 	}
84 	printf("Starting at 0x%x\n\n", entry);
85 	((void (*)())entry)(argc, argv);
86 }
87 
88 /*
89  * Open 'filename', read in program and return the entry point or -1 if error.
90  */
91 loadfile(fname)
92 	register char *fname;
93 {
94 	register struct devices *dp;
95 	register int fd, i, n;
96 	struct exec aout;
97 
98 	if ((fd = open(fname, 0)) < 0) {
99 		printf("Can't open '%s'\n", fname);
100 		goto err;
101 	}
102 
103 	/* read the COFF header */
104 	i = read(fd, (char *)&aout, sizeof(aout));
105 	if (i != sizeof(aout)) {
106 		printf("No a.out header\n");
107 		goto cerr;
108 	} else if (aout.a_magic != OMAGIC) {
109 		printf("A.out? magic 0%o size %d+%d+%d\n", aout.a_magic,
110 			aout.a_text, aout.a_data, aout.a_bss);
111 		goto cerr;
112 	}
113 
114 	/* read the code and initialized data */
115 	printf("Size: %d+%d", aout.a_text, aout.a_data);
116 	if (lseek(fd, (off_t)N_TXTOFF(aout), 0) < 0) {
117 		printf("\nSeek error\n");
118 		goto cerr;
119 	}
120 	i = aout.a_text + aout.a_data;
121 #ifndef TEST
122 	n = read(fd, (char *)aout.ex_aout.codeStart, i);
123 #else
124 	n = i;
125 #endif
126 	(void) close(fd);
127 	if (n < 0) {
128 		printf("\nRead error\n");
129 		goto err;
130 	} else if (n != i) {
131 		printf("\nShort read (%d)\n", n);
132 		goto err;
133 	}
134 
135 	/* kernel will zero out its own bss */
136 	n = aout.a_bss;
137 	printf("+%d\n", n);
138 
139 	return ((int)aout.a_entry);
140 
141 cerr:
142 	(void) close(fd);
143 err:
144 	return (-1);
145 }
146