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