ref: ee695eff4329234e20abb68ff3100d3b15929418
dir: /os/boot/pc/bootld.c/
#include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" static int addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf) { int n; n = edbuf - *dbuf; if(n <= 0) return 0; if(n > esbuf - *sbuf) n = esbuf - *sbuf; if(n <= 0) return -1; memmove(*dbuf, *sbuf, n); *sbuf += n; *dbuf += n; return edbuf - *dbuf; } extern void origin(void); int bootpass(Boot *b, void *vbuf, int nbuf) { char *buf, *ebuf, *p, *q; ulong size; 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 INIT9LOAD: b->state = READ9LOAD; b->bp = (char*)0x10000; b->wp = b->bp; b->ep = b->bp + 256*1024; break; case READ9LOAD: return ENOUGH; default: panic("bootstate"); } } return MORE; Endofinput: /* end of input */ print("\n"); switch(b->state) { case INIT9LOAD: print("premature EOF\n"); b->state = FAILED; return FAIL; case READ9LOAD: size = b->wp - b->bp; if(memcmp(b->bp, origin, 16) != 0) { print("beginning of file does not look right\n"); b->state = FAILED; return FAIL; } if(size < 32*1024 || size > 256*1024) { print("got %lud byte loader; not likely\n", size); b->state = FAILED; return FAIL; } p = b->bp; q = b->wp; if(q - p > 10000) /* don't search much past l.s */ q = p+10000; /* * The string `JUMP' appears right before * tokzero, which is where we want to jump. */ for(; p<q; p++) { if(strncmp(p, "JUMP", 4) == 0) { p += 4; warp9((ulong)p); } } print("could not find jump destination\n"); b->state = FAILED; return FAIL; default: panic("bootdone"); } b->state = FAILED; return FAIL; }