1 /*
2 * Copyright (c) 1992 OMRON Corporation.
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * OMRON Corporation.
8 *
9 * %sccs.include.redist.c%
10 *
11 * @(#)boot.c 8.1 (Berkeley) 06/10/93
12 */
13
14 /*
15 * boot.c -- boot program
16 * by A.Fujita, MAR-01-1992
17 */
18
19 #include <sys/param.h>
20 #include <sys/reboot.h>
21 #include <sys/exec.h>
22 #include <machine/stinger.h>
23 #include <luna68k/stand/saio.h>
24 #include <luna68k/stand/status.h>
25
26 extern struct KernInter *kiff;
27
28 int howto;
29 int devtype = MAKEBOOTDEV(4, 0, 6, 0, 0);
30
31 char *copyunix();
32
33 struct exec header;
34 char default_file[] = "sd(0,0)vmunix";
35
36 char *how_to_info[] = {
37 "RB_ASKNAME ask for file name to reboot from",
38 "RB_SINGLE reboot to single user only",
39 "RB_NOSYNC dont sync before reboot",
40 "RB_HALT don't reboot, just halt",
41 "RB_INITNAME name given for /etc/init (unused)",
42 "RB_DFLTROOT use compiled-in rootdev",
43 "RB_KDB give control to kernel debugger",
44 "RB_RDONLY mount root fs read-only"
45 };
46
47 #define TAPE
48 #ifdef TAPE /* A.Kojima */
49 extern dev_t rst0;
50 extern dev_t nrst0;
51 char *stcopyunix();
52 #endif
53
54 int
how_to_boot(argc,argv)55 how_to_boot(argc, argv)
56 int argc;
57 char *argv[];
58 {
59 int i, h = howto;
60
61 if (argc < 2) {
62 printf("howto: 0x%s\n\n", hexstr(howto, 2));
63
64 if (h == 0) {
65 printf("\t%s\n", "RB_AUTOBOOT flags for system auto-booting itself");
66 } else {
67 for (i = 0; i < 8; i++, h >>= 1) {
68 if (h & 0x01) {
69 printf("\t%s\n", how_to_info[i]);
70 }
71 }
72 }
73
74 printf("\n");
75 }
76 }
77
78 int
get_boot_device(s)79 get_boot_device(s)
80 char *s;
81 {
82 register int unit = 0;
83 register int part = 0;
84 register char *p = s;
85
86 while (*p != '(') {
87 if (*p == '\0')
88 goto error;
89 p++;
90 }
91
92 while (*++p != ',') {
93 if (*p == '\0')
94 goto error;
95 if (*p >= '0' && *p <= '9')
96 unit = (unit * 10) + (*p - '0');
97 }
98
99 while (*++p != ')') {
100 if (*p == '\0')
101 goto error;
102 if (*p >= '0' && *p <= '9')
103 part = (part * 10) + (*p - '0');
104 }
105
106 return(MAKEBOOTDEV(4, 0, (6 - unit), unit, part));
107
108 error:
109 return(MAKEBOOTDEV(4, 0, 6, 0, 0));
110 }
111
112 int
boot(argc,argv)113 boot(argc, argv)
114 int argc;
115 char *argv[];
116 {
117 register int io;
118 char *line;
119
120 if (argc < 2)
121 line = default_file;
122 else
123 line = argv[1];
124
125 devtype = get_boot_device(line);
126
127 printf("Booting %s\n", line);
128
129 #ifdef TAPE /* A.Kojima */
130 if (!strcmp("st", argv[1])) {
131 io = argc < 3 ? 0 : *argv[2] - '0';
132 printf("boot tape file number:%d\n", io);
133 stbootunix(howto, devtype, io);
134 return;
135 }
136 #endif
137 io = open(line, 0);
138 if (io >= 0) {
139 bootunix(howto, devtype, io);
140 close(io);
141 }
142 }
143
144 int
load(argc,argv)145 load(argc, argv)
146 int argc;
147 char *argv[];
148 {
149 register int io;
150 char *line;
151
152 if (argc < 2)
153 line = default_file;
154 else
155 line = argv[1];
156
157 printf("loading %s\n", line);
158
159 io = open(line, 0);
160 if (io >= 0) {
161 copyunix(io);
162 printf("\n");
163 close(io);
164 }
165 }
166
167 int
bootunix(howto,devtype,io)168 bootunix(howto, devtype, io)
169 register howto; /* d7 contains boot flags */
170 register devtype; /* d6 contains boot device */
171 register io;
172 {
173 register char *load; /* a5 contains load addr for unix */
174
175 load = copyunix(io);
176
177 printf(" start 0x%x\n", load);
178 asm(" movl %0,d7" : : "d" (howto));
179 asm(" movl %0,d6" : : "d" (devtype));
180 asm(" movl %0,a5" : : "a" (kiff));
181 (*((int (*)()) load))();
182 }
183
184 char *
copyunix(io)185 copyunix(io)
186 register io;
187 {
188
189 register int i;
190 register char *load; /* a5 contains load addr for unix */
191 register char *addr;
192
193 /*
194 * Read a.out file header
195 */
196
197 i = read(io, (char *)&header, sizeof(struct exec));
198 if (i != sizeof(struct exec) ||
199 (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
200 printf("illegal magic number ... 0x%x\n");
201 printf("Bad format\n");
202 return(0);
203 }
204
205 load = addr = (char *) (header.a_entry & 0x00FFFFFF);
206
207 printf("%d", header.a_text);
208 if (header.a_magic == 0413 && lseek(io, 0x400, 0) == -1)
209 goto shread;
210
211 /*
212 * Load TEXT Segment
213 */
214
215 if (read(io, (char *)addr, header.a_text) != header.a_text)
216 goto shread;
217 addr += header.a_text;
218 if (header.a_magic == 0413 || header.a_magic == 0410)
219 while ((int)addr & CLOFSET)
220 *addr++ = 0;
221
222 /*
223 * Load DATA Segment
224 */
225
226 printf("+%d", header.a_data);
227 if (read(io, addr, header.a_data) != header.a_data)
228 goto shread;
229
230 /*
231 * Clear BSS Segment
232 */
233
234 addr += header.a_data;
235 printf("+%d", header.a_bss);
236 header.a_bss += 128*512; /* slop */
237 for (i = 0; i < header.a_bss; i++)
238 *addr++ = 0;
239
240 return(load);
241
242 shread:
243 printf(" Short read\n");
244 return(0);
245 }
246
247 #ifdef TAPE /* A.Kojima */
248 int
stbootunix(howto,devtype,skip)249 stbootunix(howto, devtype, skip)
250 register howto; /* d7 contains boot flags */
251 register devtype; /* d6 contains boot device */
252 register skip; /* tape skip */
253 {
254 register int i;
255 register char *load; /* a5 contains load addr for unix */
256
257 /*
258 * Tape rewind and skip
259 */
260 st_rewind(rst0);
261 for (i = 0; i < skip; i++) {
262 st_skip(rst0);
263 }
264
265 load = stcopyunix();
266
267 st_rewind(rst0);
268
269 printf(" start 0x%x\n", load);
270 asm(" movl %0,d7" : : "d" (howto));
271 asm(" movl %0,d6" : : "d" (devtype));
272 asm(" movl %0,a5" : : "a" (kiff));
273 (*((int (*)()) load))();
274 }
275
276 char *
stcopyunix()277 stcopyunix()
278 {
279
280 register int i;
281 register char *load; /* a5 contains load addr for unix */
282 register char *addr;
283 u_char buf[0x400];
284
285 /*
286 * Read a.out file header
287 */
288
289 i = tread(/*io,*/ (char *)&header, sizeof(struct exec));
290 if (i != sizeof(struct exec) ||
291 (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
292 printf("illegal magic number ... 0x%x\n");
293 printf("Bad format\n");
294 return(0);
295 }
296
297 load = addr = (char *) (header.a_entry & 0x00FFFFFF);
298
299 printf("%d", header.a_text);
300
301 i = 0x400 - i;
302 if (header.a_magic == 0413 && tread(buf, i) != i) { /* easy seek */
303 goto shread;
304 }
305
306 /*
307 * Load TEXT Segment
308 */
309
310 if (tread(/*io,*/ (char *)addr, header.a_text) != header.a_text)
311 goto shread;
312 addr += header.a_text;
313 if (header.a_magic == 0413 || header.a_magic == 0410)
314 while ((int)addr & CLOFSET)
315 *addr++ = 0;
316
317 /*
318 * Load DATA Segment
319 */
320
321 printf("+%d", header.a_data);
322 if (tread(/*io,*/ addr, header.a_data) != header.a_data)
323 goto shread;
324
325 /*
326 * Clear BSS Segment
327 */
328
329 addr += header.a_data;
330 printf("+%d", header.a_bss);
331 header.a_bss += 128*512; /* slop */
332 for (i = 0; i < header.a_bss; i++)
333 *addr++ = 0;
334
335 return(load);
336
337 shread:
338 printf(" Short read\n");
339 return(0);
340 }
341
342 int
tread(addr,size)343 tread(addr, size)
344 int addr;
345 int size;
346 {
347 static u_char buf[512];
348 static int head = 512;
349 static int tail = 512;
350 int req_size = size;
351 int rest = tail - head;
352
353 if (rest > 0) {
354 if (size <= rest) {
355 bcopy(&buf[head], addr, size);
356 head += size;
357 return size;
358 } else { /* size > rest */
359 bcopy(&buf[head], addr, rest);
360 addr += rest;
361 size -= rest;
362 if (tail != 512) {
363 head = 512;
364 tail = 512;
365 printf("tread() EOF 0\n");
366 return rest;
367 }
368 }
369 }
370
371 /* head = 0; */
372
373 while (size > 512) {
374 if ((tail = stread(rst0, addr, 512)) == 512) {
375 addr += 512;
376 size -= 512;
377 } else { /* eof ( tail < 512 ) */
378 size -= tail;
379 head = tail;
380 printf("tread() EOF 1\n");
381 return req_size - size;
382 }
383 }
384 tail = stread(rst0, buf, 512);
385 if (tail >= size) {
386 bcopy(buf, addr, size);
387 head = size;
388 return req_size;
389 } else {
390 bcopy(buf, addr, tail);
391 head = tail;
392 printf("tread() EOF 2\n");
393 return req_size - size;
394 }
395 }
396
397 #endif
398
399