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
readseg(int dev,long (* read)(int,void *,long),long len,long addr)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
plan9boot(int dev,long (* seek)(int,long),long (* read)(int,void *,long))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