1 #include "u.h" 2 #include "lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 7 char *premature = "premature EOF\n"; 8 9 /* 10 * read in a segment 11 */ 12 static long 13 readseg(int dev, long (*read)(int, void*, long), long len, long addr) 14 { 15 char *a; 16 long n, sofar; 17 18 a = (char *)addr; 19 for(sofar = 0; sofar < len; sofar += n){ 20 n = 8*1024; 21 if(len - sofar < n) 22 n = len - sofar; 23 n = (*read)(dev, a + sofar, n); 24 if(n <= 0) 25 break; 26 print("."); 27 } 28 return sofar; 29 } 30 31 /* 32 * boot 33 */ 34 int 35 plan9boot(int dev, long (*seek)(int, long), long (*read)(int, void*, long)) 36 { 37 long n; 38 long addr; 39 void (*b)(void); 40 Exec *ep; 41 42 if((*seek)(dev, 0) < 0) 43 return -1; 44 45 /* 46 * read header 47 */ 48 ep = (Exec *) ialloc(sizeof(Exec), 0); 49 n = sizeof(Exec); 50 if(readseg(dev, read, n, (long) ep) != n){ 51 print(premature); 52 return -1; 53 } 54 if(GLLONG(ep->magic) != Q_MAGIC){ 55 print("bad magic 0x%lux not a plan 9 executable!\n", GLLONG(ep->magic)); 56 return -1; 57 } 58 59 /* 60 * read text 61 */ 62 addr = PADDR(GLLONG(ep->entry)); 63 n = GLLONG(ep->text); 64 print("%d", n); 65 if(readseg(dev, read, n, addr) != n){ 66 print(premature); 67 return -1; 68 } 69 70 /* 71 * read data (starts at first page after kernel) 72 */ 73 addr = PGROUND(addr+n); 74 n = GLLONG(ep->data); 75 print("+%d@%8.8lux", n, addr); 76 if(readseg(dev, read, n, addr) != n){ 77 print(premature); 78 return -1; 79 } 80 81 /* 82 * bss and entry point 83 */ 84 print("+%d\nstart at 0x%lux\n", GLLONG(ep->bss), GLLONG(ep->entry)); 85 uartwait(); 86 scc2stop(); 87 splhi(); 88 89 /* 90 * Go to new code. It's up to the program to get its PC relocated to 91 * the right place. 92 */ 93 b = (void (*)(void))(PADDR(GLLONG(ep->entry))); 94 (*b)(); 95 return 0; 96 } 97