diff options
author | dzwdz | 2024-07-25 20:15:40 +0200 |
---|---|---|
committer | dzwdz | 2024-07-25 20:15:40 +0200 |
commit | 24934406d5d39e013e22a9e6f4138c4169460d71 (patch) | |
tree | 358f6c1dc386c50b85900a557321a256048737cd /src/kernel/arch/amd64/boot64.S | |
parent | a6fabfb78e70b8096a8bf336aa64a3358a2f5eca (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.S | 33 |
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 |