9boot: add e820 scan to bootloader

This commit is contained in:
cinap_lenrek 2011-05-14 19:20:16 +00:00
parent e0c8b9955d
commit 0ad5929695
6 changed files with 133 additions and 28 deletions

View file

@ -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);

View file

@ -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)

20
sys/src/boot/pc/e820.s Normal file
View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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";