]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/sub.c
newboot
[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 ushort
89 beswab(ushort s)
90 {
91         uchar *p;
92
93         p = (uchar*)&s;
94         return (p[0]<<8) | p[1];
95 }
96
97 static ulong
98 beswal(ulong l)
99 {
100         uchar *p;
101
102         p = (uchar*)&l;
103         return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
104 }
105
106 char*
107 bootkern(void *f)
108 {
109         uchar *e, *d;
110         Exec ex;
111         int n;
112
113         a20();
114         if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
115                 return "bad header";
116         if(beswal(ex.magic) != I_MAGIC)
117                 return "bad magic";
118         e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
119         n = beswal(ex.text);
120         if(readn(f, e, n) != n)
121                 goto err;
122         d = (uchar*)(((ulong)e + n + 0xFFF) & ~0xFFFUL);
123         n = beswal(ex.data);
124         if(readn(f, d, n) != n)
125                 goto err;
126         close(f);
127         jump(e);
128 err:            
129         return "i/o error";
130 }
131
132 static int
133 readline(void *f, char buf[64])
134 {
135         static char white[] = "\t ";
136         char *p;
137
138         p = buf;
139         do{
140                 if(!f)
141                         putc('>');
142                 while(p < buf + 64-1){
143                         if(!f){
144                                 putc(*p = getc());
145                                 if(*p == '\r')
146                                         putc('\n');
147                                 else if(*p == 0x08 && p > buf){
148                                         p--;
149                                         continue;
150                                 }
151                         }else if(read(f, p, 1) <= 0)
152                                 return 0;
153                         if(p == buf && strchr(white, *p))
154                                 continue;
155                         if(strchr(crnl, *p))
156                                 break;
157                         p++;
158                 }
159                 while(p > buf && strchr(white, p[-1]))
160                         p--;
161         }while(p == buf);
162         *p = 0;
163         return p - buf;
164 }
165
166 char*
167 configure(void *f, char *path)
168 {
169         char line[64], *p, *kern;
170         int inblock, n;
171
172         kern = 0;
173         inblock = 0;
174         p = (char*)((CONFADDR + 64) & ~0xF0000000UL);
175 Loop:
176         while((n = readline(f, line)) > 0){
177                 if(*line == 0 || strchr("#;=", *line))
178                         continue;
179                 if(*line == '['){
180                         inblock = memcmp("[common]", line, 8);
181                         continue;
182                 }
183                 if(memcmp("boot", line, 5) == 0)
184                         break;
185                 if(inblock || !strrchr(line, '='))
186                         continue;
187                 print(line); print(crnl);
188                 if(memcmp("bootfile=", line, 9) == 0)
189                         memmove(kern = path, line+9, 1 + n-9);
190                 memmove(p, line, n); p += n;
191                 *p++ = '\n';
192         }
193         *p = 0;
194         if(f){
195                 close(f);
196                 f = 0;
197         }
198         if(!kern){
199                 print("no bootfile\r\n");
200                 goto Loop;
201         }
202         for(n=0; n<10000; n++)
203                 if(gotc())
204                         goto Loop;
205         if(p = strrchr(kern, '!'))
206                 kern = p+1;
207         return kern;
208 }