syscall #17
+14
-1
@@ -13,19 +13,32 @@
|
|||||||
// we'll only use this as a requirement for paging, not more.
|
// we'll only use this as a requirement for paging, not more.
|
||||||
// This means base 0 and no limit (whole address space)
|
// 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 NULL_SELECTOR 0x00
|
||||||
#define KERNEL_CODE_SEGMENT 0x08
|
#define KERNEL_CODE_SEGMENT 0x08
|
||||||
#define KERNEL_DATA_SEGMENT 0x10
|
#define KERNEL_DATA_SEGMENT 0x10
|
||||||
#define USER_CODE_SEGMENT 0x18
|
#define USER_CODE_SEGMENT 0x18
|
||||||
#define USER_DATA_SEGMENT 0x20
|
#define USER_DATA_SEGMENT 0x20
|
||||||
|
#define TSS_SEGMENT 0x28
|
||||||
|
|
||||||
struct GDTR {
|
struct GDTR {
|
||||||
uint16_t limit;
|
uint16_t limit;
|
||||||
uint64_t address;
|
uint64_t address;
|
||||||
} __attribute__((packed));
|
} __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);
|
void gdt_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+21
-2
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* @author xamidev <xamidev@riseup.net>
|
* @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
|
* @license GPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
uint64_t gdt_entries[NUM_GDT_ENTRIES];
|
uint64_t gdt_entries[NUM_GDT_ENTRIES];
|
||||||
struct GDTR gdtr;
|
struct GDTR gdtr;
|
||||||
|
|
||||||
|
struct tss tss = {0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gdt_load - Loads Global Descriptor Table
|
* 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)
|
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(2, 0xC, 0x93); // Kernel data (0x10)
|
||||||
gdt_set_entry(3, 0xA, 0xFB); // User code (0x18)
|
gdt_set_entry(3, 0xA, 0xFB); // User code (0x18)
|
||||||
gdt_set_entry(4, 0xC, 0xF3); // User data (0x20)
|
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
|
// The -1 subtraction is some wizardry explained in the OSDev wiki -> GDT
|
||||||
gdtr.limit = NUM_GDT_ENTRIES * sizeof(uint64_t) - 1;
|
gdtr.limit = NUM_GDT_ENTRIES * sizeof(uint64_t) - 1;
|
||||||
@@ -113,7 +131,8 @@ void gdt_init()
|
|||||||
gdt_load();
|
gdt_load();
|
||||||
gdt_flush();
|
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");
|
DEBUG("GDT initialized");
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user