int flashboot(int) { ulong entry, addr; void (*b)(void); Exec *ep; Block in; long n; uchar *p; if(flash.exec == 0) return -1; p = flash.exec; if(GLLONG(p) == Q_MAGIC){ /* unsqueezed: copy data and perhaps text, then jump to it */ ep = (Exec*)p; entry = PADDR(GLLONG(ep->entry)); p += sizeof(Exec); addr = entry; n = GLLONG(ep->text); if(addr != (ulong)p){ memmove((void*)addr, p, n); print("text: %8.8lux <- %8.8lux [%ld]\n", addr, p, n); } p += n; if(entry >= FLASHMEM) addr = 3*BY2PG; /* kernel text is in Flash, data in RAM */ else addr = PGROUND(addr+n); n = GLLONG(ep->data); memmove((void*)addr, p, n); print("data: %8.8lux <- %8.8lux [%ld]\n", addr, p, n); }else{ in.data = p; in.rp = in.data; in.lim = p+BOOTLEN; in.wp = in.lim; n = unsqueezef(&in, &entry); if(n < 0) return -1; } print("entry=0x%lux\n", entry); uartwait(); scc2stop(); /* * Go to new code. It's up to the program to get its PC relocated to * the right place. */ b = (void (*)(void))KADDR(PADDR(entry)); (*b)(); return -1; }
int flashinit(void) { int len; char *val; Flalloc *ap; void *addr; long mbytes; char type[20]; flash.base = 0; flash.exec = 0; flash.size = 0; if(archflashreset(type, &addr, &mbytes) < 0){ print("flash: flash not present or not enabled\n"); /* shouldn't happen */ return 0; } flash.size = mbytes; flash.base = addr; flash.exec = flash.base + BOOTOFF; flash.config = nil; flash.conflen = 0; for(ap = (Flalloc*)(flash.base+CONFIGLIM)-1; memcmp(ap->sig, flashsig, 4) == 0; ap--){ if(0) print("conf #%8.8lux: #%x #%6.6lux\n", ap, ap->tag, ap->base); if(ap->tag == Tconf && flashcheck(ap, &val, &len) && len >= sizeof(conftag)-1 && memcmp(val, conftag, sizeof(conftag)-1) == 0){ flash.config = val; flash.conflen = len; if(0) print("flash: found config %8.8lux(%d):\n%s\n", val, len, val); } } if(flash.config == nil) print("flash: no config\n"); else print("flash config %8.8lux(%d):\n%s\n", flash.config, flash.conflen, flash.config); if(issqueezed(flash.exec) == Q_MAGIC){ print("flash: squeezed powerpc kernel installed\n"); return 1<<0; } if(GLLONG(flash.exec) == Q_MAGIC){ print("flash: unsqueezed powerpc kernel installed\n"); return 1<<0; } flash.exec = 0; print("flash: no powerpc kernel in Flash\n"); return 0; }
int flashbootable(int) { return flash.exec != nil && (issqueezed(flash.exec) || GLLONG(flash.exec) == Q_MAGIC); }
int bootpass(Boot *b, void *vbuf, int nbuf) { char *buf, *ebuf; Hdr *hdr; ulong magic, entry, data, text, bss; uvlong entry64; if(b->state == FAILED) return FAIL; if(nbuf == 0) goto Endofinput; buf = vbuf; ebuf = buf+nbuf; while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) { switch(b->state) { case INITKERNEL: b->state = READEXEC; b->bp = (char*)&b->hdr; b->wp = b->bp; b->ep = b->bp+sizeof(Hdr); break; case READEXEC: hdr = &b->hdr; magic = GLLONG(hdr->magic); if(magic == I_MAGIC || magic == S_MAGIC) { b->state = READ9TEXT; b->bp = (char*)PADDR(GLLONG(hdr->entry)); b->wp = b->bp; b->ep = b->wp+GLLONG(hdr->text); if(magic == I_MAGIC){ memmove(b->bp, b->hdr.uvl, sizeof(b->hdr.uvl)); b->wp += sizeof(b->hdr.uvl); } print("%lud", GLLONG(hdr->text)); break; } /* check for gzipped kernel */ if(b->bp[0] == 0x1F && (uchar)b->bp[1] == 0x8B && b->bp[2] == 0x08) { b->state = READGZIP; b->bp = (char*)malloc(1440*1024); b->wp = b->bp; b->ep = b->wp + 1440*1024; memmove(b->bp, &b->hdr, sizeof(Hdr)); b->wp += sizeof(Hdr); print("gz..."); break; } /* * Check for ELF. */ if(memcmp(b->bp, elfident, 4) == 0){ b->state = READEHDR; b->bp = (char*)&ehdr; b->wp = b->bp; b->ep = b->wp + sizeof(Ehdr); memmove(b->bp, &b->hdr, sizeof(Hdr)); b->wp += sizeof(Hdr); print("elf..."); break; } print("bad kernel format (magic == %#lux)\n", magic); b->state = FAILED; return FAIL; case READ9TEXT: hdr = &b->hdr; b->state = READ9DATA; b->bp = (char*)PGROUND(PADDR(GLLONG(hdr->entry))+GLLONG(hdr->text)); b->wp = b->bp; b->ep = b->wp + GLLONG(hdr->data); print("+%ld", GLLONG(hdr->data)); break; case READ9DATA: hdr = &b->hdr; bss = GLLONG(hdr->bss); memset(b->ep, 0, bss); print("+%ld=%ld\n", bss, GLLONG(hdr->text)+GLLONG(hdr->data)+bss); b->state = TRYBOOT; return ENOUGH; case READEHDR: if(!readehdr(b)){ print("readehdr failed\n"); b->state = FAILED; return FAIL; } break; case READPHDR: if(!readphdr(b)){ b->state = FAILED; return FAIL; } break; case READEPAD: if(!readepad(b)){ b->state = FAILED; return FAIL; } break; case READEDATA: if(!readedata(b)){ b->state = FAILED; return FAIL; } if(b->state == TRYBOOT) return ENOUGH; break; case TRYBOOT: case TRYEBOOT: case READGZIP: return ENOUGH; case READ9LOAD: case INIT9LOAD: panic("9load"); default: panic("bootstate"); } } return MORE; Endofinput: /* end of input */ switch(b->state) { case INITKERNEL: case READEXEC: case READ9TEXT: case READ9DATA: case READEHDR: case READPHDR: case READEPAD: case READEDATA: print("premature EOF\n"); b->state = FAILED; return FAIL; case TRYBOOT: entry = GLLONG(b->hdr.entry); magic = GLLONG(b->hdr.magic); if(magic == I_MAGIC){ print("entry: 0x%lux\n", entry); warp9(PADDR(entry)); } else if(magic == S_MAGIC){ entry64 = beswav(b->hdr.uvl[0]); warp64(entry64); } b->state = FAILED; return FAIL; case TRYEBOOT: entry = GLLONG(b->hdr.entry); if(ehdr.machine == I386){ print("entry: 0x%lux\n", entry); warp9(PADDR(entry)); } else if(ehdr.machine == AMD64){ print("entry: 0x%lux\n", entry); warp64(entry); } b->state = FAILED; return FAIL; case READGZIP: hdr = &b->hdr; if(b->bp[0] != 0x1F || (uchar)b->bp[1] != 0x8B || b->bp[2] != 0x08) print("lost magic\n"); print("%ld => ", b->wp - b->bp); if(gunzip((uchar*)hdr, sizeof(*hdr), (uchar*)b->bp, b->wp - b->bp) < sizeof(*hdr)) { print("badly compressed kernel\n"); return FAIL; } entry = GLLONG(hdr->entry); text = GLLONG(hdr->text); data = GLLONG(hdr->data); bss = GLLONG(hdr->bss); print("%lud+%lud+%lud=%lud\n", text, data, bss, text+data+bss); if(gunzip((uchar*)PADDR(entry)-sizeof(Exec), sizeof(Exec)+text+data, (uchar*)b->bp, b->wp-b->bp) < sizeof(Exec)+text+data) { print("error uncompressing kernel\n"); return FAIL; } /* relocate data to start at page boundary */ memmove((void*)PGROUND(PADDR(entry+text)), (void*)(PADDR(entry+text)), data); entry = GLLONG(b->hdr.entry); magic = GLLONG(b->hdr.magic); if(magic == I_MAGIC){ print("entry: 0x%lux\n", entry); warp9(PADDR(entry)); } else if(magic == S_MAGIC){ entry64 = beswav(b->hdr.uvl[0]); warp64(entry64); } b->state = FAILED; return FAIL; case INIT9LOAD: case READ9LOAD: panic("end 9load"); default: panic("bootdone"); } b->state = FAILED; return FAIL; }