1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00

Reload GDT with the descriptor VMA once the CPU switches to 64-bit mode

The GDT is initially loaded in the 32-bit rt0 code where we cannot use
the 48-bit VMA for the GDT table and instead we use its physical
address. This approach works as the rt0 code establishes an identity
mapping for the region 0-8M. However, when the kernel creates a more
granular PDT it only includes the VMA addresses for the kernel ELF image
sections making the 0-8M invalid. Unless the GDT is reloaded with the
VMA of the table, the CPU will cause a non-recoverable page fault when
it tries to restore the segment registers while returning from a
recoverable page fault.
This commit is contained in:
Achilleas Anagnostopoulos 2017-07-12 23:31:54 +01:00
parent 9d2e53bac4
commit 4e0ad81770

View File

@ -355,6 +355,20 @@ write_string:
;------------------------------------------------------------------------------
bits 64
_rt0_64_entry_trampoline:
; The currently loaded GDT points to the physical address of gdt0. This
; works for now since we identity map the first 8M of the kernel. When
; we set up a proper PDT for the VMA address of the kernel, the 0-8M
; mapping will be invalid causing a page fault when the CPU tries to
; restore the segment registers while returning from the page fault
; handler.
;
; To fix this, we need to update the GDT so it uses the 48-bit virtual
; address of gdt0.
mov rax, gdt0_desc
mov rbx, gdt0
mov qword [rax+2], rbx
lgdt [rax]
mov rsp, stack_top ; now that paging is enabled we can load the stack
; with the virtual address of the allocated stack.