7 memset(void *dst, int v, int n)
18 memmove(void *dst, void *src, int n)
35 memcmp(void *src, void *dst, int n)
60 strchr(char *s, int c)
77 readn(void *f, void *data, int len)
85 if(((ulong)p & 0xF000) == 0){
87 putc(hex[((ulong)p>>16)&0xF]);
89 if((len = read(f, p, e - p)) <= 0)
95 return p - (uchar*)data;
99 readline(void *f, char buf[64])
101 static char white[] = "\t ";
108 while(p < buf + 64-1){
113 else if(*p == '\b' && p > buf){
117 }else if(read(f, p, 1) <= 0)
119 if(p == buf && strchr(white, *p))
125 while(p > buf && strchr(white, p[-1]))
145 #define BOOTLINE ((char*)CONFADDR)
146 #define BOOTLINELEN 64
147 #define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN))
148 #define BOOTARGSLEN (4096-0x200-BOOTLINELEN)
152 static void apmconf(int);
153 static void e820conf(void);
160 for(p = BOOTARGS; p < confend; p = e){
161 for(e = p+1; e < confend; e++){
167 if(!memcmp(p, s, strlen(s))){
168 memmove(p, e, confend - e);
178 configure(void *f, char *path)
180 char line[64], *kern, *s, *p;
181 int inblock, nowait, n;
188 memset(BOOTLINE, 0, BOOTLINELEN);
191 memset(confend, 0, BOOTARGSLEN);
195 while(readline(f, line) > 0){
196 if(*line == 0 || strchr("#;=", *line))
199 inblock = memcmp("[common]", line, 8);
202 if(!memcmp("boot", line, 5)){
206 if(!memcmp("wait", line, 5)){
210 if(!memcmp("clear", line, 5)){
215 } else if(line[5] == ' ' && delconf(line+6)){
221 if(inblock || (p = strchr(line, '=')) == nil)
225 if(!memcmp("apm", line, 3)){
226 apmconf('0' - line[3]);
229 if(!memcmp("bootfile", line, 8))
230 memmove(kern = path, p, strlen(p)+1);
233 memmove(confend, line, n = strlen(line)); confend += n;
235 memmove(confend, p, n = strlen(p)); confend += n;
238 print(s); print(crnl);
248 if(kern && (nowait==0 || timeout(1000)))
253 print("no bootfile\r\n");
256 while(p = strchr(kern, '!'))
264 hexfmt(char *s, int i, ulong a)
275 addconfx(char *s, int w, ulong v)
280 memmove(confend, s, n);
281 hexfmt(confend+n, w, v);
292 a = (uchar*)CONFADDR;
296 if(memcmp(a, "APM", 4))
301 addconfx("apm", 1, id);
302 addconfx("=ax=", 4, *((ushort*)(a+4)));
303 addconfx(" ebx=", 8, *((ulong*)(a+12)));
304 addconfx(" cx=", 4, *((ushort*)(a+6)));
305 addconfx(" dx=", 4, *((ushort*)(a+8)));
306 addconfx(" di=", 4, *((ushort*)(a+10)));
307 addconfx(" esi=", 8, *((ulong*)(a+16)));
309 print(s); print(crnl);
333 if(e.typ == 1 && e.len != 0 && (e.ext & 3) == 1){
335 /* single entry <= 1MB is useless */
336 if(bx == 0 && e.len <= 0x100000)
338 memmove(confend, "e820=", 5);
342 addconfx("", 8, v>>32);
343 addconfx("", 8, v&0xffffffff);
345 addconfx(" ", 8, v>>32);
346 addconfx("", 8, v&0xffffffff);
355 print(s); print(crnl);
367 return (p[0]<<8) | p[1];
376 return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
387 print("a20 enable failed\r\n");
389 if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
391 if(beswal(ex.magic) != I_MAGIC)
394 e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
398 if(readn(f, t, n) != n)
400 d = (uchar*)PGROUND((ulong)t + n);
403 if(readn(f, d, n) != n)