9boot: always check if a20 is already enabled, use different keyboard code, retry on failure.
This commit is contained in:
parent
9140ae4a2a
commit
7179a121a6
|
@ -2,69 +2,83 @@
|
|||
|
||||
#undef ORB
|
||||
|
||||
TEXT a20test(SB), $0
|
||||
LONG $1234567
|
||||
|
||||
TEXT a20check(SB), $0
|
||||
MOVL $10000, CX
|
||||
_loop:
|
||||
LEAL a20test(SB), AX
|
||||
MOVL (AX), BX
|
||||
ADDL $12345, BX
|
||||
MOVL BX, (AX)
|
||||
ORL $(1<<20), AX
|
||||
MOVL (AX), AX
|
||||
CMPL AX, BX
|
||||
JNZ _done
|
||||
LOOP _loop
|
||||
RET
|
||||
_done:
|
||||
/* return directly to caller of a20() */
|
||||
ADDL $4, SP
|
||||
XORL AX, AX
|
||||
RET
|
||||
|
||||
TEXT a20(SB), $0
|
||||
CALL a20check(SB)
|
||||
|
||||
/* try bios */
|
||||
CALL rmode16(SB)
|
||||
STI
|
||||
LWI(0x2401, rAX)
|
||||
BIOSCALL(0x15)
|
||||
JC _biosfail
|
||||
CALL16(pmode32(SB))
|
||||
RET
|
||||
|
||||
_biosfail:
|
||||
CALL16(pmode32(SB))
|
||||
|
||||
/* fast a20 */
|
||||
CALL a20check(SB)
|
||||
|
||||
/* try fast a20 */
|
||||
MOVL $0x92, DX
|
||||
INB
|
||||
ANDB $0xFE, AX
|
||||
ORB $0x02, AX
|
||||
OUTB
|
||||
|
||||
/* slow a20 */
|
||||
CALL a20wait(SB)
|
||||
MOVL $0x64, DX
|
||||
MOVB $0xAD, AL
|
||||
OUTB
|
||||
|
||||
CALL a20wait(SB)
|
||||
MOVL $0x64, DX
|
||||
MOVB $0xD0, AL
|
||||
OUTB
|
||||
|
||||
CALL a20wait2(SB)
|
||||
MOVL $0x60, DX
|
||||
INB
|
||||
PUSHL AX
|
||||
|
||||
CALL a20wait(SB)
|
||||
MOVL $0x64, DX
|
||||
MOVB $0xD1, AL
|
||||
OUTB
|
||||
|
||||
CALL a20wait(SB)
|
||||
MOVL $0x60, DX
|
||||
POPL AX
|
||||
TESTB $2, AL
|
||||
JNZ _no92
|
||||
ORB $2, AL
|
||||
ANDB $0xfe, AL
|
||||
OUTB
|
||||
_no92:
|
||||
CALL a20check(SB)
|
||||
|
||||
CALL a20wait(SB)
|
||||
/* try keyboard */
|
||||
CALL kbdempty(SB)
|
||||
MOVL $0x64, DX
|
||||
MOVB $0xAE, AL
|
||||
MOVB $0xd1, AL /* command write */
|
||||
OUTB
|
||||
CALL kbdempty(SB)
|
||||
MOVL $0x60, DX
|
||||
MOVB $0xdf, AL /* a20 on */
|
||||
OUTB
|
||||
CALL kbdempty(SB)
|
||||
MOVL $0x64, DX
|
||||
MOVB $0xff, AL /* magic */
|
||||
OUTB
|
||||
CALL kbdempty(SB)
|
||||
|
||||
TEXT a20wait(SB), $0
|
||||
_a20wait:
|
||||
CALL a20check(SB)
|
||||
|
||||
/* fail */
|
||||
XORL AX, AX
|
||||
DECL AX
|
||||
RET
|
||||
|
||||
TEXT kbdempty(SB), $0
|
||||
_kbdwait:
|
||||
MOVL $0x64, DX
|
||||
INB
|
||||
TESTB $1, AL
|
||||
JZ _a20wait2
|
||||
RET
|
||||
|
||||
TEXT a20wait2(SB), $0
|
||||
_a20wait2:
|
||||
MOVL $0x64, DX
|
||||
JZ _kbdempty
|
||||
MOVL $0x60, DX
|
||||
INB
|
||||
JMP _kbdwait
|
||||
_kbdempty:
|
||||
TESTB $2, AL
|
||||
JNZ _a20wait
|
||||
JNZ _kbdwait
|
||||
RET
|
||||
|
|
|
@ -29,3 +29,11 @@ void print(char *s);
|
|||
char *configure(void *f, char *path);
|
||||
char *bootkern(void *f);
|
||||
|
||||
/* a20.s */
|
||||
int a20(void);
|
||||
|
||||
/* e820.s */
|
||||
ulong e820(ulong bx, void *p);
|
||||
|
||||
/* apm.s */
|
||||
void apm(int id);
|
||||
|
|
|
@ -283,8 +283,6 @@ addconfx(char *s, int w, ulong v)
|
|||
*confend = 0;
|
||||
}
|
||||
|
||||
void apm(int id);
|
||||
|
||||
static void
|
||||
apmconf(int id)
|
||||
{
|
||||
|
@ -314,8 +312,6 @@ apmconf(int id)
|
|||
*confend = 0;
|
||||
}
|
||||
|
||||
ulong e820(ulong bx, void *p);
|
||||
|
||||
static void
|
||||
e820conf(void)
|
||||
{
|
||||
|
@ -380,8 +376,6 @@ beswal(ulong l)
|
|||
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
|
||||
}
|
||||
|
||||
void a20(void);
|
||||
|
||||
char*
|
||||
bootkern(void *f)
|
||||
{
|
||||
|
@ -389,7 +383,8 @@ bootkern(void *f)
|
|||
ulong n;
|
||||
Exec ex;
|
||||
|
||||
a20();
|
||||
while(a20() < 0)
|
||||
print("a20 enable failed\r\n");
|
||||
|
||||
if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
|
||||
return "bad header";
|
||||
|
|
Loading…
Reference in a new issue