]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/xen/xenbin.c
usbohci: use 64-bit io base address, disable interrupts before reset, remove resetlck
[plan9front.git] / sys / src / 9 / xen / xenbin.c
1 /*
2  * Transform a Plan 9 386 bootable image to make it compatible with
3  * the Xen binary image loader:
4  *
5  * - pad the beginning of the text with zeroes so that the image can be loaded at
6  *    guest 'physical' address 0
7  * - insert a Xen header
8  * - pad the end of the text so that data segment is page-aligned in the file
9  * - adjust the linenumber-pc table so Plan 9 debuggers won't be confused
10  */
11
12 #include <u.h>
13 #include <libc.h>
14 #include <bio.h>
15 #include <mach.h>
16
17 #define PAGE    4096
18 #define PLAN9HDR        32
19 #define XENHDR  32
20 #define KZERO   0x80000000
21 #define FLAG_VALID      (1<<16)
22 #define FLAG_PAE        (1<<14)
23
24 void
25 lput(long n)
26 {
27         char buf[sizeof(long)];
28         int i;
29
30         for (i = sizeof(long)-1; i >= 0; i--) {
31                 buf[i] = n;
32                 n >>= 8;
33         }
34         write(1, buf, sizeof(long));
35 }
36
37 void
38 rput(long n)
39 {
40         char buf[sizeof(long)];
41         int i;
42
43         for (i = 0; i < sizeof(long); i++) {
44                 buf[i] = n;
45                 n >>= 8;
46         }
47         write(1, buf, sizeof(long));
48 }
49
50 void
51 copy(long n)
52 {
53         char buf[PAGE];
54         int m;
55
56         while (n > 0) {
57                 m = sizeof buf;
58                 if (m > n)
59                         m = n;
60                 read(0, buf, m);
61                 write(1, buf, m);
62                 n -= m;
63         }
64 }
65
66 void pad(int n)
67 {
68         char buf[PAGE];
69         int m;
70
71         memset(buf, 0, sizeof buf);
72         while (n > 0) {
73                 m = sizeof buf;
74                 if (m > n)
75                         m = n;
76                 write(1, buf, m);
77                 n -= m;
78         }
79 }
80
81 /*
82  * See /sys/src/cmd/8l/span.c:/^asmlc
83  */
84 void adjustlnpc(int v)
85 {
86         char buf[PAGE];
87         int n, s;
88
89         n = 0;
90         while (v) {
91                 s = 127;
92                 if (v < 127)
93                         s = v;
94                 buf[n++] = s+128;
95                 if (n == sizeof buf) {
96                         write(1, buf, n);
97                         n = 0;
98                 }
99                 v -= s;
100         }
101         if (n > 0)
102                 write(1, buf, n);
103 }
104
105 void
106 main(int argc, char **argv)
107 {
108         Fhdr fhdr;
109         long newtxtsz;
110         long newentry;
111         long newlnpcsz;
112         long prepad, postpad;
113         long flags;
114
115         flags = FLAG_VALID;
116         if (argc > 1 && strcmp(argv[1], "-p") == 0)
117                 flags |= FLAG_PAE;
118
119         crackhdr(0, &fhdr);
120
121         newtxtsz = ((fhdr.txtsz+PLAN9HDR+PAGE-1)&~(PAGE-1)) - PLAN9HDR;
122         newentry = KZERO+PLAN9HDR;
123         prepad = fhdr.entry - newentry;
124         postpad = newtxtsz - fhdr.txtsz;
125         newtxtsz += prepad;
126         newlnpcsz = fhdr.lnpcsz;
127         if (newlnpcsz)
128                 newlnpcsz += (prepad+126)/127;
129
130         /* plan 9 header */
131         lput(4*11*11+7);                /* magic */
132         lput(newtxtsz);                 /* sizes */
133         lput(fhdr.datsz);
134         lput(fhdr.bsssz);
135         lput(fhdr.symsz);               /* nsyms */
136         lput(newentry);         /* va of entry */
137         lput(fhdr.sppcsz);              /* sp offsets */
138         lput(newlnpcsz);                /* line offsets */
139
140         /* xen header */
141         rput(0x336EC578);       /* magic */
142         rput(flags);            /* flags */
143         rput(-(0x336EC578+flags));      /* checksum */
144         rput(newentry); /* header_addr */
145         rput(KZERO);    /* load_addr */
146         rput(KZERO+newtxtsz+fhdr.datsz);        /* load_end_addr */
147         rput(KZERO+newtxtsz+fhdr.datsz+fhdr.bsssz);     /* bss_end_addr */
148         rput(fhdr.entry);       /* entry_addr */
149
150         pad(prepad-XENHDR);
151
152         seek(0, fhdr.txtoff, 0);
153         copy(fhdr.txtsz);
154         pad(postpad);
155         copy(fhdr.datsz);
156         copy(fhdr.symsz);
157         if (newlnpcsz) {
158                 adjustlnpc(prepad);
159                 copy(fhdr.lnpcsz);
160         }
161         exits(0);
162 }