diff options
author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-05-14 17:06:27 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-05-14 17:06:27 +0000 |
commit | e0c8b9955de9fab16f65ad0471a696a2e8b2fe81 (patch) | |
tree | 2c25634341571e4655849cceec126265d14b1a7a /sys/src/boot | |
parent | b4f2bf77b3710306bf1965201d526154c9dbddb7 (diff) |
9boot: add APM support
Diffstat (limited to 'sys/src/boot')
-rw-r--r-- | sys/src/boot/pc/apm.s | 51 | ||||
-rw-r--r-- | sys/src/boot/pc/fns.h | 1 | ||||
-rw-r--r-- | sys/src/boot/pc/mem.h | 4 | ||||
-rw-r--r-- | sys/src/boot/pc/mkfile | 2 | ||||
-rw-r--r-- | sys/src/boot/pc/sub.c | 89 |
5 files changed, 132 insertions, 15 deletions
diff --git a/sys/src/boot/pc/apm.s b/sys/src/boot/pc/apm.s new file mode 100644 index 000000000..0a0d41fd1 --- /dev/null +++ b/sys/src/boot/pc/apm.s @@ -0,0 +1,51 @@ +#include "x16.h" +#include "mem.h" + +TEXT apm(SB), $0 + MOVL id+4(SP), BX + CALL rmode16(SB) + + PUSHR(rBX) + LWI(0x5300, rAX) + INT $0x15 + POPR(rBX) + JC noapm + + PUSHR(rBX) + LWI(0x5304, rAX) + INT $0x15 + POPR(rBX) + CLC + + /* connect */ + LWI(0x5303, rAX) + INT $0x15 + JC noapm + + OPSIZE; PUSHR(rSI) + OPSIZE; PUSHR(rBX) + PUSHR(rDI) + PUSHR(rDX) + PUSHR(rCX) + PUSHR(rAX) + + LWI(CONFADDR, rDI) + + /* + * write APM data. first four bytes are APM\0. + */ + LWI(0x5041, rAX) + STOSW + + LWI(0x004d, rAX) + STOSW + + LWI(8, rCX) +apmmove: + POPR(rAX) + STOSW + LOOP apmmove + +noapm: + CALL16(pmode32(SB)) + RET diff --git a/sys/src/boot/pc/fns.h b/sys/src/boot/pc/fns.h index bdb1905e9..5135ac5b2 100644 --- a/sys/src/boot/pc/fns.h +++ b/sys/src/boot/pc/fns.h @@ -10,6 +10,7 @@ int getc(void); int gotc(void); void putc(int c); void a20(void); +void apm(int id); void halt(void); void jump(void *pc); diff --git a/sys/src/boot/pc/mem.h b/sys/src/boot/pc/mem.h index 64a3a869c..42f3dc316 100644 --- a/sys/src/boot/pc/mem.h +++ b/sys/src/boot/pc/mem.h @@ -16,8 +16,8 @@ /* * Fundamental addresses */ -#define CONFADDR 0x80001200 /* info passed from boot loader */ -#define BIOSXCHG 0x80006000 /* To exchange data with the BIOS */ +#define CONFADDR 0x1200 /* info passed from boot loader */ +#define BIOSXCHG 0x6000 /* To exchange data with the BIOS */ #define SELGDT (0<<3) /* selector is in gdt */ #define SELLDT (1<<3) /* selector is in ldt */ diff --git a/sys/src/boot/pc/mkfile b/sys/src/boot/pc/mkfile index 16d0c2063..4dd12e913 100644 --- a/sys/src/boot/pc/mkfile +++ b/sys/src/boot/pc/mkfile @@ -36,7 +36,7 @@ pbs: pbs.$O $LD -o $target -H3 -T0x0600 -l $prereq ls -l $target -9boot&: l%.$O %.$O sub.$O a20.$O +9boot&: l%.$O %.$O sub.$O apm.$O a20.$O $LD -o $target -H3 -T0x7c00 -l $prereq ls -l $target diff --git a/sys/src/boot/pc/sub.c b/sys/src/boot/pc/sub.c index 02d75aed5..10e5e7a22 100644 --- a/sys/src/boot/pc/sub.c +++ b/sys/src/boot/pc/sub.c @@ -129,18 +129,26 @@ readline(void *f, char buf[64]) return p - buf; } +#define BOOTLINE ((char*)CONFADDR) +#define BOOTLINELEN 64 +#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN)) +#define BOOTARGSLEN (4096-0x200-BOOTLINELEN) + +char *confend; + +static void apmconf(int); + char* configure(void *f, char *path) { - char line[64], *p, *kern; + char line[64], *kern, *p; int inblock, n; - Clear: kern = 0; inblock = 0; - p = (char*)(CONFADDR & ~0xF0000000UL); - memset(p, 0, 0xE00); - p += 64; + + confend = (char*)BOOTARGS; + memset(confend, 0, BOOTARGSLEN); Loop: while((n = readline(f, line)) > 0){ if(*line == 0 || strchr("#;=", *line)) @@ -149,21 +157,25 @@ Loop: inblock = memcmp("[common]", line, 8); continue; } - if(memcmp("clear", line, 6) == 0){ + if(!memcmp("clear", line, 6)){ print("ok\r\n"); goto Clear; } - if(memcmp("boot", line, 5) == 0) + if(!memcmp("boot", line, 5)) break; if(inblock || !strrchr(line, '=')) continue; - print(line); print(crnl); - if(memcmp("bootfile=", line, 9) == 0) + if(!memcmp("bootfile=", line, 9)) memmove(kern = path, line+9, 1 + n-9); - memmove(p, line, n); p += n; - *p++ = '\n'; + if(!memcmp("apm", line, 3) && line[4]=='='){ + apmconf('0' - line[3]); + continue; + } + memmove(confend, line, n); confend += n; + *confend++ = '\n'; + print(line); print(crnl); } - *p = 0; + *confend = 0; if(f){ close(f); f = 0; @@ -177,6 +189,7 @@ Loop: goto Loop; if(p = strrchr(kern, '!')) kern = p+1; + return kern; } @@ -199,6 +212,57 @@ beswal(ulong l) return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; } +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; +} + +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'; +} + char* bootkern(void *f) { @@ -223,6 +287,7 @@ bootkern(void *f) goto Error; close(f); unload(); + memset(BOOTLINE, 0, BOOTLINELEN); jump(e); Error: return "i/o error"; |