summaryrefslogtreecommitdiff
path: root/src/kernel/arch/amd64/boot64.S
diff options
context:
space:
mode:
authordzwdz2024-07-25 20:15:40 +0200
committerdzwdz2024-07-25 20:15:40 +0200
commit24934406d5d39e013e22a9e6f4138c4169460d71 (patch)
tree358f6c1dc386c50b85900a557321a256048737cd /src/kernel/arch/amd64/boot64.S
parenta6fabfb78e70b8096a8bf336aa64a3358a2f5eca (diff)
kernel: set up the GDT in assembly
This is just for simplicity's sake. I think I could even omit the `movw $TSS, (GdtTss + 2)` and have the linker fill that out as a relocation, but that would probably be more complex overall.
Diffstat (limited to 'src/kernel/arch/amd64/boot64.S')
-rw-r--r--src/kernel/arch/amd64/boot64.S33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/kernel/arch/amd64/boot64.S b/src/kernel/arch/amd64/boot64.S
new file mode 100644
index 0000000..f7ec60e
--- /dev/null
+++ b/src/kernel/arch/amd64/boot64.S
@@ -0,0 +1,33 @@
+.global boot64
+boot64:
+ lgdt (GdtPointer) // try reloading gdt again
+ mov $(6 << 3 | 3), %ax // SEG_TSS
+ ltr %ax
+
+ push %rdi // preserve multiboot struct
+ call sysenter_setup
+ pop %rdi
+
+ // multiboot struct in %rdi
+ jmp kmain_early
+
+
+.section .shared
+/* https://wiki.osdev.org/Task_State_Segment#Long_Mode */
+.global TSS
+.align 8
+TSS:
+ .4byte 0 /* reserved */
+ .rept 3
+ .8byte _isr_mini_stack /* stacks for privilege level changes */
+ .endr
+ .8byte 0 /* reserved */
+ .rept 7
+ .8byte _isr_mini_stack /* IST - stack pointer loaded for interrupts */
+ .endr
+ .8byte 0 /* reserved */
+ .4byte 0 /* reserved + IOPB (unused) */
+ .if . - TSS != 104
+ .error "bad tss size"
+ .abort
+ .endif