summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/boot.s56
1 files changed, 56 insertions, 0 deletions
diff --git a/kernel/boot.s b/kernel/boot.s
index d1f5606..8d07354 100644
--- a/kernel/boot.s
+++ b/kernel/boot.s
@@ -7,6 +7,7 @@ extern con_init
extern fs_init
extern kmain
extern paging_init
+extern panic
extern printk
extern syscall_init
extern timer_init
@@ -33,6 +34,7 @@ kboot:
mov esp, 0x80000
; setup descriptor tables and enable paging
call flush_gdt
+ call enable_a20
call paging_init
call flush_idt
; initialize the console
@@ -218,6 +220,60 @@ register_trap:
pop ebp
ret
+enable_a20:
+ push ebp
+ mov ebp, esp
+ ; test if the A20 gate was already enabled
+ call .testgate
+ jne .end
+ ; send read controller output port command
+ call .waitout
+ mov al, 0xD0
+ out 0x64, al
+ ; read controller output port
+ call .waitin
+ in al, 0x60
+ xchg ax, cx
+ ; send write controller output port command
+ call .waitout
+ mov al, 0xD1
+ out 0x64, al
+ ; write controller output port (enabling gate A20)
+ call .waitout
+ xchg ax, cx
+ or al, 0x02
+ out 0x60, al
+ ; make sure the gate is working (panic if not)
+ call .testgate
+ jne .end
+ push .msg
+ call printk
+ add sp, 4
+ call panic
+.waitin:
+ in al, 0x64
+ test al, 0x01
+ jz .waitin
+ ret
+.waitout:
+ in al, 0x64
+ test al, 0x02
+ jnz .waitout
+ ret
+.testgate:
+ ; test if the A20 gate is enabled by depositing
+ ; two words 1MB away from each other in memory.
+ mov word [.tmp+0x100000], 0xBEEF
+ mov cx, [.tmp]
+ mov dx, [.tmp+0x100000]
+ cmp cx, dx
+ ret
+.end:
+ pop ebp
+ ret
+.tmp: dw 0xDEAD
+.msg: db "Failed to enable A20 gate!", 10, 0
+
pic_init:
push ebp
mov ebp, esp