]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/sub.c
add clear command to 9boot to reset configuration
[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 + 64) & ~0xF0000000UL);
132 Loop:
133         while((n = readline(f, line)) > 0){
134                 if(*line == 0 || strchr("#;=", *line))
135                         continue;
136                 if(*line == '['){
137                         inblock = memcmp("[common]", line, 8);
138                         continue;
139                 }
140                 if(memcmp("clear", line, 6) == 0){
141                         print("ok\r\n");
142                         goto Clear;
143                 }
144                 if(memcmp("boot", line, 5) == 0)
145                         break;
146                 if(inblock || !strrchr(line, '='))
147                         continue;
148                 print(line); print(crnl);
149                 if(memcmp("bootfile=", line, 9) == 0)
150                         memmove(kern = path, line+9, 1 + n-9);
151                 memmove(p, line, n); p += n;
152                 *p++ = '\n';
153         }
154         *p = 0;
155         if(f){
156                 close(f);
157                 f = 0;
158         }
159         if(!kern){
160                 print("no bootfile\r\n");
161                 goto Loop;
162         }
163         for(n=0; n<10000; n++)
164                 if(gotc())
165                         goto Loop;
166         if(p = strrchr(kern, '!'))
167                 kern = p+1;
168         return kern;
169 }
170
171
172 static ushort
173 beswab(ushort s)
174 {
175         uchar *p;
176
177         p = (uchar*)&s;
178         return (p[0]<<8) | p[1];
179 }
180
181 static ulong
182 beswal(ulong l)
183 {
184         uchar *p;
185
186         p = (uchar*)&l;
187         return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
188 }
189
190 char*
191 bootkern(void *f)
192 {
193         uchar *e, *d;
194         Exec ex;
195         int n;
196
197         a20();
198         if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
199                 return "bad header";
200         if(beswal(ex.magic) != I_MAGIC)
201                 return "bad magic";
202         e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
203         n = beswal(ex.text);
204         if(readn(f, e, n) != n)
205                 goto Error;
206         d = (uchar*)(((ulong)e + n + 0xFFF) & ~0xFFFUL);
207         n = beswal(ex.data);
208         if(readn(f, d, n) != n)
209                 goto Error;
210         close(f);
211         jump(e);
212 Error:          
213         return "i/o error";
214 }