9boot: add APM support
This commit is contained in:
parent
b4f2bf77b3
commit
e0c8b9955d
5 changed files with 132 additions and 15 deletions
51
sys/src/boot/pc/apm.s
Normal file
51
sys/src/boot/pc/apm.s
Normal file
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in a new issue