enable a20
This commit is contained in:
1 parent
bf3a9d2a00
commit
575ab46109
4 files changed
+99
-16
No files matched your search
@@ -223,22 +223,25 @@ main:
|
|||||||
call vga_println
|
call vga_println
|
||||||
|
|
||||||
call test_a20
|
call test_a20
|
||||||
test ax, ax
|
test al, al
|
||||||
jnz .a20_enabled
|
jnz .a20_enabled
|
||||||
|
|
||||||
mov ax, msg_a20_disabled
|
mov ax, msg_a20_disabled
|
||||||
call vga_println
|
call vga_println
|
||||||
|
|
||||||
mov eax, 0xa1b2c3d4
|
mov ax, msg_a20_8042
|
||||||
mov ebx, 0x12345678
|
call vga_println
|
||||||
mov ecx, 0xdeadbeef
|
|
||||||
mov edx, 0xcafebabe
|
|
||||||
mov esi, 0xfeedface
|
|
||||||
mov edi, 0x66778899
|
|
||||||
panic PANIC_TYPE_A20
|
|
||||||
|
|
||||||
; TODO: enable a20
|
; Try to enable A20 using the Intel 8042 PS/2 keyboard controller.
|
||||||
hlt
|
call enable_a20_intel_8042
|
||||||
|
call test_a20
|
||||||
|
test al, al
|
||||||
|
jnz .a20_enabled
|
||||||
|
|
||||||
|
; TODO: try other methods first before we panic:
|
||||||
|
; - [ ] BIOS interrupt
|
||||||
|
; - [ ] Fast A20 enable
|
||||||
|
panic PANIC_TYPE_A20
|
||||||
|
|
||||||
.a20_enabled:
|
.a20_enabled:
|
||||||
mov ax, msg_a20_enabled
|
mov ax, msg_a20_enabled
|
||||||
@@ -596,11 +599,6 @@ nybble_to_hex_char:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
enable_a20:
|
|
||||||
fnstart
|
|
||||||
fnret
|
|
||||||
|
|
||||||
|
|
||||||
; Check whether the A20 line is enabled. Writes to the boot sector identifier.
|
; Check whether the A20 line is enabled. Writes to the boot sector identifier.
|
||||||
; Arguments: none
|
; Arguments: none
|
||||||
; Return:
|
; Return:
|
||||||
@@ -638,9 +636,78 @@ test_a20:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; Wait for the Intel 8042 input buffer to become empty, so we can write.
|
||||||
|
; Arguments: none
|
||||||
|
; Return: none
|
||||||
|
; Clobber: al
|
||||||
|
intel_8042_wait_write:
|
||||||
|
.loop:
|
||||||
|
; Read the 8042 status register.
|
||||||
|
in al, INTEL_8042_IN_STATUS
|
||||||
|
; Input buffer status flag set means the input buffer is full, so loop in this case.
|
||||||
|
test al, (1 << INTEL_8042_STATUS_IBUF)
|
||||||
|
jnz .loop
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; Wait for the Intel 8042 output buffer to become filled, so we can read.
|
||||||
|
; Arguments: none
|
||||||
|
; Return: none
|
||||||
|
; Clobber: al
|
||||||
|
intel_8042_wait_read:
|
||||||
|
.loop:
|
||||||
|
; Read the 8042 status register.
|
||||||
|
in al, INTEL_8042_IN_STATUS
|
||||||
|
; Output buffer status flag unset means output buffer is empty, so loop in this case.
|
||||||
|
test al, (1 << INTEL_8042_STATUS_OBUF)
|
||||||
|
jz .loop
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; Try to enable A20 using the Intel 8042 PS/2 keyboard controller.
|
||||||
|
; Arguments: none
|
||||||
|
; Return: none
|
||||||
|
; Clobber: ax, cx, dx
|
||||||
|
enable_a20_intel_8042:
|
||||||
|
; Temporarily disable the keyboard.
|
||||||
|
call intel_8042_wait_write
|
||||||
|
mov al, INTEL_8042_CMD_PS2_1_DISABLE
|
||||||
|
out INTEL_8042_OUT_CMD, al
|
||||||
|
|
||||||
|
; Read the controller output port.
|
||||||
|
call intel_8042_wait_write
|
||||||
|
mov al, INTEL_8042_CMD_CONTROLLER_OUT_PORT_READ
|
||||||
|
out INTEL_8042_OUT_CMD, al
|
||||||
|
call intel_8042_wait_read
|
||||||
|
in al, INTEL_8042_IO_DATA
|
||||||
|
|
||||||
|
; The second bit is "A20 enabled", so set it.
|
||||||
|
mov cl, al
|
||||||
|
or cl, 2
|
||||||
|
|
||||||
|
; Write the modified byte back to the controller output port.
|
||||||
|
call intel_8042_wait_write
|
||||||
|
mov al, INTEL_8042_CMD_CONTROLLER_OUT_PORT_WRITE
|
||||||
|
out INTEL_8042_OUT_CMD, al
|
||||||
|
call intel_8042_wait_write
|
||||||
|
mov al, cl
|
||||||
|
out INTEL_8042_IO_DATA, al
|
||||||
|
|
||||||
|
; Re-enable the keyboard.
|
||||||
|
call intel_8042_wait_write
|
||||||
|
mov al, INTEL_8042_CMD_PS2_1_ENABLE
|
||||||
|
out INTEL_8042_OUT_CMD, al
|
||||||
|
|
||||||
|
; Wait for writes to finish.
|
||||||
|
call intel_8042_wait_write
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
msg_boot1_loaded db "boot1 loaded. hello!", 0
|
msg_boot1_loaded db "boot1 loaded. hello!", 0
|
||||||
msg_a20_enabled db "a20 enabled", 0
|
msg_a20_enabled db "a20 enabled", 0
|
||||||
msg_a20_disabled db "a20 not enabled", 0
|
msg_a20_disabled db "a20 not enabled", 0
|
||||||
|
msg_a20_8042 db "trying 8042", 0
|
||||||
msg_panic db "panic!", 0
|
msg_panic db "panic!", 0
|
||||||
|
|
||||||
msg_reg_eip db "eip", 0
|
msg_reg_eip db "eip", 0
|
||||||
|
|||||||
@@ -11,6 +11,18 @@
|
|||||||
%define VGA_WIDTH 80
|
%define VGA_WIDTH 80
|
||||||
%define VGA_HEIGHT 25
|
%define VGA_HEIGHT 25
|
||||||
|
|
||||||
|
%define INTEL_8042_IO_DATA 0x60
|
||||||
|
%define INTEL_8042_IN_STATUS 0x64
|
||||||
|
%define INTEL_8042_OUT_CMD 0x64
|
||||||
|
|
||||||
|
%define INTEL_8042_STATUS_OBUF 0
|
||||||
|
%define INTEL_8042_STATUS_IBUF 1
|
||||||
|
|
||||||
|
%define INTEL_8042_CMD_PS2_1_DISABLE 0xad
|
||||||
|
%define INTEL_8042_CMD_PS2_1_ENABLE 0xae
|
||||||
|
%define INTEL_8042_CMD_CONTROLLER_OUT_PORT_READ 0xd0
|
||||||
|
%define INTEL_8042_CMD_CONTROLLER_OUT_PORT_WRITE 0xd1
|
||||||
|
|
||||||
; boot0 base stack frame variable offsets / globals
|
; boot0 base stack frame variable offsets / globals
|
||||||
; (we use the same offsets once we copy the variables to the globals section)
|
; (we use the same offsets once we copy the variables to the globals section)
|
||||||
; -------------------------------------------------------------------------------------------------
|
; -------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ fit into 440 bytes. Its tasks are:
|
|||||||
|
|
||||||
`boot1.s` is the second-stage bootloader. Its tasks are:
|
`boot1.s` is the second-stage bootloader. Its tasks are:
|
||||||
- [x] Load its own sectors not loaded by the first stage
|
- [x] Load its own sectors not loaded by the first stage
|
||||||
- [ ] Enable A20
|
- [x] Enable A20
|
||||||
- [ ] Detect available memory
|
- [ ] Detect available memory
|
||||||
- [ ] Enter unreal mode
|
- [ ] Enter unreal mode
|
||||||
- [ ] Read the kernel ELF from disk (don't have to parse the ELF just yet)
|
- [ ] Read the kernel ELF from disk (don't have to parse the ELF just yet)
|
||||||
|
|||||||
@@ -33,3 +33,7 @@
|
|||||||
## ELF
|
## ELF
|
||||||
- <https://wiki.osdev.org/ELF>
|
- <https://wiki.osdev.org/ELF>
|
||||||
- <https://wiki.osdev.org/ELF_Tutorial>
|
- <https://wiki.osdev.org/ELF_Tutorial>
|
||||||
|
|
||||||
|
## Intel 8042 PS/2 controller
|
||||||
|
- <https://wiki.osdev.org/%228042%22_PS/2_Controller>
|
||||||
|
- <https://wiki.osdev.org/I/O_Ports>
|
||||||
Reference in new issue
Block a user