]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/sub.c
9boot: oops, it all was just a20 gate not being enabled
[plan9front.git] / sys / src / boot / pc / sub.c
1 #include <u.h>
2 #include <a.out.h>
3 #include "fns.h"
4 #include "mem.h"
5
6 void
7 memset(void *p, int v, int n)
8 {
9         uchar *d = p;
10         while(n > 0){
11                 *d++ = v;
12                 n--;
13         }
14 }
15
16 void
17 memmove(void *dst, void *src, int n)
18 {
19         uchar *d = dst;
20         uchar *s = src;
21
22         if(d < s){
23                 while(n > 0){
24                         *d++ = *s++;
25                         n--;
26                 }
27         } if(d > s){
28                 s += n;
29                 d += n;
30                 while(n > 0){
31                         *--d = *--s;
32                         n--;
33                 }
34         }
35 }
36
37 int
38 memcmp(void *src, void *dst, int n)
39 {
40         uchar *d = dst;
41         uchar *s = src;
42         int r = 0;
43         while((n > 0) && (r = (*d++ - *s++)) == 0)
44                 n--;
45         return r;
46 }
47
48 int
49 strlen(char *s)
50 {
51         char *p = s;
52         while(*p)
53                 p++;
54         return p - s;
55 }
56
57 char*
58 strchr(char *s, int c)
59 {
60         for(; *s; s++)
61                 if(*s == c)
62                         return s;
63         return 0;
64 }
65
66 char*
67 strrchr(char *s, int c)
68 {
69         char *r;
70         r = 0;
71         while(s = strchr(s, c))
72                 r = s++;
73         return r;
74 }
75
76 void
77 print(char *s)
78 {
79         while(*s)
80                 putc(*s++);
81 }
82
83 int
84 readn(void *f, void *data, int len)
85 {
86         uchar *p, *e;
87
88         p = data;
89         e = p + len;
90         while(p < e){
91                 if((len = read(f, p, e - p)) <= 0)
92                         break;
93                 p += len;
94         }
95         return p - (uchar*)data;
96 }
97
98 static int
99 readline(void *f, char buf[64])
100 {
101         static char white[] = "\t ";
102         char *p;
103
104         p = buf;
105         do{
106                 if(!f)
107                         putc('>');
108                 while(p < buf + 64-1){
109                         if(!f){
110                                 putc(*p = getc());
111                                 if(*p == '\r')
112                                         putc('\n');
113                                 else if(*p == 0x08 && p > buf){
114                                         p--;
115                                         continue;
116                                 }
117                         }else if(read(f, p, 1) <= 0)
118                                 return 0;
119                         if(p == buf && strchr(white, *p))
120                                 continue;
121                         if(strchr(crnl, *p))
122                                 break;
123                         p++;
124                 }
125                 while(p > buf && strchr(white, p[-1]))
126                         p--;
127         }while(p == buf);
128         *p = 0;
129         return p - buf;
130 }
131
132 char*
133 configure(void *f, char *path)
134 {
135         char line[64], *p, *kern;
136         int inblock, n;
137
138 Clear:
139         kern = 0;
140         inblock = 0;
141         p = (char*)(CONFADDR & ~0xF0000000UL);
142         memset(p, 0, 0xE00);
143         p += 64;
144 Loop:
145         while((n = readline(f, line)) > 0){
146                 if(*line == 0 || strchr("#;=", *line))
147                         continue;
148                 if(*line == '['){
149                         inblock = memcmp("[common]", line, 8);
150                         continue;
151                 }
152                 if(memcmp("clear", line, 6) == 0){
153                         print("ok\r\n");
154                         goto Clear;
155                 }
156                 if(memcmp("boot", line, 5) == 0)
157                         break;
158                 if(inblock || !strrchr(line, '='))
159                         continue;
160                 print(line); print(crnl);
161                 if(memcmp("bootfile=", line, 9) == 0)
162                         memmove(kern = path, line+9, 1 + n-9);
163                 memmove(p, line, n); p += n;
164                 *p++ = '\n';
165         }
166         *p = 0;
167         if(f){
168                 close(f);
169                 f = 0;
170         }
171         if(!kern){
172                 print("no bootfile\r\n");
173                 goto Loop;
174         }
175         for(n=0; n<10000; n++)
176                 if(gotc())
177                         goto Loop;
178         if(p = strrchr(kern, '!'))
179                 kern = p+1;
180         return kern;
181 }
182
183
184 static ushort
185 beswab(ushort s)
186 {
187         uchar *p;
188
189         p = (uchar*)&s;
190         return (p[0]<<8) | p[1];
191 }
192
193 static ulong
194 beswal(ulong l)
195 {
196         uchar *p;
197
198         p = (uchar*)&l;
199         return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
200 }
201
202 char*
203 bootkern(void *f)
204 {
205         uchar *e, *d, *t;
206         ulong n;
207         Exec ex;
208
209         a20();
210         if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
211                 return "bad header";
212         if(beswal(ex.magic) != I_MAGIC)
213                 return "bad magic";
214
215         e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
216         t = e;
217         n = beswal(ex.text);
218         if(readn(f, t, n) != n)
219                 goto Error;
220         d = (uchar*)PGROUND((ulong)t + n);
221         n = beswal(ex.data);
222         if(readn(f, d, n) != n)
223                 goto Error;
224         close(f);
225         unload();
226         jump(e);
227 Error:          
228         return "i/o error";
229 }