diff options
| -rw-r--r-- | kernel/boot.s | 56 |
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 |
