TSS setup

This commit is contained in:
2026-04-01 13:04:33 +02:00
parent 8be2a744b4
commit d644126901
2 changed files with 35 additions and 3 deletions
+14 -1
View File
@@ -13,19 +13,32 @@
// we'll only use this as a requirement for paging, not more.
// This means base 0 and no limit (whole address space)
#define NUM_GDT_ENTRIES 5
#define NUM_GDT_ENTRIES 7
#define NULL_SELECTOR 0x00
#define KERNEL_CODE_SEGMENT 0x08
#define KERNEL_DATA_SEGMENT 0x10
#define USER_CODE_SEGMENT 0x18
#define USER_DATA_SEGMENT 0x20
#define TSS_SEGMENT 0x28
struct GDTR {
uint16_t limit;
uint64_t address;
} __attribute__((packed));
struct tss {
uint32_t reserved0;
uint64_t rsp0;
uint64_t rsp1;
uint64_t rsp2;
uint64_t reserved1;
uint64_t ist[7];
uint64_t reserved2;
uint16_t reserved3;
uint16_t iopb;
} __attribute__((packed));
void gdt_init(void);
#endif
+21 -2
View File
@@ -1,6 +1,6 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Global Descriptor Table (for legacy reasons)
* @brief Global Descriptor Table and Task State Segment setup
* @license GPL-3.0-only
*/
@@ -14,6 +14,8 @@
uint64_t gdt_entries[NUM_GDT_ENTRIES];
struct GDTR gdtr;
struct tss tss = {0};
/*
* gdt_load - Loads Global Descriptor Table
*/
@@ -85,7 +87,22 @@ static void gdt_set_entry(int num, uint8_t flags, uint8_t access)
*/
static void gdt_set_tss(int num)
{
uint64_t tss_base = (uint64_t)&tss;
uint64_t tss_limit = sizeof(struct tss) - 1;
tss.iopb = sizeof(struct tss);
uint64_t tss_low = 0;
tss_low |= (tss_limit & 0xFFFFULL);
tss_low |= (tss_base & 0xFFFFFFULL) << 16;
tss_low |= 0x89ULL << 40;
tss_low |= ((tss_limit >> 16) & 0xFULL) << 48;
tss_low |= ((tss_base >> 24) & 0xFFULL) << 56;
uint64_t tss_high = (tss_base >> 32) & 0xFFFFFFFFULL;
gdt_entries[num] = tss_low;
gdt_entries[num + 1] = tss_high;
}
/*
@@ -104,6 +121,7 @@ void gdt_init()
gdt_set_entry(2, 0xC, 0x93); // Kernel data (0x10)
gdt_set_entry(3, 0xA, 0xFB); // User code (0x18)
gdt_set_entry(4, 0xC, 0xF3); // User data (0x20)
gdt_set_tss(5); // TSS (0x28)
// The -1 subtraction is some wizardry explained in the OSDev wiki -> GDT
gdtr.limit = NUM_GDT_ENTRIES * sizeof(uint64_t) - 1;
@@ -113,7 +131,8 @@ void gdt_init()
gdt_load();
gdt_flush();
// Here we should load the task register with TSS selector
// Load task register with new TSS
asm volatile("ltr %%ax" : : "a"(TSS_SEGMENT) : "memory");
DEBUG("GDT initialized");
}