Got GDT working

This commit is contained in:
2025-03-21 12:30:04 +01:00
parent 5076d1c56b
commit 05c8ee8f67
6 changed files with 71 additions and 104 deletions
+30 -37
View File
@@ -3,24 +3,6 @@
#include <kernel.h> #include <kernel.h>
/*
* Entries:
* 0 Null desc.
* 1 Kernel code desc.
* 2 Kernel data desc.
* 3 SYSENTER
* 4 SYSEXIT
* 5 User code desc.
* 6 User data desc.
* 7 Task State Segment
*/
#define GDT_ENTRIES 8
#define GDT_KERNEL_CODE 0x28
#define GDT_KERNEL_DATA 0x30
#define GDT_USER_CODE 0x50
#define GDT_USER_DATA 0x48
#define GDT_TSS 0x50
/* /*
* Segment selector explanation (why kcode is 0x08?) * Segment selector explanation (why kcode is 0x08?)
* *
@@ -47,13 +29,39 @@
#define SEGMENT_SEL(_priv, _tab, _i)\ #define SEGMENT_SEL(_priv, _tab, _i)\
(uint16_t)(((_i) << 3) | ((_tab) << 2) | (_priv)) (uint16_t)(((_i) << 3) | ((_tab) << 2) | (_priv))
/*
* Entries:
* 0 Null desc.
* 1 Kernel code desc.
* 2 Kernel data desc.
* 3 User code desc.
* 4 User data desc.
* 5 Task State Segment
*/
#define GDT_ENTRIES 6
#define GDT_NULL SEGMENT_SEL(0, 0, 0)
#define GDT_KERNEL_CODE SEGMENT_SEL(0, 0, 1)
#define GDT_KERNEL_DATA SEGMENT_SEL(0, 0, 2)
#define GDT_USER_CODE SEGMENT_SEL(3, 0, 3)
#define GDT_USER_DATA SEGMENT_SEL(3, 0, 4)
#define GDT_TSS SEGMENT_SEL(0, 0, 5)
#define GDT_DESC(_lim, _base, _acc, _flag) (struct gdt_entry){\
.limit = (_lim) & 0xffff,\
.baseLow = (uint16_t)(_base),\
.baseMid = (uint8_t)((_base) >> 16),\
.access = (_acc),\
.flags = (_flag << 4) | (((_lim) >> 16) & 0x0f),\
.baseHigh = (uint8_t)((_base) >> 24),\
}
struct gdt_entry { struct gdt_entry {
uint16_t limit; uint16_t limit;
uint16_t baseLow; uint16_t baseLow;
uint8_t baseMid; uint8_t baseMid;
uint8_t access; uint8_t access;
uint8_t granulatiry; uint8_t flags; // low 4 bits are 4 msbs of limit, high 4 bits are flags
uint8_t baseHigh; uint8_t baseHigh;
} __packed; } __packed;
struct gdt_pointer { struct gdt_pointer {
@@ -61,15 +69,6 @@ struct gdt_pointer {
uint32_t base; uint32_t base;
} __packed; } __packed;
struct tss_entry {
uint16_t length;
uint16_t baseLow;
uint8_t baseMid;
uint8_t flags1;
uint8_t flags2;
uint8_t baseHigh;
} __packed;
struct tss_pointer { struct tss_pointer {
uint16_t link; uint16_t link;
uint16_t __reserved0; uint16_t __reserved0;
@@ -90,7 +89,6 @@ struct tss_pointer {
uint32_t edx; uint32_t edx;
uint32_t ebx; uint32_t ebx;
uint32_t esp; uint32_t esp;
uint32_t ebs;
uint32_t ebp; uint32_t ebp;
uint32_t esi; uint32_t esi;
uint32_t edi; uint32_t edi;
@@ -112,11 +110,6 @@ struct tss_pointer {
uint32_t ssp; uint32_t ssp;
} __packed; } __packed;
struct gdt_entries {
struct gdt_entry descriptors[GDT_ENTRIES - 1]; // Subtract one for TSS
struct tss_entry tss;
};
int gdt_init(void); int gdt_init(void);
#endif #endif
+5 -1
View File
@@ -73,6 +73,7 @@ typedef int32_t intptr_t;
* Linker defined values * Linker defined values
*/ */
extern uint32_t __kernel_start, __kernel_end; extern uint32_t __kernel_start, __kernel_end;
extern uint32_t __kernel_stack_top, __kernel_stack_bottom;
/* /*
* Logging and errors * Logging and errors
@@ -82,7 +83,10 @@ extern uint32_t __kernel_start, __kernel_end;
#define pr_dbg(_s) printk("[debug] %s\n", (_s)) #define pr_dbg(_s) printk("[debug] %s\n", (_s))
#define pr_wrn(_s) printk("[warning] %s\n", (_s)) #define pr_wrn(_s) printk("[warning] %s\n", (_s))
#define pr_err(_s) printk("[error] %s\n", (_s)) #define pr_err(_s) printk("[error] %s\n", (_s))
#define panic(_s) printk("[panic] %s\n", (_s)) #define panic(_s) do {\
printk("[panic] %s\n", (_s));\
while (1) __asm__ volatile ("cli; hlt");\
} while (0)
#define BUG() panic("BUG()") #define BUG() panic("BUG()")
#define WARN() pr_wrn("WARN()") #define WARN() pr_wrn("WARN()")
#define BUG_ON(_e) ((_e) ? BUG() : NULL) #define BUG_ON(_e) ((_e) ? BUG() : NULL)
+7
View File
@@ -32,6 +32,13 @@ SECTIONS {
*(COMMON) *(COMMON)
*(.bss) *(.bss)
} : data } : data
/* Stack */
. = ALIGN(16);
__kernel_stack_bottom = .;
. += 16K;
__kernel_stack_top = .;
__kernel_end = .; __kernel_end = .;
/DISCARD/ : { /DISCARD/ : {
+7 -5
View File
@@ -17,20 +17,22 @@ multiboot:
dd FLAGS dd FLAGS
dd CHECK dd CHECK
section .bss
align 16
; Initialize stack ; Initialize stack
stack_bottom: section .bss
align 16
global __kernel_stack_top
global __kernel_stack_bottom
__kernel_stack_bottom:
resb 16384 resb 16384
stack_top: __kernel_stack_top:
; Entry point ; Entry point
section .text section .text
global _start global _start
extern kmain extern kmain
_start: _start:
mov esp, stack_top ; Setup stack mov esp, __kernel_stack_top
push eax push eax
push ebx push ebx
call kmain ; Call kernel main call kmain ; Call kernel main
+22 -60
View File
@@ -2,22 +2,9 @@
#include <string.h> #include <string.h>
#include <gdt.h> #include <gdt.h>
static struct gdt_entries gdt; static struct gdt_entry gdt[GDT_ENTRIES];
static struct gdt_pointer gdtp; static struct gdt_pointer gdtp;
static struct tss_pointer tss; static struct tss_pointer tss;
struct tss_pointer* tssp = &tss;
void gdt_loadTss(struct tss_pointer* ptr) {
size_t addr = (size_t)ptr;
gdt.tss.baseLow = (uint16_t)addr;
gdt.tss.baseMid = (uint8_t)(addr >> 16);
gdt.tss.flags1 = 0x89;
gdt.tss.flags2 = 0;
gdt.tss.baseHigh = (uint8_t)(addr >> 24);
__asm__ volatile ("ltr %0" : : "rm"(SEGMENT_SEL(0, 0, 7)));
}
void gdt_reload(void) { void gdt_reload(void) {
__asm__ volatile ( __asm__ volatile (
@@ -37,66 +24,41 @@ void gdt_reload(void) {
); );
} }
void tss_reload(void) {
__asm__ volatile ("ltr %0" : : "rm"(GDT_TSS));
gdt[5].access |= 0x02;
}
int gdt_init(void) { int gdt_init(void) {
// Null descriptor (0) // Null descriptor (0)
gdt.descriptors[0].limit = 0; gdt[0] = GDT_DESC(0, 0, 0, 0);
gdt.descriptors[0].baseLow = 0;
gdt.descriptors[0].baseMid = 0;
gdt.descriptors[0].access = 0;
gdt.descriptors[0].granulatiry = 0;
gdt.descriptors[0].baseHigh = 0;
// Kernel code (8) // Kernel code (8)
gdt.descriptors[1].limit = 0xffff; gdt[1] = GDT_DESC(0xfffff, 0, 0x9a, 0xc);
gdt.descriptors[1].baseLow = 0;
gdt.descriptors[1].baseMid = 0;
gdt.descriptors[1].access = 0x9a;
gdt.descriptors[1].granulatiry = 0xcf;
gdt.descriptors[1].baseHigh = 0;
// Kernel data (16) // Kernel data (16)
gdt.descriptors[2].limit = 0xffff; gdt[2] = GDT_DESC(0xfffff, 0, 0x92, 0xc);
gdt.descriptors[2].baseLow = 0;
gdt.descriptors[2].baseMid = 0;
gdt.descriptors[2].access = 0x90;
gdt.descriptors[2].granulatiry = 0xcf;
gdt.descriptors[2].baseHigh = 0;
// SYSENTER/SYSEXIT // User code (24)
gdt.descriptors[3] = (struct gdt_entry){ 0 }; // (24) gdt[3] = GDT_DESC(0xfffff, 0, 0xfa, 0xc);
gdt.descriptors[4] = (struct gdt_entry){ 0 }; // (32)
// User code (40) // User data (32)
gdt.descriptors[5].limit = 0; gdt[4] = GDT_DESC(0xfffff, 0, 0xf2, 0xc);
gdt.descriptors[5].baseLow = 0;
gdt.descriptors[5].baseMid = 0;
gdt.descriptors[5].access = 0xfa;
gdt.descriptors[5].granulatiry = 0x20;
gdt.descriptors[5].baseHigh = 0;
// User data (48) // TSS (40)
gdt.descriptors[6].limit = 0; memset(&tss, 0, sizeof(tss));
gdt.descriptors[6].baseLow = 0; gdt[5] = GDT_DESC(sizeof(tss) - 1, (uint32_t)&tss, 0x89, 0x00);
gdt.descriptors[6].baseMid = 0; tss.iopb = sizeof(struct tss_pointer);
gdt.descriptors[6].access = 0xf2; tss.esp0 = __kernel_stack_top;
gdt.descriptors[6].granulatiry = 0; tss.ss0 = GDT_KERNEL_DATA;
gdt.descriptors[6].baseHigh = 0;
// TSS (56) // GDT Pointer
gdt.tss.length = 104; gdtp.limit = sizeof(gdt) - 1;
gdt.tss.baseLow = 0;
gdt.tss.baseMid = 0;
gdt.tss.flags1 = 0x89;
gdt.tss.flags2 = 0;
gdt.tss.baseHigh = 0;
gdtp.limit = sizeof(struct gdt_entries) - 1;
gdtp.base = (uint32_t)&gdt; gdtp.base = (uint32_t)&gdt;
gdt_reload(); gdt_reload();
tss_reload();
memset(tssp, 0, sizeof(struct tss_pointer));
gdt_loadTss(tssp);
return 0; return 0;
} }
-1
View File
@@ -27,7 +27,6 @@ void kmain(void* ptr, uint32_t magic) {
gdt_init(); gdt_init();
// isr_init(); // isr_init();
// pag_init(); // pag_init();
while (1);
debugf("Basic initialization complete!\n"); debugf("Basic initialization complete!\n");