|
|
|
|
@ -252,6 +252,8 @@ main:
|
|
|
|
|
|
|
|
|
|
call print_memmap
|
|
|
|
|
|
|
|
|
|
call unreal_enable
|
|
|
|
|
|
|
|
|
|
.hlt_loop:
|
|
|
|
|
hlt
|
|
|
|
|
jmp .hlt_loop
|
|
|
|
|
@ -746,6 +748,42 @@ enable_a20_intel_8042:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unreal_enable:
|
|
|
|
|
fnstart
|
|
|
|
|
push ds
|
|
|
|
|
|
|
|
|
|
; Load GDT
|
|
|
|
|
lgdt [unreal_setup_gdt_slice]
|
|
|
|
|
|
|
|
|
|
; Switch to protected mode.
|
|
|
|
|
mov eax, cr0
|
|
|
|
|
or al, 0x01
|
|
|
|
|
mov cr0, eax
|
|
|
|
|
; Set the code segment to the code segment in our GDT (offset 0x08)
|
|
|
|
|
jmp (GDT_DESCRIPTOR_SIZE):.protected_mode
|
|
|
|
|
|
|
|
|
|
.protected_mode:
|
|
|
|
|
; In protected mode, the value in a segment register refers to an offset into the GDT. Setting
|
|
|
|
|
; a segment register updates the segment descriptor cache with the selected GDT descriptor. The
|
|
|
|
|
; limit of our second GDT descriptor is 0xfffff pages, which covers the entire 32-bit address
|
|
|
|
|
; space. This limit is unchanged when we return to real mode, so we'll be able to address the
|
|
|
|
|
; whole 32-bit address space.
|
|
|
|
|
mov ax, (2 * GDT_DESCRIPTOR_SIZE)
|
|
|
|
|
mov ds, ax
|
|
|
|
|
|
|
|
|
|
; Switch back to real mode.
|
|
|
|
|
mov eax, cr0
|
|
|
|
|
and eax, 0xfe
|
|
|
|
|
mov cr0, eax
|
|
|
|
|
; Reset code segment back to 0 since we're using real-mode addressing again
|
|
|
|
|
; (0x08 would now offset us by 16 * 8 = 128 bytes if we left it there)
|
|
|
|
|
jmp 0x00:.unreal_mode
|
|
|
|
|
|
|
|
|
|
.unreal_mode:
|
|
|
|
|
pop ds
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; FIXME:
|
|
|
|
|
; - We want this to work in a streaming fashion, so we can see all the reserved regions even if we
|
|
|
|
|
; don't have enough space to store all the regions. We can always rerun with a different buffer
|
|
|
|
|
@ -921,6 +959,75 @@ print_memmap:
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unreal_setup_gdt_slice:
|
|
|
|
|
dw UNREAL_SETUP_GDT_LEN
|
|
|
|
|
dd unreal_setup_gdt
|
|
|
|
|
|
|
|
|
|
; Segment descriptor layout
|
|
|
|
|
; | Range (bits) | Field |
|
|
|
|
|
; |--------------|---------------|
|
|
|
|
|
; | 0-16 | limit |
|
|
|
|
|
; | 16-32 | base |
|
|
|
|
|
; | 32-40 | base cont. |
|
|
|
|
|
; | 40-48 | access |
|
|
|
|
|
; | 48-52 | limit cont. |
|
|
|
|
|
; | 52-56 | flags |
|
|
|
|
|
; | 56-64 | base cont. |
|
|
|
|
|
;
|
|
|
|
|
; Flags
|
|
|
|
|
; - 0: reserved
|
|
|
|
|
; - 1: long-mode code segment
|
|
|
|
|
; - 2: size
|
|
|
|
|
; - unset: 16-bit
|
|
|
|
|
; - set: 32-bit
|
|
|
|
|
; - 3: granularity
|
|
|
|
|
; - unset: limit is measured in bytes
|
|
|
|
|
; - set: limit is measured in 4KiB pages
|
|
|
|
|
;
|
|
|
|
|
; Access
|
|
|
|
|
; - 0: accessed
|
|
|
|
|
; - unset: CPU will set it when the segment is accessed
|
|
|
|
|
; - 1: readable / writable
|
|
|
|
|
; - data segments: is segment writable (data segments are always readable)
|
|
|
|
|
; - code segments: is segment readable (code segments are never writable)
|
|
|
|
|
; - 2: direction / conforming
|
|
|
|
|
; - data segments: whether segment grows down
|
|
|
|
|
; - code segments: whether this can be executed from a lower-privilege ring
|
|
|
|
|
; - 3: executable
|
|
|
|
|
; - unset: this is a data segment
|
|
|
|
|
; - set: this is a code segment
|
|
|
|
|
; - 4: descriptor type
|
|
|
|
|
; - unset: this is a task state segment
|
|
|
|
|
; - set: this is a data or code segment
|
|
|
|
|
; - 5-6: privilege level (ring number)
|
|
|
|
|
; - 7: present (must be set)
|
|
|
|
|
;
|
|
|
|
|
unreal_setup_gdt:
|
|
|
|
|
dq 0
|
|
|
|
|
|
|
|
|
|
; Code segment for low memory, bytes 0x0000 - 0xffff
|
|
|
|
|
.segment_code:
|
|
|
|
|
db 0xff, 0xff, \
|
|
|
|
|
0x00, 0x00, \
|
|
|
|
|
0x00, \
|
|
|
|
|
010011011b, \
|
|
|
|
|
00000000b, \
|
|
|
|
|
0x00
|
|
|
|
|
|
|
|
|
|
; Data segment for pages 0x000000 - 0x0fffff, which covers the entire 32-bit address space
|
|
|
|
|
; (start of 0xfffff-th page is 0xfffff * 4096 = 0xfffff000, end of page exclusive is
|
|
|
|
|
; 0xfffff000 + 4096 = 0x100000000)
|
|
|
|
|
.segment_data:
|
|
|
|
|
db 0xff, 0xff, \
|
|
|
|
|
0x00, 0x00, \
|
|
|
|
|
0x00, \
|
|
|
|
|
10010011b, \
|
|
|
|
|
11001111b, \
|
|
|
|
|
0x00
|
|
|
|
|
|
|
|
|
|
UNREAL_SETUP_GDT_LEN equ ($ - unreal_setup_gdt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
msg_boot1_loaded db "boot1 loaded. hello!", 0
|
|
|
|
|
msg_a20_enabled db "a20 enabled", 0
|
|
|
|
|
msg_a20_disabled db "a20 not enabled", 0
|
|
|
|
|
|