#include "mem.h"
void
-memset(void *p, int v, int n)
+memset(void *dst, int v, int n)
{
- uchar *d = p;
+ uchar *d = dst;
+
while(n > 0){
*d++ = v;
n--;
uchar *s = src;
if(d < s){
- while(n > 0){
+ while(n-- > 0)
*d++ = *s++;
- n--;
- }
- } if(d > s){
+ } else if(d > s){
s += n;
d += n;
- while(n > 0){
+ while(n-- > 0)
*--d = *--s;
- n--;
- }
}
}
uchar *d = dst;
uchar *s = src;
int r = 0;
- while((n > 0) && (r = (*d++ - *s++)) == 0)
- n--;
+
+ while(n-- > 0)
+ if(r = (*d++ - *s++))
+ break;
+
return r;
}
strlen(char *s)
{
char *p = s;
+
while(*p)
p++;
+
return p - s;
}
for(; *s; s++)
if(*s == c)
return s;
- return 0;
-}
-char*
-strrchr(char *s, int c)
-{
- char *r;
- r = 0;
- while(s = strchr(s, c))
- r = s++;
- return r;
+ return 0;
}
void
{
uchar *p, *e;
+ putc(' ');
p = data;
e = p + len;
while(p < e){
+ if(((ulong)p & 0xF000) == 0){
+ putc('\b');
+ putc(hex[((ulong)p>>16)&0xF]);
+ }
if((len = read(f, p, e - p)) <= 0)
break;
p += len;
}
+ putc('\b');
+
return p - (uchar*)data;
}
putc(*p = getc());
if(*p == '\r')
putc('\n');
- else if(*p == 0x08 && p > buf){
+ else if(*p == '\b' && p > buf){
p--;
continue;
}
p--;
}while(p == buf);
*p = 0;
+
return p - buf;
}
+static int
+timeout(int ms)
+{
+ while(ms > 0){
+ if(gotc())
+ return 1;
+ usleep(100000);
+ ms -= 100;
+ }
+ return 0;
+}
+
+#define BOOTLINE ((char*)CONFADDR)
+#define BOOTLINELEN 64
+#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN))
+#define BOOTARGSLEN (4096-0x200-BOOTLINELEN)
+
+char *confend;
+
+static void apmconf(int);
+static void e820conf(void);
+
+static int
+delconf(char *s)
+{
+ char *p, *e;
+
+ for(p = BOOTARGS; p < confend; p = e){
+ for(e = p+1; e < confend; e++){
+ if(*e == '\n'){
+ e++;
+ break;
+ }
+ }
+ if(!memcmp(p, s, strlen(s))){
+ memmove(p, e, confend - e);
+ confend -= e - p;
+ *confend = 0;
+ return 1;
+ }
+ }
+ return 0;
+}
+
char*
configure(void *f, char *path)
{
- char line[64], *p, *kern;
- int inblock, n;
+ char line[64], *kern, *s, *p;
+ int inblock, nowait, n;
Clear:
kern = 0;
+ nowait = 1;
inblock = 0;
- p = (char*)(CONFADDR & ~0xF0000000UL);
- memset(p, 0, 0xE00);
- p += 64;
+
+ memset(BOOTLINE, 0, BOOTLINELEN);
+
+ confend = BOOTARGS;
+ memset(confend, 0, BOOTARGSLEN);
+
+ e820conf();
Loop:
- while((n = readline(f, line)) > 0){
+ while(readline(f, line) > 0){
if(*line == 0 || strchr("#;=", *line))
continue;
if(*line == '['){
inblock = memcmp("[common]", line, 8);
continue;
}
- if(memcmp("clear", line, 6) == 0){
- print("ok\r\n");
- goto Clear;
- }
- if(memcmp("boot", line, 5) == 0)
+ if(!memcmp("boot", line, 5)){
+ nowait=1;
break;
- if(inblock || !strrchr(line, '='))
+ }
+ if(!memcmp("wait", line, 5)){
+ nowait=0;
continue;
- print(line); print(crnl);
- if(memcmp("bootfile=", line, 9) == 0)
- memmove(kern = path, line+9, 1 + n-9);
- memmove(p, line, n); p += n;
- *p++ = '\n';
+ }
+ if(!memcmp("clear", line, 5)){
+ if(line[5] == 0){
+ print("ok");
+ print(crnl);
+ goto Clear;
+ } else if(line[5] == ' ' && delconf(line+6)){
+ print("ok");
+ print(crnl);
+ }
+ continue;
+ }
+ if(inblock || (p = strchr(line, '=')) == nil)
+ continue;
+ *p++ = 0;
+ delconf(line);
+ if(!memcmp("apm", line, 3)){
+ apmconf('0' - line[3]);
+ continue;
+ }
+ if(!memcmp("bootfile", line, 8))
+ memmove(kern = path, p, strlen(p)+1);
+
+ s = confend;
+ memmove(confend, line, n = strlen(line)); confend += n;
+ *confend++ = '=';
+ memmove(confend, p, n = strlen(p)); confend += n;
+ *confend = 0;
+
+ print(s); print(crnl);
+
+ *confend++ = '\n';
+ *confend = 0;
}
- *p = 0;
+
if(f){
close(f);
f = 0;
+
+ if(kern && (nowait==0 || timeout(1000)))
+ goto Loop;
}
+
if(!kern){
print("no bootfile\r\n");
goto Loop;
}
- for(n=0; n<10000; n++)
- if(gotc())
- goto Loop;
- if(p = strrchr(kern, '!'))
+ while(p = strchr(kern, '!'))
kern = p+1;
+
return kern;
}
+static void
+hexfmt(char *s, int i, ulong a)
+{
+ s += i;
+ while(i > 0){
+ *--s = hex[a&15];
+ a >>= 4;
+ i--;
+ }
+}
+
+static void
+addconfx(char *s, int w, ulong v)
+{
+ int n;
+
+ n = strlen(s);
+ memmove(confend, s, n);
+ hexfmt(confend+n, w, v);
+ confend += n+w;
+ *confend = 0;
+}
+
+void apm(int id);
+
+static void
+apmconf(int id)
+{
+ uchar *a;
+ char *s;
+
+ a = (uchar*)CONFADDR;
+ memset(a, 0, 20);
+
+ apm(id);
+ if(memcmp(a, "APM", 4))
+ return;
+
+ s = confend;
+
+ addconfx("apm", 1, id);
+ addconfx("=ax=", 4, *((ushort*)(a+4)));
+ addconfx(" ebx=", 8, *((ulong*)(a+12)));
+ addconfx(" cx=", 4, *((ushort*)(a+6)));
+ addconfx(" dx=", 4, *((ushort*)(a+8)));
+ addconfx(" di=", 4, *((ushort*)(a+10)));
+ addconfx(" esi=", 8, *((ulong*)(a+16)));
+
+ print(s); print(crnl);
+
+ *confend++ = '\n';
+ *confend = 0;
+}
+
+ulong e820(ulong bx, void *p);
+
+static void
+e820conf(void)
+{
+ struct {
+ uvlong base;
+ uvlong len;
+ ulong typ;
+ ulong ext;
+ } e;
+ uvlong v;
+ ulong bx;
+ char *s;
+
+ bx=0;
+ s = confend;
+
+ do{
+ bx = e820(bx, &e);
+ if(e.typ == 1 && e.len != 0 && (e.ext & 3) == 1){
+ if(confend == s){
+ /* single entry <= 1MB is useless */
+ if(bx == 0 && e.len <= 0x100000)
+ break;
+ memmove(confend, "e820=", 5);
+ confend += 5;
+ }
+ v = e.base;
+ addconfx("", 8, v>>32);
+ addconfx("", 8, v&0xffffffff);
+ v += e.len;
+ addconfx(" ", 8, v>>32);
+ addconfx("", 8, v&0xffffffff);
+ *confend++ = ' ';
+ }
+ } while(bx);
+
+ if(confend == s)
+ return;
+
+ *confend = 0;
+ print(s); print(crnl);
+
+ *confend++ = '\n';
+ *confend = 0;
+}
+
static ushort
beswab(ushort s)
{
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
+void a20(void);
+
char*
bootkern(void *f)
{
Exec ex;
a20();
+
if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
return "bad header";
if(beswal(ex.magic) != I_MAGIC)
return "bad magic";
- /* load address */
e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
-
- /*
- * the kernels load addess (entry) might overlap
- * with some bios memory (pxe) that is needed to load
- * it. so we read it to this address and after
- * we finished, move it to final location.
- */
- t = (uchar*)0x200000;
-
+ t = e;
n = beswal(ex.text);
+
if(readn(f, t, n) != n)
goto Error;
- d = t + ((uchar*)PGROUND((ulong)e + n) - e);
+ d = (uchar*)PGROUND((ulong)t + n);
n = beswal(ex.data);
+
if(readn(f, d, n) != n)
goto Error;
close(f);
-
unload();
- n = (d + n) - t;
- memmove(e, t, n);
+ print("boot");
+ print(crnl);
+
jump(e);
+
Error:
return "i/o error";
}