125210b06SDavid du Colombier /*
225210b06SDavid du Colombier * load kernel into memory
325210b06SDavid du Colombier */
425210b06SDavid du Colombier #include "u.h"
525210b06SDavid du Colombier #include "../port/lib.h"
625210b06SDavid du Colombier #include "mem.h"
725210b06SDavid du Colombier #include "dat.h"
825210b06SDavid du Colombier #include "fns.h"
925210b06SDavid du Colombier #include "io.h"
1025210b06SDavid du Colombier #include "ureg.h"
1125210b06SDavid du Colombier #include "pool.h"
1225210b06SDavid du Colombier #include "../port/netif.h"
1325210b06SDavid du Colombier #include "../ip/ip.h"
1425210b06SDavid du Colombier #include "pxe.h"
1525210b06SDavid du Colombier
1625210b06SDavid du Colombier #include <a.out.h>
1725210b06SDavid du Colombier #include "/sys/src/libmach/elf.h"
1825210b06SDavid du Colombier
1925210b06SDavid du Colombier #undef KADDR
2025210b06SDavid du Colombier #undef PADDR
2125210b06SDavid du Colombier
2225210b06SDavid du Colombier #define KADDR(a) ((void*)((ulong)(a) | KZERO))
2325210b06SDavid du Colombier #define PADDR(a) ((ulong)(a) & ~KSEGM)
2425210b06SDavid du Colombier
2525210b06SDavid du Colombier extern int debug;
26*62579e34SDavid du Colombier
2725210b06SDavid du Colombier extern void pagingoff(ulong);
2825210b06SDavid du Colombier
29*62579e34SDavid du Colombier static uchar elfident[] = {
30*62579e34SDavid du Colombier '\177', 'E', 'L', 'F',
3125210b06SDavid du Colombier };
3225210b06SDavid du Colombier static Ehdr ehdr, rehdr;
33*62579e34SDavid du Colombier static E64hdr e64hdr;
3425210b06SDavid du Colombier static Phdr *phdr;
35*62579e34SDavid du Colombier static P64hdr *p64hdr;
36*62579e34SDavid du Colombier
3725210b06SDavid du Colombier static int curphdr;
3825210b06SDavid du Colombier static ulong curoff;
3925210b06SDavid du Colombier static ulong elftotal;
40*62579e34SDavid du Colombier
41*62579e34SDavid du Colombier static uvlong (*swav)(uvlong);
4225210b06SDavid du Colombier static long (*swal)(long);
4325210b06SDavid du Colombier static ushort (*swab)(ushort);
4425210b06SDavid du Colombier
4525210b06SDavid du Colombier /*
4625210b06SDavid du Colombier * big-endian short
4725210b06SDavid du Colombier */
4825210b06SDavid du Colombier ushort
beswab(ushort s)4925210b06SDavid du Colombier beswab(ushort s)
5025210b06SDavid du Colombier {
5125210b06SDavid du Colombier uchar *p;
5225210b06SDavid du Colombier
5325210b06SDavid du Colombier p = (uchar*)&s;
5425210b06SDavid du Colombier return (p[0]<<8) | p[1];
5525210b06SDavid du Colombier }
5625210b06SDavid du Colombier
5725210b06SDavid du Colombier /*
5825210b06SDavid du Colombier * big-endian long
5925210b06SDavid du Colombier */
6025210b06SDavid du Colombier long
beswal(long l)6125210b06SDavid du Colombier beswal(long l)
6225210b06SDavid du Colombier {
6325210b06SDavid du Colombier uchar *p;
6425210b06SDavid du Colombier
6525210b06SDavid du Colombier p = (uchar*)&l;
6625210b06SDavid du Colombier return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
6725210b06SDavid du Colombier }
6825210b06SDavid du Colombier
6925210b06SDavid du Colombier /*
7025210b06SDavid du Colombier * big-endian vlong
7125210b06SDavid du Colombier */
7225210b06SDavid du Colombier uvlong
beswav(uvlong v)7325210b06SDavid du Colombier beswav(uvlong v)
7425210b06SDavid du Colombier {
7525210b06SDavid du Colombier uchar *p;
7625210b06SDavid du Colombier
7725210b06SDavid du Colombier p = (uchar*)&v;
7825210b06SDavid du Colombier return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40)
7925210b06SDavid du Colombier | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24)
8025210b06SDavid du Colombier | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8)
8125210b06SDavid du Colombier | (uvlong)p[7];
8225210b06SDavid du Colombier }
8325210b06SDavid du Colombier
8425210b06SDavid du Colombier /*
8525210b06SDavid du Colombier * little-endian short
8625210b06SDavid du Colombier */
8725210b06SDavid du Colombier ushort
leswab(ushort s)8825210b06SDavid du Colombier leswab(ushort s)
8925210b06SDavid du Colombier {
9025210b06SDavid du Colombier uchar *p;
9125210b06SDavid du Colombier
9225210b06SDavid du Colombier p = (uchar*)&s;
9325210b06SDavid du Colombier return (p[1]<<8) | p[0];
9425210b06SDavid du Colombier }
9525210b06SDavid du Colombier
9625210b06SDavid du Colombier /*
9725210b06SDavid du Colombier * little-endian long
9825210b06SDavid du Colombier */
9925210b06SDavid du Colombier long
leswal(long l)10025210b06SDavid du Colombier leswal(long l)
10125210b06SDavid du Colombier {
10225210b06SDavid du Colombier uchar *p;
10325210b06SDavid du Colombier
10425210b06SDavid du Colombier p = (uchar*)&l;
10525210b06SDavid du Colombier return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
10625210b06SDavid du Colombier }
10725210b06SDavid du Colombier
10825210b06SDavid du Colombier /*
109*62579e34SDavid du Colombier * little-endian vlong
110*62579e34SDavid du Colombier */
111*62579e34SDavid du Colombier uvlong
leswav(uvlong v)112*62579e34SDavid du Colombier leswav(uvlong v)
113*62579e34SDavid du Colombier {
114*62579e34SDavid du Colombier uchar *p;
115*62579e34SDavid du Colombier
116*62579e34SDavid du Colombier p = (uchar*)&v;
117*62579e34SDavid du Colombier return ((uvlong)p[7]<<56) | ((uvlong)p[6]<<48) | ((uvlong)p[5]<<40)
118*62579e34SDavid du Colombier | ((uvlong)p[4]<<32) | ((uvlong)p[3]<<24)
119*62579e34SDavid du Colombier | ((uvlong)p[2]<<16) | ((uvlong)p[1]<<8)
120*62579e34SDavid du Colombier | (uvlong)p[0];
121*62579e34SDavid du Colombier }
122*62579e34SDavid du Colombier
123*62579e34SDavid du Colombier /*
12425210b06SDavid du Colombier * Convert header to canonical form
12525210b06SDavid du Colombier */
12625210b06SDavid du Colombier static void
hswal(long * lp,int n,long (* swap)(long))12725210b06SDavid du Colombier hswal(long *lp, int n, long (*swap) (long))
12825210b06SDavid du Colombier {
12925210b06SDavid du Colombier while (n--) {
13025210b06SDavid du Colombier *lp = (*swap) (*lp);
13125210b06SDavid du Colombier lp++;
13225210b06SDavid du Colombier }
13325210b06SDavid du Colombier }
13425210b06SDavid du Colombier
135*62579e34SDavid du Colombier static void
hswav(uvlong * lp,int n,uvlong (* swap)(uvlong))136*62579e34SDavid du Colombier hswav(uvlong *lp, int n, uvlong (*swap)(uvlong))
137*62579e34SDavid du Colombier {
138*62579e34SDavid du Colombier while (n--) {
139*62579e34SDavid du Colombier *lp = (*swap)(*lp);
140*62579e34SDavid du Colombier lp++;
141*62579e34SDavid du Colombier }
142*62579e34SDavid du Colombier }
143*62579e34SDavid du Colombier
14425210b06SDavid du Colombier static int
readehdr(Boot * b)14525210b06SDavid du Colombier readehdr(Boot *b)
14625210b06SDavid du Colombier {
14725210b06SDavid du Colombier int i;
14825210b06SDavid du Colombier
14925210b06SDavid du Colombier /* bitswap the header according to the DATA format */
15025210b06SDavid du Colombier if(ehdr.ident[CLASS] != ELFCLASS32) {
15125210b06SDavid du Colombier print("bad ELF class - not 32 bit\n");
15225210b06SDavid du Colombier return 0;
15325210b06SDavid du Colombier }
15425210b06SDavid du Colombier if(ehdr.ident[DATA] == ELFDATA2LSB) {
15525210b06SDavid du Colombier swab = leswab;
15625210b06SDavid du Colombier swal = leswal;
15725210b06SDavid du Colombier } else if(ehdr.ident[DATA] == ELFDATA2MSB) {
15825210b06SDavid du Colombier swab = beswab;
15925210b06SDavid du Colombier swal = beswal;
16025210b06SDavid du Colombier } else {
16125210b06SDavid du Colombier print("bad ELF encoding - not big or little endian\n");
16225210b06SDavid du Colombier return 0;
16325210b06SDavid du Colombier }
164*62579e34SDavid du Colombier memmove(&rehdr, &ehdr, sizeof(Ehdr)); /* copy; never used */
16525210b06SDavid du Colombier
16625210b06SDavid du Colombier ehdr.type = swab(ehdr.type);
16725210b06SDavid du Colombier ehdr.machine = swab(ehdr.machine);
16825210b06SDavid du Colombier ehdr.version = swal(ehdr.version);
16925210b06SDavid du Colombier ehdr.elfentry = swal(ehdr.elfentry);
17025210b06SDavid du Colombier ehdr.phoff = swal(ehdr.phoff);
17125210b06SDavid du Colombier ehdr.shoff = swal(ehdr.shoff);
17225210b06SDavid du Colombier ehdr.flags = swal(ehdr.flags);
17325210b06SDavid du Colombier ehdr.ehsize = swab(ehdr.ehsize);
17425210b06SDavid du Colombier ehdr.phentsize = swab(ehdr.phentsize);
17525210b06SDavid du Colombier ehdr.phnum = swab(ehdr.phnum);
17625210b06SDavid du Colombier ehdr.shentsize = swab(ehdr.shentsize);
17725210b06SDavid du Colombier ehdr.shnum = swab(ehdr.shnum);
17825210b06SDavid du Colombier ehdr.shstrndx = swab(ehdr.shstrndx);
17925210b06SDavid du Colombier if(ehdr.type != EXEC || ehdr.version != CURRENT)
18025210b06SDavid du Colombier return 0;
18125210b06SDavid du Colombier if(ehdr.phentsize != sizeof(Phdr))
18225210b06SDavid du Colombier return 0;
18325210b06SDavid du Colombier
18425210b06SDavid du Colombier if(debug)
18525210b06SDavid du Colombier print("readehdr OK entry %#lux\n", ehdr.elfentry);
18625210b06SDavid du Colombier
18725210b06SDavid du Colombier curoff = sizeof(Ehdr);
18825210b06SDavid du Colombier i = ehdr.phoff+ehdr.phentsize*ehdr.phnum - curoff;
18925210b06SDavid du Colombier b->state = READPHDR;
19025210b06SDavid du Colombier b->bp = (char*)smalloc(i);
19125210b06SDavid du Colombier b->wp = b->bp;
19225210b06SDavid du Colombier b->ep = b->wp + i;
193*62579e34SDavid du Colombier elftotal = 0;
19425210b06SDavid du Colombier phdr = (Phdr*)(b->bp + ehdr.phoff-sizeof(Ehdr));
19525210b06SDavid du Colombier if(debug)
19625210b06SDavid du Colombier print("phdr...");
19725210b06SDavid du Colombier
19825210b06SDavid du Colombier return 1;
19925210b06SDavid du Colombier }
20025210b06SDavid du Colombier
20125210b06SDavid du Colombier static int
reade64hdr(Boot * b)202*62579e34SDavid du Colombier reade64hdr(Boot *b)
203*62579e34SDavid du Colombier {
204*62579e34SDavid du Colombier int i;
205*62579e34SDavid du Colombier
206*62579e34SDavid du Colombier /* bitswap the header according to the DATA format */
207*62579e34SDavid du Colombier if(e64hdr.ident[CLASS] != ELFCLASS64) {
208*62579e34SDavid du Colombier print("bad ELF class - not 64 bit\n");
209*62579e34SDavid du Colombier return 0;
210*62579e34SDavid du Colombier }
211*62579e34SDavid du Colombier if(e64hdr.ident[DATA] == ELFDATA2LSB) {
212*62579e34SDavid du Colombier swab = leswab;
213*62579e34SDavid du Colombier swal = leswal;
214*62579e34SDavid du Colombier swav = leswav;
215*62579e34SDavid du Colombier } else if(e64hdr.ident[DATA] == ELFDATA2MSB) {
216*62579e34SDavid du Colombier swab = beswab;
217*62579e34SDavid du Colombier swal = beswal;
218*62579e34SDavid du Colombier swav = beswav;
219*62579e34SDavid du Colombier } else {
220*62579e34SDavid du Colombier print("bad ELF encoding - not big or little endian\n");
221*62579e34SDavid du Colombier return 0;
222*62579e34SDavid du Colombier }
223*62579e34SDavid du Colombier // memmove(&rehdr, &ehdr, sizeof(Ehdr)); /* copy; never used */
224*62579e34SDavid du Colombier
225*62579e34SDavid du Colombier e64hdr.type = swab(e64hdr.type);
226*62579e34SDavid du Colombier e64hdr.machine = swab(e64hdr.machine);
227*62579e34SDavid du Colombier e64hdr.version = swal(e64hdr.version);
228*62579e34SDavid du Colombier e64hdr.elfentry = swav(e64hdr.elfentry);
229*62579e34SDavid du Colombier e64hdr.phoff = swav(e64hdr.phoff);
230*62579e34SDavid du Colombier e64hdr.shoff = swav(e64hdr.shoff);
231*62579e34SDavid du Colombier e64hdr.flags = swal(e64hdr.flags);
232*62579e34SDavid du Colombier e64hdr.ehsize = swab(e64hdr.ehsize);
233*62579e34SDavid du Colombier e64hdr.phentsize = swab(e64hdr.phentsize);
234*62579e34SDavid du Colombier e64hdr.phnum = swab(e64hdr.phnum);
235*62579e34SDavid du Colombier e64hdr.shentsize = swab(e64hdr.shentsize);
236*62579e34SDavid du Colombier e64hdr.shnum = swab(e64hdr.shnum);
237*62579e34SDavid du Colombier e64hdr.shstrndx = swab(e64hdr.shstrndx);
238*62579e34SDavid du Colombier if(e64hdr.type != EXEC || e64hdr.version != CURRENT)
239*62579e34SDavid du Colombier return 0;
240*62579e34SDavid du Colombier if(e64hdr.phentsize != sizeof(P64hdr))
241*62579e34SDavid du Colombier return 0;
242*62579e34SDavid du Colombier
243*62579e34SDavid du Colombier if(debug)
244*62579e34SDavid du Colombier print("reade64hdr OK entry %#llux\n", e64hdr.elfentry);
245*62579e34SDavid du Colombier
246*62579e34SDavid du Colombier curoff = sizeof(E64hdr);
247*62579e34SDavid du Colombier i = e64hdr.phoff + e64hdr.phentsize*e64hdr.phnum - curoff;
248*62579e34SDavid du Colombier b->state = READ64PHDR;
249*62579e34SDavid du Colombier b->bp = (char*)smalloc(i);
250*62579e34SDavid du Colombier b->wp = b->bp;
251*62579e34SDavid du Colombier b->ep = b->wp + i;
252*62579e34SDavid du Colombier elftotal = 0;
253*62579e34SDavid du Colombier p64hdr = (P64hdr*)(b->bp + e64hdr.phoff-sizeof(E64hdr));
254*62579e34SDavid du Colombier if(debug)
255*62579e34SDavid du Colombier print("p64hdr...");
256*62579e34SDavid du Colombier
257*62579e34SDavid du Colombier return 1;
258*62579e34SDavid du Colombier }
259*62579e34SDavid du Colombier
260*62579e34SDavid du Colombier static int
nextphdr(Boot * b)26125210b06SDavid du Colombier nextphdr(Boot *b)
26225210b06SDavid du Colombier {
26325210b06SDavid du Colombier Phdr *php;
264*62579e34SDavid du Colombier ulong offset;
26525210b06SDavid du Colombier char *physaddr;
26625210b06SDavid du Colombier
26725210b06SDavid du Colombier if(debug)
26825210b06SDavid du Colombier print("readedata %d\n", curphdr);
26925210b06SDavid du Colombier
27025210b06SDavid du Colombier for(; curphdr < ehdr.phnum; curphdr++){
27125210b06SDavid du Colombier php = phdr+curphdr;
27225210b06SDavid du Colombier if(php->type != LOAD)
27325210b06SDavid du Colombier continue;
27425210b06SDavid du Colombier offset = php->offset;
27525210b06SDavid du Colombier physaddr = (char*)KADDR(PADDR(php->paddr));
27625210b06SDavid du Colombier if(offset < curoff){
27725210b06SDavid du Colombier /*
27825210b06SDavid du Colombier * Can't (be bothered to) rewind the
27925210b06SDavid du Colombier * input, it might be from tftp. If we
28025210b06SDavid du Colombier * did then we could boot FreeBSD kernels
28125210b06SDavid du Colombier * too maybe.
28225210b06SDavid du Colombier */
28325210b06SDavid du Colombier return 0;
28425210b06SDavid du Colombier }
28525210b06SDavid du Colombier if(php->offset > curoff){
28625210b06SDavid du Colombier b->state = READEPAD;
28725210b06SDavid du Colombier b->bp = (char*)smalloc(offset - curoff);
28825210b06SDavid du Colombier b->wp = b->bp;
28925210b06SDavid du Colombier b->ep = b->wp + offset - curoff;
29025210b06SDavid du Colombier if(debug)
29125210b06SDavid du Colombier print("nextphdr %lud...\n", offset - curoff);
29225210b06SDavid du Colombier return 1;
29325210b06SDavid du Colombier }
29425210b06SDavid du Colombier b->state = READEDATA;
29525210b06SDavid du Colombier b->bp = physaddr;
29625210b06SDavid du Colombier b->wp = b->bp;
29725210b06SDavid du Colombier b->ep = b->wp+php->filesz;
29825210b06SDavid du Colombier print("%ud+", php->filesz);
29925210b06SDavid du Colombier elftotal += php->filesz;
30025210b06SDavid du Colombier if(debug)
30125210b06SDavid du Colombier print("nextphdr %ud@%#p\n", php->filesz, physaddr);
30225210b06SDavid du Colombier
30325210b06SDavid du Colombier return 1;
30425210b06SDavid du Colombier }
30525210b06SDavid du Colombier
30625210b06SDavid du Colombier if(curphdr != 0){
30725210b06SDavid du Colombier print("=%lud\n", elftotal);
30825210b06SDavid du Colombier b->state = TRYEBOOT;
309*62579e34SDavid du Colombier b->entry = ehdr.elfentry;
310*62579e34SDavid du Colombier // PLLONG(b->hdr.entry, b->entry);
311*62579e34SDavid du Colombier return 1;
312*62579e34SDavid du Colombier }
313*62579e34SDavid du Colombier
314*62579e34SDavid du Colombier return 0;
315*62579e34SDavid du Colombier }
316*62579e34SDavid du Colombier
317*62579e34SDavid du Colombier static int
nextp64hdr(Boot * b)318*62579e34SDavid du Colombier nextp64hdr(Boot *b)
319*62579e34SDavid du Colombier {
320*62579e34SDavid du Colombier P64hdr *php;
321*62579e34SDavid du Colombier uvlong offset;
322*62579e34SDavid du Colombier char *physaddr;
323*62579e34SDavid du Colombier
324*62579e34SDavid du Colombier if(debug)
325*62579e34SDavid du Colombier print("reade64data %d\n", curphdr);
326*62579e34SDavid du Colombier
327*62579e34SDavid du Colombier for(; curphdr < e64hdr.phnum; curphdr++){
328*62579e34SDavid du Colombier php = p64hdr+curphdr;
329*62579e34SDavid du Colombier if(php->type != LOAD)
330*62579e34SDavid du Colombier continue;
331*62579e34SDavid du Colombier offset = php->offset;
332*62579e34SDavid du Colombier physaddr = (char*)KADDR(PADDR(php->paddr));
333*62579e34SDavid du Colombier if(offset < curoff){
334*62579e34SDavid du Colombier /*
335*62579e34SDavid du Colombier * Can't (be bothered to) rewind the
336*62579e34SDavid du Colombier * input, it might be from tftp. If we
337*62579e34SDavid du Colombier * did then we could boot FreeBSD kernels
338*62579e34SDavid du Colombier * too maybe.
339*62579e34SDavid du Colombier */
340*62579e34SDavid du Colombier return 0;
341*62579e34SDavid du Colombier }
342*62579e34SDavid du Colombier if(php->offset > curoff){
343*62579e34SDavid du Colombier b->state = READE64PAD;
344*62579e34SDavid du Colombier b->bp = (char*)smalloc(offset - curoff);
345*62579e34SDavid du Colombier b->wp = b->bp;
346*62579e34SDavid du Colombier b->ep = b->wp + offset - curoff;
347*62579e34SDavid du Colombier if(debug)
348*62579e34SDavid du Colombier print("nextp64hdr %llud...\n", offset - curoff);
349*62579e34SDavid du Colombier return 1;
350*62579e34SDavid du Colombier }
351*62579e34SDavid du Colombier b->state = READE64DATA;
352*62579e34SDavid du Colombier b->bp = physaddr;
353*62579e34SDavid du Colombier b->wp = b->bp;
354*62579e34SDavid du Colombier b->ep = b->wp+php->filesz;
355*62579e34SDavid du Colombier print("%llud+", php->filesz);
356*62579e34SDavid du Colombier elftotal += php->filesz;
357*62579e34SDavid du Colombier if(debug)
358*62579e34SDavid du Colombier print("nextp64hdr %llud@%#p\n", php->filesz, physaddr);
359*62579e34SDavid du Colombier
360*62579e34SDavid du Colombier return 1;
361*62579e34SDavid du Colombier }
362*62579e34SDavid du Colombier
363*62579e34SDavid du Colombier if(curphdr != 0){
364*62579e34SDavid du Colombier print("=%lud\n", elftotal);
365*62579e34SDavid du Colombier b->state = TRYE64BOOT;
366*62579e34SDavid du Colombier b->entry = e64hdr.elfentry;
36725210b06SDavid du Colombier return 1;
36825210b06SDavid du Colombier }
36925210b06SDavid du Colombier
37025210b06SDavid du Colombier return 0;
37125210b06SDavid du Colombier }
37225210b06SDavid du Colombier
37325210b06SDavid du Colombier static int
readepad(Boot * b)37425210b06SDavid du Colombier readepad(Boot *b)
37525210b06SDavid du Colombier {
37625210b06SDavid du Colombier Phdr *php;
37725210b06SDavid du Colombier
37825210b06SDavid du Colombier php = phdr+curphdr;
37925210b06SDavid du Colombier if(debug)
38025210b06SDavid du Colombier print("readepad %d\n", curphdr);
38125210b06SDavid du Colombier curoff = php->offset;
38225210b06SDavid du Colombier
38325210b06SDavid du Colombier return nextphdr(b);
38425210b06SDavid du Colombier }
38525210b06SDavid du Colombier
38625210b06SDavid du Colombier static int
reade64pad(Boot * b)387*62579e34SDavid du Colombier reade64pad(Boot *b)
388*62579e34SDavid du Colombier {
389*62579e34SDavid du Colombier P64hdr *php;
390*62579e34SDavid du Colombier
391*62579e34SDavid du Colombier php = p64hdr+curphdr;
392*62579e34SDavid du Colombier if(debug)
393*62579e34SDavid du Colombier print("reade64pad %d\n", curphdr);
394*62579e34SDavid du Colombier curoff = php->offset;
395*62579e34SDavid du Colombier
396*62579e34SDavid du Colombier return nextp64hdr(b);
397*62579e34SDavid du Colombier }
398*62579e34SDavid du Colombier
399*62579e34SDavid du Colombier static int
readedata(Boot * b)40025210b06SDavid du Colombier readedata(Boot *b)
40125210b06SDavid du Colombier {
40225210b06SDavid du Colombier Phdr *php;
40325210b06SDavid du Colombier
40425210b06SDavid du Colombier php = phdr+curphdr;
40525210b06SDavid du Colombier if(debug)
40625210b06SDavid du Colombier print("readedata %d\n", curphdr);
40725210b06SDavid du Colombier if(php->filesz < php->memsz){
40825210b06SDavid du Colombier print("%lud", php->memsz-php->filesz);
40925210b06SDavid du Colombier elftotal += php->memsz-php->filesz;
41025210b06SDavid du Colombier memset((char*)KADDR(PADDR(php->paddr)+php->filesz), 0,
41125210b06SDavid du Colombier php->memsz-php->filesz);
41225210b06SDavid du Colombier }
41325210b06SDavid du Colombier curoff = php->offset+php->filesz;
41425210b06SDavid du Colombier curphdr++;
41525210b06SDavid du Colombier
41625210b06SDavid du Colombier return nextphdr(b);
41725210b06SDavid du Colombier }
41825210b06SDavid du Colombier
41925210b06SDavid du Colombier static int
reade64data(Boot * b)420*62579e34SDavid du Colombier reade64data(Boot *b)
421*62579e34SDavid du Colombier {
422*62579e34SDavid du Colombier P64hdr *php;
423*62579e34SDavid du Colombier
424*62579e34SDavid du Colombier php = p64hdr+curphdr;
425*62579e34SDavid du Colombier if(debug)
426*62579e34SDavid du Colombier print("reade64data %d\n", curphdr);
427*62579e34SDavid du Colombier if(php->filesz < php->memsz){
428*62579e34SDavid du Colombier print("%llud", php->memsz - php->filesz);
429*62579e34SDavid du Colombier elftotal += php->memsz - php->filesz;
430*62579e34SDavid du Colombier memset((char*)KADDR(PADDR(php->paddr) + php->filesz), 0,
431*62579e34SDavid du Colombier php->memsz - php->filesz);
432*62579e34SDavid du Colombier }
433*62579e34SDavid du Colombier curoff = php->offset + php->filesz;
434*62579e34SDavid du Colombier curphdr++;
435*62579e34SDavid du Colombier
436*62579e34SDavid du Colombier return nextp64hdr(b);
437*62579e34SDavid du Colombier }
438*62579e34SDavid du Colombier
439*62579e34SDavid du Colombier static int
readphdr(Boot * b)44025210b06SDavid du Colombier readphdr(Boot *b)
44125210b06SDavid du Colombier {
44225210b06SDavid du Colombier Phdr *php;
44325210b06SDavid du Colombier
44425210b06SDavid du Colombier php = phdr;
44525210b06SDavid du Colombier hswal((long*)php, ehdr.phentsize*ehdr.phnum/sizeof(long), swal);
44625210b06SDavid du Colombier if(debug)
44725210b06SDavid du Colombier print("phdr curoff %lud vaddr %#lux paddr %#lux\n",
44825210b06SDavid du Colombier curoff, php->vaddr, php->paddr);
44925210b06SDavid du Colombier
45025210b06SDavid du Colombier curoff = ehdr.phoff+ehdr.phentsize*ehdr.phnum;
45125210b06SDavid du Colombier curphdr = 0;
45225210b06SDavid du Colombier
45325210b06SDavid du Colombier return nextphdr(b);
45425210b06SDavid du Colombier }
45525210b06SDavid du Colombier
45625210b06SDavid du Colombier static int
readp64hdr(Boot * b)457*62579e34SDavid du Colombier readp64hdr(Boot *b)
458*62579e34SDavid du Colombier {
459*62579e34SDavid du Colombier int hdr;
460*62579e34SDavid du Colombier P64hdr *php, *p;
461*62579e34SDavid du Colombier
462*62579e34SDavid du Colombier php = p = p64hdr;
463*62579e34SDavid du Colombier for (hdr = 0; hdr < e64hdr.phnum; hdr++, p++) {
464*62579e34SDavid du Colombier hswal((long*)p, 2, swal);
465*62579e34SDavid du Colombier hswav((uvlong*)&p->offset, 6, swav);
466*62579e34SDavid du Colombier }
467*62579e34SDavid du Colombier if(debug)
468*62579e34SDavid du Colombier print("p64hdr curoff %lud vaddr %#llux paddr %#llux\n",
469*62579e34SDavid du Colombier curoff, php->vaddr, php->paddr);
470*62579e34SDavid du Colombier
471*62579e34SDavid du Colombier curoff = e64hdr.phoff + e64hdr.phentsize*e64hdr.phnum;
472*62579e34SDavid du Colombier curphdr = 0;
473*62579e34SDavid du Colombier
474*62579e34SDavid du Colombier return nextp64hdr(b);
475*62579e34SDavid du Colombier }
476*62579e34SDavid du Colombier
477*62579e34SDavid du Colombier static int
addbytes(char ** dbuf,char * edbuf,char ** sbuf,char * esbuf)47825210b06SDavid du Colombier addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
47925210b06SDavid du Colombier {
48025210b06SDavid du Colombier int n;
48125210b06SDavid du Colombier
48225210b06SDavid du Colombier n = edbuf - *dbuf;
48325210b06SDavid du Colombier if(n <= 0)
484*62579e34SDavid du Colombier return 0; /* dest buffer is full */
48525210b06SDavid du Colombier if(n > esbuf - *sbuf)
48625210b06SDavid du Colombier n = esbuf - *sbuf;
48725210b06SDavid du Colombier if(n <= 0)
488*62579e34SDavid du Colombier return -1; /* src buffer is empty */
48925210b06SDavid du Colombier
49025210b06SDavid du Colombier memmove(*dbuf, *sbuf, n);
49125210b06SDavid du Colombier *sbuf += n;
49225210b06SDavid du Colombier *dbuf += n;
49325210b06SDavid du Colombier return edbuf - *dbuf;
49425210b06SDavid du Colombier }
49525210b06SDavid du Colombier
49625210b06SDavid du Colombier void
impulse(void)49725210b06SDavid du Colombier impulse(void)
49825210b06SDavid du Colombier {
49925210b06SDavid du Colombier delay(500); /* drain uart */
50025210b06SDavid du Colombier splhi();
50125210b06SDavid du Colombier
50225210b06SDavid du Colombier /* turn off buffered serial console */
50325210b06SDavid du Colombier serialoq = nil;
50425210b06SDavid du Colombier
50525210b06SDavid du Colombier /* shutdown devices */
50625210b06SDavid du Colombier chandevshutdown();
50725210b06SDavid du Colombier arch->introff();
50825210b06SDavid du Colombier }
50925210b06SDavid du Colombier
51025210b06SDavid du Colombier void
prstackuse(int)51125210b06SDavid du Colombier prstackuse(int)
51225210b06SDavid du Colombier {
51325210b06SDavid du Colombier char *top, *base;
51425210b06SDavid du Colombier ulong *p;
51525210b06SDavid du Colombier
51625210b06SDavid du Colombier base = up->kstack;
51725210b06SDavid du Colombier top = up->kstack + KSTACK - (sizeof(Sargs) + BY2WD);
51825210b06SDavid du Colombier for (p = (ulong *)base; (char *)p < top && *p ==
51925210b06SDavid du Colombier (Stkpat<<24 | Stkpat<<16 | Stkpat<<8 | Stkpat); p++)
52025210b06SDavid du Colombier ;
52125210b06SDavid du Colombier print("proc stack: used %ld bytes, %ld left (stack pattern)\n",
52225210b06SDavid du Colombier top - (char *)p, (char *)p - base);
52325210b06SDavid du Colombier }
52425210b06SDavid du Colombier
52525210b06SDavid du Colombier /*
52625210b06SDavid du Colombier * this code is simplified from reboot(). It doesn't need to relocate
52725210b06SDavid du Colombier * the new kernel nor deal with other processors.
52825210b06SDavid du Colombier */
52925210b06SDavid du Colombier void
warp9(ulong entry)53025210b06SDavid du Colombier warp9(ulong entry)
53125210b06SDavid du Colombier {
53225210b06SDavid du Colombier // prstackuse(0); /* debugging */
533bca3d52eSDavid du Colombier mkmultiboot();
53425210b06SDavid du Colombier impulse();
53525210b06SDavid du Colombier
53625210b06SDavid du Colombier /* get out of KZERO space, turn off paging and jump to entry */
53725210b06SDavid du Colombier pagingoff(PADDR(entry));
53825210b06SDavid du Colombier }
53925210b06SDavid du Colombier
540*62579e34SDavid du Colombier static int
bootfail(Boot * b)541*62579e34SDavid du Colombier bootfail(Boot *b)
54225210b06SDavid du Colombier {
543*62579e34SDavid du Colombier b->state = FAILED;
54425210b06SDavid du Colombier return FAIL;
545*62579e34SDavid du Colombier }
54625210b06SDavid du Colombier
547*62579e34SDavid du Colombier static int
isgzipped(uchar * p)548*62579e34SDavid du Colombier isgzipped(uchar *p)
549*62579e34SDavid du Colombier {
550*62579e34SDavid du Colombier return p[0] == 0x1F && p[1] == 0x8B && p[2] == 0x08;
551*62579e34SDavid du Colombier }
55225210b06SDavid du Colombier
553*62579e34SDavid du Colombier static int
readexec(Boot * b)554*62579e34SDavid du Colombier readexec(Boot *b)
555*62579e34SDavid du Colombier {
556*62579e34SDavid du Colombier Exechdr *hdr;
557*62579e34SDavid du Colombier ulong pentry, text, data, magic;
558*62579e34SDavid du Colombier
55925210b06SDavid du Colombier hdr = &b->hdr;
56025210b06SDavid du Colombier magic = GLLONG(hdr->magic);
56125210b06SDavid du Colombier if(magic == I_MAGIC || magic == S_MAGIC) {
56225210b06SDavid du Colombier pentry = PADDR(GLLONG(hdr->entry));
56325210b06SDavid du Colombier text = GLLONG(hdr->text);
56425210b06SDavid du Colombier data = GLLONG(hdr->data);
56525210b06SDavid du Colombier if (pentry < MB)
566*62579e34SDavid du Colombier panic("kernel entry %#p below 1 MB", pentry);
567*62579e34SDavid du Colombier if (PGROUND(pentry + text) + data > MB + Kernelmax)
568*62579e34SDavid du Colombier panic("kernel larger than %d bytes", Kernelmax);
56925210b06SDavid du Colombier b->state = READ9TEXT;
57025210b06SDavid du Colombier b->bp = (char*)KADDR(pentry);
57125210b06SDavid du Colombier b->wp = b->bp;
57225210b06SDavid du Colombier b->ep = b->wp+text;
57325210b06SDavid du Colombier
57425210b06SDavid du Colombier if(magic == I_MAGIC){
57525210b06SDavid du Colombier memmove(b->bp, b->hdr.uvl, sizeof(b->hdr.uvl));
57625210b06SDavid du Colombier b->wp += sizeof(b->hdr.uvl);
57725210b06SDavid du Colombier }
57825210b06SDavid du Colombier
57925210b06SDavid du Colombier print("%lud", text);
580*62579e34SDavid du Colombier } else if(memcmp(b->bp, elfident, 4) == 0 &&
581*62579e34SDavid du Colombier (uchar)b->bp[4] == ELFCLASS32){
58225210b06SDavid du Colombier b->state = READEHDR;
58325210b06SDavid du Colombier b->bp = (char*)&ehdr;
58425210b06SDavid du Colombier b->wp = b->bp;
58525210b06SDavid du Colombier b->ep = b->wp + sizeof(Ehdr);
58625210b06SDavid du Colombier memmove(b->bp, &b->hdr, sizeof(Exechdr));
58725210b06SDavid du Colombier b->wp += sizeof(Exechdr);
58825210b06SDavid du Colombier print("elf...");
589*62579e34SDavid du Colombier } else if(memcmp(b->bp, elfident, 4) == 0 &&
590*62579e34SDavid du Colombier (uchar)b->bp[4] == ELFCLASS64){
591*62579e34SDavid du Colombier b->state = READE64HDR;
592*62579e34SDavid du Colombier b->bp = (char*)&e64hdr;
593*62579e34SDavid du Colombier b->wp = b->bp;
594*62579e34SDavid du Colombier b->ep = b->wp + sizeof(E64hdr);
595*62579e34SDavid du Colombier memmove(b->bp, &b->hdr, sizeof(Exechdr));
596*62579e34SDavid du Colombier b->wp += sizeof(Exechdr);
597*62579e34SDavid du Colombier print("elf64...");
598*62579e34SDavid du Colombier } else if(isgzipped((uchar *)b->bp)) {
59925210b06SDavid du Colombier b->state = READGZIP;
60025210b06SDavid du Colombier /* could use Unzipbuf instead of smalloc() */
60125210b06SDavid du Colombier b->bp = (char*)smalloc(Kernelmax);
60225210b06SDavid du Colombier b->wp = b->bp;
60325210b06SDavid du Colombier b->ep = b->wp + Kernelmax;
60425210b06SDavid du Colombier memmove(b->bp, &b->hdr, sizeof(Exechdr));
60525210b06SDavid du Colombier b->wp += sizeof(Exechdr);
60625210b06SDavid du Colombier print("gz...");
60725210b06SDavid du Colombier } else {
608*62579e34SDavid du Colombier print("bad kernel format (magic %#lux)\n", magic);
609*62579e34SDavid du Colombier return bootfail(b);
61025210b06SDavid du Colombier }
611*62579e34SDavid du Colombier return MORE;
612*62579e34SDavid du Colombier }
613*62579e34SDavid du Colombier
614*62579e34SDavid du Colombier static void
boot9(Boot * b,ulong magic,ulong entry)615*62579e34SDavid du Colombier boot9(Boot *b, ulong magic, ulong entry)
616*62579e34SDavid du Colombier {
617*62579e34SDavid du Colombier if(magic == I_MAGIC){
618*62579e34SDavid du Colombier print("entry: %#lux\n", entry);
619*62579e34SDavid du Colombier warp9(PADDR(entry));
620*62579e34SDavid du Colombier }
621*62579e34SDavid du Colombier else if(magic == S_MAGIC)
622*62579e34SDavid du Colombier warp64(beswav(b->hdr.uvl[0]));
623*62579e34SDavid du Colombier else
624*62579e34SDavid du Colombier print("bad magic %#lux\n", magic);
625*62579e34SDavid du Colombier }
626*62579e34SDavid du Colombier
627*62579e34SDavid du Colombier /* only returns upon failure */
628*62579e34SDavid du Colombier static void
readgzip(Boot * b)629*62579e34SDavid du Colombier readgzip(Boot *b)
630*62579e34SDavid du Colombier {
631*62579e34SDavid du Colombier ulong entry, text, data, bss, magic, all, pentry;
632*62579e34SDavid du Colombier uchar *sdata;
633*62579e34SDavid du Colombier Exechdr *hdr;
634*62579e34SDavid du Colombier
635*62579e34SDavid du Colombier /* the whole gzipped kernel is now at b->bp */
636*62579e34SDavid du Colombier hdr = &b->hdr;
637*62579e34SDavid du Colombier if(!isgzipped((uchar *)b->bp)) {
638*62579e34SDavid du Colombier print("lost magic\n");
639*62579e34SDavid du Colombier return;
640*62579e34SDavid du Colombier }
641*62579e34SDavid du Colombier print("%ld => ", b->wp - b->bp);
642*62579e34SDavid du Colombier /* just fill hdr from gzipped b->bp, to get various sizes */
643*62579e34SDavid du Colombier if(gunzip((uchar*)hdr, sizeof *hdr, (uchar*)b->bp, b->wp - b->bp)
644*62579e34SDavid du Colombier < sizeof *hdr) {
645*62579e34SDavid du Colombier print("error uncompressing kernel exec header\n");
646*62579e34SDavid du Colombier return;
647*62579e34SDavid du Colombier }
648*62579e34SDavid du Colombier
649*62579e34SDavid du Colombier /* assume uncompressed kernel is a plan 9 boot image */
650*62579e34SDavid du Colombier magic = GLLONG(hdr->magic);
651*62579e34SDavid du Colombier entry = GLLONG(hdr->entry);
652*62579e34SDavid du Colombier text = GLLONG(hdr->text);
653*62579e34SDavid du Colombier data = GLLONG(hdr->data);
654*62579e34SDavid du Colombier bss = GLLONG(hdr->bss);
655*62579e34SDavid du Colombier print("%lud+%lud+%lud=%lud\n", text, data, bss, text+data+bss);
656*62579e34SDavid du Colombier
657*62579e34SDavid du Colombier pentry = PADDR(entry);
658*62579e34SDavid du Colombier if (pentry < MB)
659*62579e34SDavid du Colombier panic("kernel entry %#p below 1 MB", pentry);
660*62579e34SDavid du Colombier if (PGROUND(pentry + text) + data > MB + Kernelmax)
661*62579e34SDavid du Colombier panic("kernel larger than %d bytes", Kernelmax);
662*62579e34SDavid du Colombier
663*62579e34SDavid du Colombier /* fill entry from gzipped b->bp */
664*62579e34SDavid du Colombier all = sizeof(Exec) + text + data;
665*62579e34SDavid du Colombier if(gunzip((uchar *)KADDR(PADDR(entry)) - sizeof(Exec), all,
666*62579e34SDavid du Colombier (uchar*)b->bp, b->wp - b->bp) < all) {
667*62579e34SDavid du Colombier print("error uncompressing kernel\n");
668*62579e34SDavid du Colombier return;
669*62579e34SDavid du Colombier }
670*62579e34SDavid du Colombier
671*62579e34SDavid du Colombier /* relocate data to start at page boundary */
672*62579e34SDavid du Colombier sdata = KADDR(PADDR(entry+text));
673*62579e34SDavid du Colombier memmove((void*)PGROUND((uintptr)sdata), sdata, data);
674*62579e34SDavid du Colombier
675*62579e34SDavid du Colombier boot9(b, magic, entry);
676*62579e34SDavid du Colombier }
677*62579e34SDavid du Colombier
678*62579e34SDavid du Colombier /*
679*62579e34SDavid du Colombier * if nbuf is zero, boot.
680*62579e34SDavid du Colombier * else add nbuf bytes from vbuf to b->wp (if there is room)
681*62579e34SDavid du Colombier * and advance the state machine, which may reset b's pointers
682*62579e34SDavid du Colombier * and return to the top.
683*62579e34SDavid du Colombier */
684*62579e34SDavid du Colombier int
bootpass(Boot * b,void * vbuf,int nbuf)685*62579e34SDavid du Colombier bootpass(Boot *b, void *vbuf, int nbuf)
686*62579e34SDavid du Colombier {
687*62579e34SDavid du Colombier char *buf, *ebuf;
688*62579e34SDavid du Colombier Exechdr *hdr;
689*62579e34SDavid du Colombier ulong entry, bss;
690*62579e34SDavid du Colombier uvlong entry64;
691*62579e34SDavid du Colombier
692*62579e34SDavid du Colombier if(b->state == FAILED)
693*62579e34SDavid du Colombier return FAIL;
694*62579e34SDavid du Colombier
695*62579e34SDavid du Colombier if(nbuf == 0)
696*62579e34SDavid du Colombier goto Endofinput;
697*62579e34SDavid du Colombier
698*62579e34SDavid du Colombier buf = vbuf;
699*62579e34SDavid du Colombier ebuf = buf+nbuf;
700*62579e34SDavid du Colombier /* possibly copy into b->wp from buf (not first time) */
701*62579e34SDavid du Colombier while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) {
702*62579e34SDavid du Colombier /* b->bp is full, so advance the state machine */
703*62579e34SDavid du Colombier switch(b->state) {
704*62579e34SDavid du Colombier case INITKERNEL:
705*62579e34SDavid du Colombier b->state = READEXEC;
706*62579e34SDavid du Colombier b->bp = (char*)&b->hdr;
707*62579e34SDavid du Colombier b->wp = b->bp;
708*62579e34SDavid du Colombier b->ep = b->bp+sizeof(Exechdr);
709*62579e34SDavid du Colombier break;
710*62579e34SDavid du Colombier case READEXEC:
711*62579e34SDavid du Colombier readexec(b);
71225210b06SDavid du Colombier break;
71325210b06SDavid du Colombier
71425210b06SDavid du Colombier case READ9TEXT:
71525210b06SDavid du Colombier hdr = &b->hdr;
71625210b06SDavid du Colombier b->state = READ9DATA;
71725210b06SDavid du Colombier b->bp = (char*)PGROUND((uintptr)
71825210b06SDavid du Colombier KADDR(PADDR(GLLONG(hdr->entry))) +
71925210b06SDavid du Colombier GLLONG(hdr->text));
72025210b06SDavid du Colombier b->wp = b->bp;
72125210b06SDavid du Colombier b->ep = b->wp + GLLONG(hdr->data);
72225210b06SDavid du Colombier print("+%ld", GLLONG(hdr->data));
72325210b06SDavid du Colombier break;
72425210b06SDavid du Colombier
72525210b06SDavid du Colombier case READ9DATA:
72625210b06SDavid du Colombier hdr = &b->hdr;
72725210b06SDavid du Colombier bss = GLLONG(hdr->bss);
72825210b06SDavid du Colombier memset(b->ep, 0, bss);
72925210b06SDavid du Colombier print("+%ld=%ld\n",
73025210b06SDavid du Colombier bss, GLLONG(hdr->text)+GLLONG(hdr->data)+bss);
73125210b06SDavid du Colombier b->state = TRYBOOT;
73225210b06SDavid du Colombier return ENOUGH;
73325210b06SDavid du Colombier
734*62579e34SDavid du Colombier /*
735*62579e34SDavid du Colombier * elf
736*62579e34SDavid du Colombier */
73725210b06SDavid du Colombier case READEHDR:
738*62579e34SDavid du Colombier if(!readehdr(b))
73925210b06SDavid du Colombier print("readehdr failed\n");
74025210b06SDavid du Colombier break;
74125210b06SDavid du Colombier case READPHDR:
742*62579e34SDavid du Colombier readphdr(b);
74325210b06SDavid du Colombier break;
74425210b06SDavid du Colombier case READEPAD:
745*62579e34SDavid du Colombier readepad(b);
746*62579e34SDavid du Colombier break;
747*62579e34SDavid du Colombier case READEDATA:
748*62579e34SDavid du Colombier readedata(b);
749*62579e34SDavid du Colombier if(b->state == TRYEBOOT)
750*62579e34SDavid du Colombier return ENOUGH;
75125210b06SDavid du Colombier break;
75225210b06SDavid du Colombier
753*62579e34SDavid du Colombier /*
754*62579e34SDavid du Colombier * elf64
755*62579e34SDavid du Colombier */
756*62579e34SDavid du Colombier case READE64HDR:
757*62579e34SDavid du Colombier if(!reade64hdr(b))
758*62579e34SDavid du Colombier print("reade64hdr failed\n");
759*62579e34SDavid du Colombier break;
760*62579e34SDavid du Colombier case READ64PHDR:
761*62579e34SDavid du Colombier readp64hdr(b);
762*62579e34SDavid du Colombier break;
763*62579e34SDavid du Colombier case READE64PAD:
764*62579e34SDavid du Colombier reade64pad(b);
765*62579e34SDavid du Colombier break;
766*62579e34SDavid du Colombier case READE64DATA:
767*62579e34SDavid du Colombier reade64data(b);
768*62579e34SDavid du Colombier if(b->state == TRYE64BOOT)
76925210b06SDavid du Colombier return ENOUGH;
77025210b06SDavid du Colombier break;
77125210b06SDavid du Colombier
77225210b06SDavid du Colombier case TRYBOOT:
77325210b06SDavid du Colombier case TRYEBOOT:
774*62579e34SDavid du Colombier case TRYE64BOOT:
77525210b06SDavid du Colombier case READGZIP:
77625210b06SDavid du Colombier return ENOUGH;
77725210b06SDavid du Colombier
77825210b06SDavid du Colombier case READ9LOAD:
77925210b06SDavid du Colombier case INIT9LOAD:
78025210b06SDavid du Colombier panic("9load");
78125210b06SDavid du Colombier
78225210b06SDavid du Colombier default:
78325210b06SDavid du Colombier panic("bootstate");
78425210b06SDavid du Colombier }
785*62579e34SDavid du Colombier if(b->state == FAILED)
786*62579e34SDavid du Colombier return FAIL;
78725210b06SDavid du Colombier }
78825210b06SDavid du Colombier return MORE;
78925210b06SDavid du Colombier
79025210b06SDavid du Colombier Endofinput:
79125210b06SDavid du Colombier /* end of input */
79225210b06SDavid du Colombier switch(b->state) {
79325210b06SDavid du Colombier case INITKERNEL:
79425210b06SDavid du Colombier case READEXEC:
79525210b06SDavid du Colombier case READ9TEXT:
79625210b06SDavid du Colombier case READ9DATA:
79725210b06SDavid du Colombier case READEHDR:
79825210b06SDavid du Colombier case READPHDR:
79925210b06SDavid du Colombier case READEPAD:
80025210b06SDavid du Colombier case READEDATA:
801*62579e34SDavid du Colombier case READE64HDR:
802*62579e34SDavid du Colombier case READ64PHDR:
803*62579e34SDavid du Colombier case READE64PAD:
804*62579e34SDavid du Colombier case READE64DATA:
80525210b06SDavid du Colombier print("premature EOF\n");
806*62579e34SDavid du Colombier break;
80725210b06SDavid du Colombier
80825210b06SDavid du Colombier case TRYBOOT:
809*62579e34SDavid du Colombier boot9(b, GLLONG(b->hdr.magic), GLLONG(b->hdr.entry));
810*62579e34SDavid du Colombier break;
81125210b06SDavid du Colombier
81225210b06SDavid du Colombier case TRYEBOOT:
813*62579e34SDavid du Colombier entry = b->entry;
81425210b06SDavid du Colombier if(ehdr.machine == I386){
81525210b06SDavid du Colombier print("entry: %#lux\n", entry);
81625210b06SDavid du Colombier warp9(PADDR(entry));
81725210b06SDavid du Colombier }
818*62579e34SDavid du Colombier else if(ehdr.machine == AMD64)
81925210b06SDavid du Colombier warp64(entry);
820*62579e34SDavid du Colombier else
821*62579e34SDavid du Colombier panic("elf boot: ehdr.machine %d unknown", ehdr.machine);
822*62579e34SDavid du Colombier break;
823*62579e34SDavid du Colombier
824*62579e34SDavid du Colombier case TRYE64BOOT:
825*62579e34SDavid du Colombier entry64 = b->entry;
826*62579e34SDavid du Colombier if(e64hdr.machine == I386){
827*62579e34SDavid du Colombier print("entry: %#llux\n", entry64);
828*62579e34SDavid du Colombier warp9(PADDR(entry64));
82925210b06SDavid du Colombier }
830*62579e34SDavid du Colombier else if(e64hdr.machine == AMD64)
831*62579e34SDavid du Colombier warp64(entry64);
832*62579e34SDavid du Colombier else
833*62579e34SDavid du Colombier panic("elf64 boot: e64hdr.machine %d unknown",
834*62579e34SDavid du Colombier e64hdr.machine);
835*62579e34SDavid du Colombier break;
83625210b06SDavid du Colombier
83725210b06SDavid du Colombier case READGZIP:
838*62579e34SDavid du Colombier readgzip(b);
839*62579e34SDavid du Colombier break;
84025210b06SDavid du Colombier
84125210b06SDavid du Colombier case INIT9LOAD:
84225210b06SDavid du Colombier case READ9LOAD:
84325210b06SDavid du Colombier panic("end 9load");
84425210b06SDavid du Colombier
84525210b06SDavid du Colombier default:
84625210b06SDavid du Colombier panic("bootdone");
84725210b06SDavid du Colombier }
848*62579e34SDavid du Colombier return bootfail(b);
84925210b06SDavid du Colombier }
850