1 /*
2 * load kernel into memory
3 */
4 #include "u.h"
5 #include "../port/lib.h"
6 #include "mem.h"
7 #include "dat.h"
8 #include "fns.h"
9 #include "io.h"
10 #include "ureg.h"
11 #include "pool.h"
12 #include "../port/netif.h"
13 #include "../ip/ip.h"
14 #include "pxe.h"
15
16 #include <a.out.h>
17 #include "/sys/src/libmach/elf.h"
18
19 #undef KADDR
20 #undef PADDR
21
22 #define KADDR(a) ((void*)((ulong)(a) | KZERO))
23 #define PADDR(a) ((ulong)(a) & ~KSEGM)
24
25 extern int debug;
26
27 extern void pagingoff(ulong);
28
29 static uchar elfident[] = {
30 '\177', 'E', 'L', 'F',
31 };
32 static Ehdr ehdr, rehdr;
33 static E64hdr e64hdr;
34 static Phdr *phdr;
35 static P64hdr *p64hdr;
36
37 static int curphdr;
38 static ulong curoff;
39 static ulong elftotal;
40
41 static uvlong (*swav)(uvlong);
42 static long (*swal)(long);
43 static ushort (*swab)(ushort);
44
45 /*
46 * big-endian short
47 */
48 ushort
beswab(ushort s)49 beswab(ushort s)
50 {
51 uchar *p;
52
53 p = (uchar*)&s;
54 return (p[0]<<8) | p[1];
55 }
56
57 /*
58 * big-endian long
59 */
60 long
beswal(long l)61 beswal(long l)
62 {
63 uchar *p;
64
65 p = (uchar*)&l;
66 return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
67 }
68
69 /*
70 * big-endian vlong
71 */
72 uvlong
beswav(uvlong v)73 beswav(uvlong v)
74 {
75 uchar *p;
76
77 p = (uchar*)&v;
78 return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40)
79 | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24)
80 | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8)
81 | (uvlong)p[7];
82 }
83
84 /*
85 * little-endian short
86 */
87 ushort
leswab(ushort s)88 leswab(ushort s)
89 {
90 uchar *p;
91
92 p = (uchar*)&s;
93 return (p[1]<<8) | p[0];
94 }
95
96 /*
97 * little-endian long
98 */
99 long
leswal(long l)100 leswal(long l)
101 {
102 uchar *p;
103
104 p = (uchar*)&l;
105 return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
106 }
107
108 /*
109 * little-endian vlong
110 */
111 uvlong
leswav(uvlong v)112 leswav(uvlong v)
113 {
114 uchar *p;
115
116 p = (uchar*)&v;
117 return ((uvlong)p[7]<<56) | ((uvlong)p[6]<<48) | ((uvlong)p[5]<<40)
118 | ((uvlong)p[4]<<32) | ((uvlong)p[3]<<24)
119 | ((uvlong)p[2]<<16) | ((uvlong)p[1]<<8)
120 | (uvlong)p[0];
121 }
122
123 /*
124 * Convert header to canonical form
125 */
126 static void
hswal(long * lp,int n,long (* swap)(long))127 hswal(long *lp, int n, long (*swap) (long))
128 {
129 while (n--) {
130 *lp = (*swap) (*lp);
131 lp++;
132 }
133 }
134
135 static void
hswav(uvlong * lp,int n,uvlong (* swap)(uvlong))136 hswav(uvlong *lp, int n, uvlong (*swap)(uvlong))
137 {
138 while (n--) {
139 *lp = (*swap)(*lp);
140 lp++;
141 }
142 }
143
144 static int
readehdr(Boot * b)145 readehdr(Boot *b)
146 {
147 int i;
148
149 /* bitswap the header according to the DATA format */
150 if(ehdr.ident[CLASS] != ELFCLASS32) {
151 print("bad ELF class - not 32 bit\n");
152 return 0;
153 }
154 if(ehdr.ident[DATA] == ELFDATA2LSB) {
155 swab = leswab;
156 swal = leswal;
157 } else if(ehdr.ident[DATA] == ELFDATA2MSB) {
158 swab = beswab;
159 swal = beswal;
160 } else {
161 print("bad ELF encoding - not big or little endian\n");
162 return 0;
163 }
164 memmove(&rehdr, &ehdr, sizeof(Ehdr)); /* copy; never used */
165
166 ehdr.type = swab(ehdr.type);
167 ehdr.machine = swab(ehdr.machine);
168 ehdr.version = swal(ehdr.version);
169 ehdr.elfentry = swal(ehdr.elfentry);
170 ehdr.phoff = swal(ehdr.phoff);
171 ehdr.shoff = swal(ehdr.shoff);
172 ehdr.flags = swal(ehdr.flags);
173 ehdr.ehsize = swab(ehdr.ehsize);
174 ehdr.phentsize = swab(ehdr.phentsize);
175 ehdr.phnum = swab(ehdr.phnum);
176 ehdr.shentsize = swab(ehdr.shentsize);
177 ehdr.shnum = swab(ehdr.shnum);
178 ehdr.shstrndx = swab(ehdr.shstrndx);
179 if(ehdr.type != EXEC || ehdr.version != CURRENT)
180 return 0;
181 if(ehdr.phentsize != sizeof(Phdr))
182 return 0;
183
184 if(debug)
185 print("readehdr OK entry %#lux\n", ehdr.elfentry);
186
187 curoff = sizeof(Ehdr);
188 i = ehdr.phoff+ehdr.phentsize*ehdr.phnum - curoff;
189 b->state = READPHDR;
190 b->bp = (char*)smalloc(i);
191 b->wp = b->bp;
192 b->ep = b->wp + i;
193 elftotal = 0;
194 phdr = (Phdr*)(b->bp + ehdr.phoff-sizeof(Ehdr));
195 if(debug)
196 print("phdr...");
197
198 return 1;
199 }
200
201 static int
reade64hdr(Boot * b)202 reade64hdr(Boot *b)
203 {
204 int i;
205
206 /* bitswap the header according to the DATA format */
207 if(e64hdr.ident[CLASS] != ELFCLASS64) {
208 print("bad ELF class - not 64 bit\n");
209 return 0;
210 }
211 if(e64hdr.ident[DATA] == ELFDATA2LSB) {
212 swab = leswab;
213 swal = leswal;
214 swav = leswav;
215 } else if(e64hdr.ident[DATA] == ELFDATA2MSB) {
216 swab = beswab;
217 swal = beswal;
218 swav = beswav;
219 } else {
220 print("bad ELF encoding - not big or little endian\n");
221 return 0;
222 }
223 // memmove(&rehdr, &ehdr, sizeof(Ehdr)); /* copy; never used */
224
225 e64hdr.type = swab(e64hdr.type);
226 e64hdr.machine = swab(e64hdr.machine);
227 e64hdr.version = swal(e64hdr.version);
228 e64hdr.elfentry = swav(e64hdr.elfentry);
229 e64hdr.phoff = swav(e64hdr.phoff);
230 e64hdr.shoff = swav(e64hdr.shoff);
231 e64hdr.flags = swal(e64hdr.flags);
232 e64hdr.ehsize = swab(e64hdr.ehsize);
233 e64hdr.phentsize = swab(e64hdr.phentsize);
234 e64hdr.phnum = swab(e64hdr.phnum);
235 e64hdr.shentsize = swab(e64hdr.shentsize);
236 e64hdr.shnum = swab(e64hdr.shnum);
237 e64hdr.shstrndx = swab(e64hdr.shstrndx);
238 if(e64hdr.type != EXEC || e64hdr.version != CURRENT)
239 return 0;
240 if(e64hdr.phentsize != sizeof(P64hdr))
241 return 0;
242
243 if(debug)
244 print("reade64hdr OK entry %#llux\n", e64hdr.elfentry);
245
246 curoff = sizeof(E64hdr);
247 i = e64hdr.phoff + e64hdr.phentsize*e64hdr.phnum - curoff;
248 b->state = READ64PHDR;
249 b->bp = (char*)smalloc(i);
250 b->wp = b->bp;
251 b->ep = b->wp + i;
252 elftotal = 0;
253 p64hdr = (P64hdr*)(b->bp + e64hdr.phoff-sizeof(E64hdr));
254 if(debug)
255 print("p64hdr...");
256
257 return 1;
258 }
259
260 static int
nextphdr(Boot * b)261 nextphdr(Boot *b)
262 {
263 Phdr *php;
264 ulong offset;
265 char *physaddr;
266
267 if(debug)
268 print("readedata %d\n", curphdr);
269
270 for(; curphdr < ehdr.phnum; curphdr++){
271 php = phdr+curphdr;
272 if(php->type != LOAD)
273 continue;
274 offset = php->offset;
275 physaddr = (char*)KADDR(PADDR(php->paddr));
276 if(offset < curoff){
277 /*
278 * Can't (be bothered to) rewind the
279 * input, it might be from tftp. If we
280 * did then we could boot FreeBSD kernels
281 * too maybe.
282 */
283 return 0;
284 }
285 if(php->offset > curoff){
286 b->state = READEPAD;
287 b->bp = (char*)smalloc(offset - curoff);
288 b->wp = b->bp;
289 b->ep = b->wp + offset - curoff;
290 if(debug)
291 print("nextphdr %lud...\n", offset - curoff);
292 return 1;
293 }
294 b->state = READEDATA;
295 b->bp = physaddr;
296 b->wp = b->bp;
297 b->ep = b->wp+php->filesz;
298 print("%ud+", php->filesz);
299 elftotal += php->filesz;
300 if(debug)
301 print("nextphdr %ud@%#p\n", php->filesz, physaddr);
302
303 return 1;
304 }
305
306 if(curphdr != 0){
307 print("=%lud\n", elftotal);
308 b->state = TRYEBOOT;
309 b->entry = ehdr.elfentry;
310 // PLLONG(b->hdr.entry, b->entry);
311 return 1;
312 }
313
314 return 0;
315 }
316
317 static int
nextp64hdr(Boot * b)318 nextp64hdr(Boot *b)
319 {
320 P64hdr *php;
321 uvlong offset;
322 char *physaddr;
323
324 if(debug)
325 print("reade64data %d\n", curphdr);
326
327 for(; curphdr < e64hdr.phnum; curphdr++){
328 php = p64hdr+curphdr;
329 if(php->type != LOAD)
330 continue;
331 offset = php->offset;
332 physaddr = (char*)KADDR(PADDR(php->paddr));
333 if(offset < curoff){
334 /*
335 * Can't (be bothered to) rewind the
336 * input, it might be from tftp. If we
337 * did then we could boot FreeBSD kernels
338 * too maybe.
339 */
340 return 0;
341 }
342 if(php->offset > curoff){
343 b->state = READE64PAD;
344 b->bp = (char*)smalloc(offset - curoff);
345 b->wp = b->bp;
346 b->ep = b->wp + offset - curoff;
347 if(debug)
348 print("nextp64hdr %llud...\n", offset - curoff);
349 return 1;
350 }
351 b->state = READE64DATA;
352 b->bp = physaddr;
353 b->wp = b->bp;
354 b->ep = b->wp+php->filesz;
355 print("%llud+", php->filesz);
356 elftotal += php->filesz;
357 if(debug)
358 print("nextp64hdr %llud@%#p\n", php->filesz, physaddr);
359
360 return 1;
361 }
362
363 if(curphdr != 0){
364 print("=%lud\n", elftotal);
365 b->state = TRYE64BOOT;
366 b->entry = e64hdr.elfentry;
367 return 1;
368 }
369
370 return 0;
371 }
372
373 static int
readepad(Boot * b)374 readepad(Boot *b)
375 {
376 Phdr *php;
377
378 php = phdr+curphdr;
379 if(debug)
380 print("readepad %d\n", curphdr);
381 curoff = php->offset;
382
383 return nextphdr(b);
384 }
385
386 static int
reade64pad(Boot * b)387 reade64pad(Boot *b)
388 {
389 P64hdr *php;
390
391 php = p64hdr+curphdr;
392 if(debug)
393 print("reade64pad %d\n", curphdr);
394 curoff = php->offset;
395
396 return nextp64hdr(b);
397 }
398
399 static int
readedata(Boot * b)400 readedata(Boot *b)
401 {
402 Phdr *php;
403
404 php = phdr+curphdr;
405 if(debug)
406 print("readedata %d\n", curphdr);
407 if(php->filesz < php->memsz){
408 print("%lud", php->memsz-php->filesz);
409 elftotal += php->memsz-php->filesz;
410 memset((char*)KADDR(PADDR(php->paddr)+php->filesz), 0,
411 php->memsz-php->filesz);
412 }
413 curoff = php->offset+php->filesz;
414 curphdr++;
415
416 return nextphdr(b);
417 }
418
419 static int
reade64data(Boot * b)420 reade64data(Boot *b)
421 {
422 P64hdr *php;
423
424 php = p64hdr+curphdr;
425 if(debug)
426 print("reade64data %d\n", curphdr);
427 if(php->filesz < php->memsz){
428 print("%llud", php->memsz - php->filesz);
429 elftotal += php->memsz - php->filesz;
430 memset((char*)KADDR(PADDR(php->paddr) + php->filesz), 0,
431 php->memsz - php->filesz);
432 }
433 curoff = php->offset + php->filesz;
434 curphdr++;
435
436 return nextp64hdr(b);
437 }
438
439 static int
readphdr(Boot * b)440 readphdr(Boot *b)
441 {
442 Phdr *php;
443
444 php = phdr;
445 hswal((long*)php, ehdr.phentsize*ehdr.phnum/sizeof(long), swal);
446 if(debug)
447 print("phdr curoff %lud vaddr %#lux paddr %#lux\n",
448 curoff, php->vaddr, php->paddr);
449
450 curoff = ehdr.phoff+ehdr.phentsize*ehdr.phnum;
451 curphdr = 0;
452
453 return nextphdr(b);
454 }
455
456 static int
readp64hdr(Boot * b)457 readp64hdr(Boot *b)
458 {
459 int hdr;
460 P64hdr *php, *p;
461
462 php = p = p64hdr;
463 for (hdr = 0; hdr < e64hdr.phnum; hdr++, p++) {
464 hswal((long*)p, 2, swal);
465 hswav((uvlong*)&p->offset, 6, swav);
466 }
467 if(debug)
468 print("p64hdr curoff %lud vaddr %#llux paddr %#llux\n",
469 curoff, php->vaddr, php->paddr);
470
471 curoff = e64hdr.phoff + e64hdr.phentsize*e64hdr.phnum;
472 curphdr = 0;
473
474 return nextp64hdr(b);
475 }
476
477 static int
addbytes(char ** dbuf,char * edbuf,char ** sbuf,char * esbuf)478 addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
479 {
480 int n;
481
482 n = edbuf - *dbuf;
483 if(n <= 0)
484 return 0; /* dest buffer is full */
485 if(n > esbuf - *sbuf)
486 n = esbuf - *sbuf;
487 if(n <= 0)
488 return -1; /* src buffer is empty */
489
490 memmove(*dbuf, *sbuf, n);
491 *sbuf += n;
492 *dbuf += n;
493 return edbuf - *dbuf;
494 }
495
496 void
impulse(void)497 impulse(void)
498 {
499 delay(500); /* drain uart */
500 splhi();
501
502 /* turn off buffered serial console */
503 serialoq = nil;
504
505 /* shutdown devices */
506 chandevshutdown();
507 arch->introff();
508 }
509
510 void
prstackuse(int)511 prstackuse(int)
512 {
513 char *top, *base;
514 ulong *p;
515
516 base = up->kstack;
517 top = up->kstack + KSTACK - (sizeof(Sargs) + BY2WD);
518 for (p = (ulong *)base; (char *)p < top && *p ==
519 (Stkpat<<24 | Stkpat<<16 | Stkpat<<8 | Stkpat); p++)
520 ;
521 print("proc stack: used %ld bytes, %ld left (stack pattern)\n",
522 top - (char *)p, (char *)p - base);
523 }
524
525 /*
526 * this code is simplified from reboot(). It doesn't need to relocate
527 * the new kernel nor deal with other processors.
528 */
529 void
warp9(ulong entry)530 warp9(ulong entry)
531 {
532 // prstackuse(0); /* debugging */
533 mkmultiboot();
534 impulse();
535
536 /* get out of KZERO space, turn off paging and jump to entry */
537 pagingoff(PADDR(entry));
538 }
539
540 static int
bootfail(Boot * b)541 bootfail(Boot *b)
542 {
543 b->state = FAILED;
544 return FAIL;
545 }
546
547 static int
isgzipped(uchar * p)548 isgzipped(uchar *p)
549 {
550 return p[0] == 0x1F && p[1] == 0x8B && p[2] == 0x08;
551 }
552
553 static int
readexec(Boot * b)554 readexec(Boot *b)
555 {
556 Exechdr *hdr;
557 ulong pentry, text, data, magic;
558
559 hdr = &b->hdr;
560 magic = GLLONG(hdr->magic);
561 if(magic == I_MAGIC || magic == S_MAGIC) {
562 pentry = PADDR(GLLONG(hdr->entry));
563 text = GLLONG(hdr->text);
564 data = GLLONG(hdr->data);
565 if (pentry < MB)
566 panic("kernel entry %#p below 1 MB", pentry);
567 if (PGROUND(pentry + text) + data > MB + Kernelmax)
568 panic("kernel larger than %d bytes", Kernelmax);
569 b->state = READ9TEXT;
570 b->bp = (char*)KADDR(pentry);
571 b->wp = b->bp;
572 b->ep = b->wp+text;
573
574 if(magic == I_MAGIC){
575 memmove(b->bp, b->hdr.uvl, sizeof(b->hdr.uvl));
576 b->wp += sizeof(b->hdr.uvl);
577 }
578
579 print("%lud", text);
580 } else if(memcmp(b->bp, elfident, 4) == 0 &&
581 (uchar)b->bp[4] == ELFCLASS32){
582 b->state = READEHDR;
583 b->bp = (char*)&ehdr;
584 b->wp = b->bp;
585 b->ep = b->wp + sizeof(Ehdr);
586 memmove(b->bp, &b->hdr, sizeof(Exechdr));
587 b->wp += sizeof(Exechdr);
588 print("elf...");
589 } else if(memcmp(b->bp, elfident, 4) == 0 &&
590 (uchar)b->bp[4] == ELFCLASS64){
591 b->state = READE64HDR;
592 b->bp = (char*)&e64hdr;
593 b->wp = b->bp;
594 b->ep = b->wp + sizeof(E64hdr);
595 memmove(b->bp, &b->hdr, sizeof(Exechdr));
596 b->wp += sizeof(Exechdr);
597 print("elf64...");
598 } else if(isgzipped((uchar *)b->bp)) {
599 b->state = READGZIP;
600 /* could use Unzipbuf instead of smalloc() */
601 b->bp = (char*)smalloc(Kernelmax);
602 b->wp = b->bp;
603 b->ep = b->wp + Kernelmax;
604 memmove(b->bp, &b->hdr, sizeof(Exechdr));
605 b->wp += sizeof(Exechdr);
606 print("gz...");
607 } else {
608 print("bad kernel format (magic %#lux)\n", magic);
609 return bootfail(b);
610 }
611 return MORE;
612 }
613
614 static void
boot9(Boot * b,ulong magic,ulong entry)615 boot9(Boot *b, ulong magic, ulong entry)
616 {
617 if(magic == I_MAGIC){
618 print("entry: %#lux\n", entry);
619 warp9(PADDR(entry));
620 }
621 else if(magic == S_MAGIC)
622 warp64(beswav(b->hdr.uvl[0]));
623 else
624 print("bad magic %#lux\n", magic);
625 }
626
627 /* only returns upon failure */
628 static void
readgzip(Boot * b)629 readgzip(Boot *b)
630 {
631 ulong entry, text, data, bss, magic, all, pentry;
632 uchar *sdata;
633 Exechdr *hdr;
634
635 /* the whole gzipped kernel is now at b->bp */
636 hdr = &b->hdr;
637 if(!isgzipped((uchar *)b->bp)) {
638 print("lost magic\n");
639 return;
640 }
641 print("%ld => ", b->wp - b->bp);
642 /* just fill hdr from gzipped b->bp, to get various sizes */
643 if(gunzip((uchar*)hdr, sizeof *hdr, (uchar*)b->bp, b->wp - b->bp)
644 < sizeof *hdr) {
645 print("error uncompressing kernel exec header\n");
646 return;
647 }
648
649 /* assume uncompressed kernel is a plan 9 boot image */
650 magic = GLLONG(hdr->magic);
651 entry = GLLONG(hdr->entry);
652 text = GLLONG(hdr->text);
653 data = GLLONG(hdr->data);
654 bss = GLLONG(hdr->bss);
655 print("%lud+%lud+%lud=%lud\n", text, data, bss, text+data+bss);
656
657 pentry = PADDR(entry);
658 if (pentry < MB)
659 panic("kernel entry %#p below 1 MB", pentry);
660 if (PGROUND(pentry + text) + data > MB + Kernelmax)
661 panic("kernel larger than %d bytes", Kernelmax);
662
663 /* fill entry from gzipped b->bp */
664 all = sizeof(Exec) + text + data;
665 if(gunzip((uchar *)KADDR(PADDR(entry)) - sizeof(Exec), all,
666 (uchar*)b->bp, b->wp - b->bp) < all) {
667 print("error uncompressing kernel\n");
668 return;
669 }
670
671 /* relocate data to start at page boundary */
672 sdata = KADDR(PADDR(entry+text));
673 memmove((void*)PGROUND((uintptr)sdata), sdata, data);
674
675 boot9(b, magic, entry);
676 }
677
678 /*
679 * if nbuf is zero, boot.
680 * else add nbuf bytes from vbuf to b->wp (if there is room)
681 * and advance the state machine, which may reset b's pointers
682 * and return to the top.
683 */
684 int
bootpass(Boot * b,void * vbuf,int nbuf)685 bootpass(Boot *b, void *vbuf, int nbuf)
686 {
687 char *buf, *ebuf;
688 Exechdr *hdr;
689 ulong entry, bss;
690 uvlong entry64;
691
692 if(b->state == FAILED)
693 return FAIL;
694
695 if(nbuf == 0)
696 goto Endofinput;
697
698 buf = vbuf;
699 ebuf = buf+nbuf;
700 /* possibly copy into b->wp from buf (not first time) */
701 while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) {
702 /* b->bp is full, so advance the state machine */
703 switch(b->state) {
704 case INITKERNEL:
705 b->state = READEXEC;
706 b->bp = (char*)&b->hdr;
707 b->wp = b->bp;
708 b->ep = b->bp+sizeof(Exechdr);
709 break;
710 case READEXEC:
711 readexec(b);
712 break;
713
714 case READ9TEXT:
715 hdr = &b->hdr;
716 b->state = READ9DATA;
717 b->bp = (char*)PGROUND((uintptr)
718 KADDR(PADDR(GLLONG(hdr->entry))) +
719 GLLONG(hdr->text));
720 b->wp = b->bp;
721 b->ep = b->wp + GLLONG(hdr->data);
722 print("+%ld", GLLONG(hdr->data));
723 break;
724
725 case READ9DATA:
726 hdr = &b->hdr;
727 bss = GLLONG(hdr->bss);
728 memset(b->ep, 0, bss);
729 print("+%ld=%ld\n",
730 bss, GLLONG(hdr->text)+GLLONG(hdr->data)+bss);
731 b->state = TRYBOOT;
732 return ENOUGH;
733
734 /*
735 * elf
736 */
737 case READEHDR:
738 if(!readehdr(b))
739 print("readehdr failed\n");
740 break;
741 case READPHDR:
742 readphdr(b);
743 break;
744 case READEPAD:
745 readepad(b);
746 break;
747 case READEDATA:
748 readedata(b);
749 if(b->state == TRYEBOOT)
750 return ENOUGH;
751 break;
752
753 /*
754 * elf64
755 */
756 case READE64HDR:
757 if(!reade64hdr(b))
758 print("reade64hdr failed\n");
759 break;
760 case READ64PHDR:
761 readp64hdr(b);
762 break;
763 case READE64PAD:
764 reade64pad(b);
765 break;
766 case READE64DATA:
767 reade64data(b);
768 if(b->state == TRYE64BOOT)
769 return ENOUGH;
770 break;
771
772 case TRYBOOT:
773 case TRYEBOOT:
774 case TRYE64BOOT:
775 case READGZIP:
776 return ENOUGH;
777
778 case READ9LOAD:
779 case INIT9LOAD:
780 panic("9load");
781
782 default:
783 panic("bootstate");
784 }
785 if(b->state == FAILED)
786 return FAIL;
787 }
788 return MORE;
789
790 Endofinput:
791 /* end of input */
792 switch(b->state) {
793 case INITKERNEL:
794 case READEXEC:
795 case READ9TEXT:
796 case READ9DATA:
797 case READEHDR:
798 case READPHDR:
799 case READEPAD:
800 case READEDATA:
801 case READE64HDR:
802 case READ64PHDR:
803 case READE64PAD:
804 case READE64DATA:
805 print("premature EOF\n");
806 break;
807
808 case TRYBOOT:
809 boot9(b, GLLONG(b->hdr.magic), GLLONG(b->hdr.entry));
810 break;
811
812 case TRYEBOOT:
813 entry = b->entry;
814 if(ehdr.machine == I386){
815 print("entry: %#lux\n", entry);
816 warp9(PADDR(entry));
817 }
818 else if(ehdr.machine == AMD64)
819 warp64(entry);
820 else
821 panic("elf boot: ehdr.machine %d unknown", ehdr.machine);
822 break;
823
824 case TRYE64BOOT:
825 entry64 = b->entry;
826 if(e64hdr.machine == I386){
827 print("entry: %#llux\n", entry64);
828 warp9(PADDR(entry64));
829 }
830 else if(e64hdr.machine == AMD64)
831 warp64(entry64);
832 else
833 panic("elf64 boot: e64hdr.machine %d unknown",
834 e64hdr.machine);
835 break;
836
837 case READGZIP:
838 readgzip(b);
839 break;
840
841 case INIT9LOAD:
842 case READ9LOAD:
843 panic("end 9load");
844
845 default:
846 panic("bootdone");
847 }
848 return bootfail(b);
849 }
850