From 2015399687c71ce9678f23e94a2f13bb9603250b Mon Sep 17 00:00:00 2001 From: pantonshire Date: Sat, 27 Jul 2024 17:13:58 +0100 Subject: [PATCH] enter unreal mode --- boot1.s | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ defines.s | 2 + resources.md | 11 +++++- 3 files changed, 119 insertions(+), 1 deletion(-) diff --git a/boot1.s b/boot1.s index 2e5c968..32ddb0a 100644 --- a/boot1.s +++ b/boot1.s @@ -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 diff --git a/defines.s b/defines.s index d46b3a4..e6e389b 100644 --- a/defines.s +++ b/defines.s @@ -45,6 +45,8 @@ %define MEMMAP_ENT_FIELD_EXT 0x14 %define MEMMAP_ENT_FIELD_END 0x18 +%define GDT_DESCRIPTOR_SIZE 0x08 + ; boot0 base stack frame variable offsets / globals ; (we use the same offsets once we copy the variables to the globals section) ; ------------------------------------------------------------------------------------------------- diff --git a/resources.md b/resources.md index ecbf597..db81ad5 100644 --- a/resources.md +++ b/resources.md @@ -11,9 +11,12 @@ ## Boot sequence - - -- - +## Unreal mode +- +- + ## Memory - - @@ -44,3 +47,9 @@ ## Partitioning - + +## Memory protection +- +- +- +-