sos

[unmaintained] experimenting with low level OS development
Log | Files | Refs | README | LICENSE

commit 4e464a4dab52b685b9b90bd12507eb85209e00bc
parent c67256787e2754cf1ec940a3777018723c45e497
Author: Stefan <misc@stefan-koch.name>
Date:   Sat, 17 Oct 2015 16:38:56 +0200

add code to enable a20 line

Diffstat:
Aa20.asm | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mkernel.asm | 5++++-
2 files changed, 136 insertions(+), 1 deletion(-)

diff --git a/a20.asm b/a20.asm @@ -0,0 +1,132 @@ +a20_enable: + call a20_stop_if_active + +a20_bios: + mov ax, 2401h + int 15h + + call a20_stop_if_active + +a20_keyboard: + call a20_wait_inbuf ; disable the keyboard + mov al, 0adh + out 64h, al + + call a20_wait_inbuf ; tell the controller we want to read data + mov al, 0d0h + out 64h, al + + call a20_wait_outbuf ; read the P2 port provided by the controller + in al, 60h + push ax + + call a20_wait_inbuf ; tell the controller we want to write data + mov al, 0d1h + out 64h, al + + call a20_wait_inbuf ; write the new P2 port with A20 line active + pop ax + or al, 2 + out 60h, al + + call a20_wait_inbuf ; re-enable the keyboard + mov al, 0aeh + out 64h, al + + call a20_wait_inbuf + + call a20_stop_if_active_loop + +a20_fast: + in al, 92h + test al, 2 + jnz a20_done ; A20 Fast Gate is already activated + or al, 2 + and al, 0feh + out 92h, al + + call a20_stop_if_active_loop + + jmp a20_done ; give up, no other methods there + ; could jump to another location and display an error + +a20_wait_inbuf: + in al, 64h + test al, 2 + jnz a20_wait_inbuf + ret + +a20_wait_outbuf: + in al, 64h, + test al, 1 + jz a20_wait_outbuf + ret + +a20_active: + pushf + push ds + push es + push di + push si + + xor ax, ax ; ax = 0 + mov es, ax + + not ax; ax = 0xffff + mov ds, ax + + mov di, 0500h + mov si, 0510h + + mov al, byte [es:di] ; save the old values from memory + push ax + + mov al, byte [ds:si] + push ax + + mov byte [es:di], 00h ; write 0x00 to one and 0xff to the other location + mov byte [ds:si], 0ffh + + cmp byte [es:di], 0ffh ; check if the address we set to 0x00 was + ; set to 0xff later, then we have only 20 bit + ; addresses + + pop ax ; restore the bytes we set before + mov byte [ds:si], al + + pop ax + mov byte [es:di], al + + mov ax, 0 + je a20_active_end + mov ax, 1 + +a20_active_end: + pop si + pop di + pop es + pop ds + popf + ret + +a20_stop_if_active: + call a20_active + test ax, ax ; check if all bits are 0, then ZF = 1 + jnz a20_done + ret + +a20_stop_if_active_loop: ; try in a loop if a20 is active for k times + mov bx, 0ffh +a20_stop_if_active_loop_iterator: + dec bx + call a20_stop_if_active + test ax, ax + jnz a20_done + + test bx, bx ; check if bx 0 + jnz a20_stop_if_active_loop_iterator + + ret + + +a20_done: diff --git a/kernel.asm b/kernel.asm @@ -6,8 +6,11 @@ mov ss, ax mov ds, ax mov es, ax +cli + +%include "a20.asm" + enter_pmode: - cli lgdt [gdtr] mov eax, cr0 or eax, 1