Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
541
bootfail(Boot *b)
542
{
543
	b->state = FAILED;
544
	return FAIL;
545
}
546
 
547
static int
548
isgzipped(uchar *p)
549
{
550
	return p[0] == 0x1F && p[1] == 0x8B && p[2] == 0x08;
551
}
552
 
553
static int
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
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
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
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
}