diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-05-14 19:20:16 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-05-14 19:20:16 +0000 |
commit | 0ad5929695507eb80f18e177f29f5c51697bcc23 (patch) | |
tree | 9fa917c4e3e2cb9b5e06702c75b278be6b211795 /sys/src | |
parent | e0c8b9955de9fab16f65ad0471a696a2e8b2fe81 (diff) |
9boot: add e820 scan to bootloader
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/pc/memory.c | 60 | ||||
-rw-r--r-- | sys/src/boot/pc/apm.s | 6 | ||||
-rw-r--r-- | sys/src/boot/pc/e820.s | 20 | ||||
-rw-r--r-- | sys/src/boot/pc/fns.h | 2 | ||||
-rw-r--r-- | sys/src/boot/pc/mkfile | 2 | ||||
-rw-r--r-- | sys/src/boot/pc/sub.c | 71 |
6 files changed, 133 insertions, 28 deletions
diff --git a/sys/src/9/pc/memory.c b/sys/src/9/pc/memory.c index edf52623e..33121d647 100644 --- a/sys/src/9/pc/memory.c +++ b/sys/src/9/pc/memory.c @@ -673,35 +673,51 @@ e820scan(void) ulong cont, base, len; uvlong last; Emap *e; + char *s; - if(getconf("*norealmode") || getconf("*noe820scan")) - return -1; - - cont = 0; - for(i=0; i<nelem(emap); i++){ - memset(&u, 0, sizeof u); - u.ax = 0xE820; - u.bx = cont; - u.cx = 20; - u.dx = SMAP; - u.es = (PADDR(RMBUF)>>4)&0xF000; - u.di = PADDR(RMBUF)&0xFFFF; - u.trap = 0x15; - realmode(&u); - cont = u.bx; - if((u.flags&Carry) || u.ax != SMAP || u.cx != 20) - break; - e = &emap[nemap++]; - *e = *(Emap*)RMBUF; - if(u.bx == 0) - break; + if((s = getconf("e820")) != nil){ + for(nemap = 0; nemap < nelem(emap); nemap++){ + if(*s == 0) + break; + e = emap + nemap; + e->base = strtoull(s, &s, 16); + if(*s != ' ') + break; + e->len = strtoull(s, &s, 16) - e->base; + if(*s != ' ' && *s != 0 || e->len >= 1ull<<32 || e->len == 0) + break; + e->type = Ememory; + } + }else{ + if(getconf("*norealmode") || getconf("*noe820scan")) + return -1; + cont = 0; + for(i=0; i<nelem(emap); i++){ + memset(&u, 0, sizeof u); + u.ax = 0xE820; + u.bx = cont; + u.cx = 20; + u.dx = SMAP; + u.es = (PADDR(RMBUF)>>4)&0xF000; + u.di = PADDR(RMBUF)&0xFFFF; + u.trap = 0x15; + realmode(&u); + cont = u.bx; + if((u.flags&Carry) || u.ax != SMAP || u.cx != 20) + break; + e = &emap[nemap++]; + *e = *(Emap*)RMBUF; + if(u.bx == 0) + break; + } } + if(nemap == 0) return -1; qsort(emap, nemap, sizeof emap[0], emapcmp); - if(getconf("*noe820print") == nil){ + if(s == nil && getconf("*noe820print") == nil){ for(i=0; i<nemap; i++){ e = &emap[i]; print("E820: %.8llux %.8llux ", e->base, e->base+e->len); diff --git a/sys/src/boot/pc/apm.s b/sys/src/boot/pc/apm.s index 0a0d41fd1..b6a9104b1 100644 --- a/sys/src/boot/pc/apm.s +++ b/sys/src/boot/pc/apm.s @@ -7,19 +7,19 @@ TEXT apm(SB), $0 PUSHR(rBX) LWI(0x5300, rAX) - INT $0x15 + BIOSCALL(0x15) POPR(rBX) JC noapm PUSHR(rBX) LWI(0x5304, rAX) - INT $0x15 + BIOSCALL(0x15) POPR(rBX) CLC /* connect */ LWI(0x5303, rAX) - INT $0x15 + BIOSCALL(0x15) JC noapm OPSIZE; PUSHR(rSI) diff --git a/sys/src/boot/pc/e820.s b/sys/src/boot/pc/e820.s new file mode 100644 index 000000000..c830a64e6 --- /dev/null +++ b/sys/src/boot/pc/e820.s @@ -0,0 +1,20 @@ +#include "x16.h" +#include "mem.h" + +TEXT e820(SB), $0 + MOVL bx+4(SP), BX + MOVL p+8(SP), DI + + MOVL $0xe820, AX + MOVL $0x534D4150, DX + CALL rmode16(SB) + LWI(24, rCX) + BIOSCALL(0x15) + JC _bad + CALL16(pmode32(SB)) + MOVL BX, AX + RET +_bad: + CALL16(pmode32(SB)) + XORL AX, AX + RET diff --git a/sys/src/boot/pc/fns.h b/sys/src/boot/pc/fns.h index 5135ac5b2..11176f07f 100644 --- a/sys/src/boot/pc/fns.h +++ b/sys/src/boot/pc/fns.h @@ -9,8 +9,6 @@ void start(void *sp); 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/mkfile b/sys/src/boot/pc/mkfile index 4dd12e913..ff6ce3114 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 apm.$O a20.$O +9boot&: l%.$O %.$O sub.$O apm.$O e820.$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 10e5e7a22..205cace13 100644 --- a/sys/src/boot/pc/sub.c +++ b/sys/src/boot/pc/sub.c @@ -235,6 +235,8 @@ addconfx(char *s, int w, ulong v) *confend = 0; } +void apm(int id); + static void apmconf(int id) { @@ -263,6 +265,73 @@ apmconf(int id) *confend++ = '\n'; } +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; + + memset(&e, 0, sizeof(e)); + if((bx = e820(0, &e)) == 0) + return; + + memmove(confend, "e820=", 5); + confend += 5; + + do{ + s = confend; + v = e.base; + addconfx("", 8, v>>32); + addconfx("", 8, v&0xffffffff); + v = e.base + e.len; + addconfx(" ", 8, v>>32); + addconfx("", 8, v&0xffffffff); + + print(s); + + switch(e.typ){ + case 1: + print(" ram"); + break; + case 2: + print(" reserved"); + break; + case 3: + print(" acpi reclaim"); + break; + case 4: + print(" acpi nvs"); + break; + case 5: + print(" bad"); + break; + default: + print(" ???"); + } + print(crnl); + + if(e.typ == 1 && (e.ext & 1) == 0) + *confend++ = ' '; + else + confend = s; + memset(&e, 0, sizeof(e)); + } while(bx = e820(bx, &e)); + + *confend++ = '\n'; + *confend = 0; +} + +void a20(void); + char* bootkern(void *f) { @@ -270,6 +339,8 @@ bootkern(void *f) ulong n; Exec ex; + e820conf(); + a20(); if(readn(f, &ex, sizeof(ex)) != sizeof(ex)) return "bad header"; |