From 6c6312e540a570d376aae5551626128fcc1cd1c6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Duje=20Mihanovi=C4=87?= Date: Thu, 16 Sep 2021 16:41:24 +0200 Subject: [PATCH] Enable A20 gate --- Makefile | 2 +- boot/x86/a20.s | 112 +++++++++++++++++++++++++++++++++---------- boot/x86/boot | Bin 512 -> 0 bytes boot/x86/boot.s | 19 +++++--- boot/x86/print.s | 27 +++++++++++ boot/x86/protected.s | 5 -- kernel/kernel.c | 3 +- 7 files changed, 131 insertions(+), 37 deletions(-) delete mode 100644 boot/x86/boot create mode 100644 boot/x86/print.s diff --git a/Makefile b/Makefile index 9d1c344..8d4b365 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ boot.img: boot/x86/boot kernel/kernel.bin cat boot/x86/boot kernel/kernel.bin > $@ truncate -s1440K $@ -boot/x86/boot: boot/x86/boot.s boot/x86/a20.s boot/x86/protected.s +boot/x86/boot: boot/x86/boot.s boot/x86/a20.s boot/x86/protected.s boot/x86/print.s $(AS) -f bin boot/x86/boot.s -o $@ kernel/kernel.bin: ${KERNEL_OBJ} diff --git a/boot/x86/a20.s b/boot/x86/a20.s index f6a292b..b1c86ce 100644 --- a/boot/x86/a20.s +++ b/boot/x86/a20.s @@ -1,42 +1,45 @@ ; Some routines for managing the A20 line ; Check if A20 is enabled -; Based on , slightly modified -check_a20 - pushf ; save EFLAGS - ; save segment and index registers - push ds +; Based on +check_a20: + pushf + push ds push es push di push si - cli ; disable interrupts - xor ax, ax ; ax = 0 - mov es, ax ; es = 0 + cli + + xor ax, ax + mov es, ax - not ax ; ax = FFFFh - mov ds, ax ; ds = FFFFh + not ax + mov ds, ax mov di, 500h mov si, 510h - mov al, [es:di] ; preserve contents of 0:500h - mov ah, [ds:si] ; preserve contents of FFFFh:510h - push ax ; push all that to stack + mov al, byte [es:di] + push ax + + mov al, byte [ds:si] + push ax - mov byte [es:di], 0 ; set 0:500h to 0 - mov byte [ds:si], 0FFh ; set FFFFh:510h to FFh + mov byte [es:di], 0 + mov byte [ds:si], 0FFh - cmp byte [es:di], 0FFh ; compare 0:500h with FFh - ; if A20 is enabled, this will not be equal, but if A20 is disabled it will be + cmp byte [es:di], 0FFh - pop ax ; pop old contents of the 2 addresses - mov [ds:si], ah ; restore contents of FFFFh:510h - mov [es:di], al ; restore contents of 0:500h + pop ax + mov byte [ds:si], al + + pop ax + mov byte [es:di], al - xor ax, ax ; clear ax - je .exit ; if A20 is disabled, return 0 - mov ax, 1 ; otherwise return 1 + mov ax, 0 + je .exit + mov ax, 1 .exit pop si @@ -44,6 +47,67 @@ check_a20 pop es pop ds popf - sti ret +a20_i8042_wait + in al, 64h + test al, 2 + jnz a20_i8042_wait + ret + +a20_i8042_wait2 + in al, 64h + test al, 1 + jnz a20_i8042_wait2 + ret + +enable_a20 + mov ax, 2401h + int 15h + call check_a20 + cmp ax, 1 + jne .fail +.success + ret +.fail + cli ; disable interrupts + + call a20_i8042_wait + mov al, 0ADh ; disable 1st PS/2 port + out 64h, al + + call a20_i8042_wait + mov al, 0D0h ; read controller output port + out 64h, al + + call a20_i8042_wait2 + in al, 60h ; do the actual read + push ax ; save the register + + call a20_i8042_wait + mov al, 0D1h ; write byte to output port + out 64h, al + + call a20_i8042_wait + pop ax ; restore the register + or al, 2 ; toggle A20 bit + out 60h, al + + call a20_i8042_wait + mov al, 0AEh ; reenable 1st PS/2 port + out 64h, al + + call a20_i8042_wait + sti ; enable interrupts + ret + + call check_a20 + cmp ax, 1 + jne .fail2 + ret +.fail2 + mov si, A20_FAIL + call print + jmp $ + +A20_FAIL db "A20 enable fail, not booting!", 0 diff --git a/boot/x86/boot b/boot/x86/boot deleted file mode 100644 index a70865181bef901f68adda2d1ab6a34b24541678..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 512 zcmeAWld9dzFro9!eg+1^180Scq_;3_;4*l-k;&kj;qAV|yBP$4f`T?&HN3Awb~Ehg zJFIq$)$lbpjA`_m;q|{ca%|yYzYGub9r%8s@5X)x)_nr3YF(^$T`B=U)eLsWSpKUu z*#3{O>rheaU^P5Y!n}i#AugU>e(rCe1z6cefCS2&Q?e1ef*>A