diff --git a/kernel/include/gdt.h b/kernel/include/gdt.h index 750f9ef..134c813 100644 --- a/kernel/include/gdt.h +++ b/kernel/include/gdt.h @@ -3,24 +3,6 @@ #include -/* - * 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?) * @@ -47,13 +29,39 @@ #define SEGMENT_SEL(_priv, _tab, _i)\ (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 { uint16_t limit; uint16_t baseLow; - uint8_t baseMid; - uint8_t access; - uint8_t granulatiry; - uint8_t baseHigh; + uint8_t baseMid; + uint8_t access; + uint8_t flags; // low 4 bits are 4 msbs of limit, high 4 bits are flags + uint8_t baseHigh; } __packed; struct gdt_pointer { @@ -61,15 +69,6 @@ struct gdt_pointer { uint32_t base; } __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 { uint16_t link; uint16_t __reserved0; @@ -90,7 +89,6 @@ struct tss_pointer { uint32_t edx; uint32_t ebx; uint32_t esp; - uint32_t ebs; uint32_t ebp; uint32_t esi; uint32_t edi; @@ -112,11 +110,6 @@ struct tss_pointer { uint32_t ssp; } __packed; -struct gdt_entries { - struct gdt_entry descriptors[GDT_ENTRIES - 1]; // Subtract one for TSS - struct tss_entry tss; -}; - int gdt_init(void); #endif diff --git a/kernel/include/kernel.h b/kernel/include/kernel.h index 021a2c5..1add0d5 100644 --- a/kernel/include/kernel.h +++ b/kernel/include/kernel.h @@ -73,6 +73,7 @@ typedef int32_t intptr_t; * Linker defined values */ extern uint32_t __kernel_start, __kernel_end; +extern uint32_t __kernel_stack_top, __kernel_stack_bottom; /* * 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_wrn(_s) printk("[warning] %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 WARN() pr_wrn("WARN()") #define BUG_ON(_e) ((_e) ? BUG() : NULL) diff --git a/kernel/linker.ld b/kernel/linker.ld index 663efa1..481c415 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -32,6 +32,13 @@ SECTIONS { *(COMMON) *(.bss) } : data + + /* Stack */ + . = ALIGN(16); + __kernel_stack_bottom = .; + . += 16K; + __kernel_stack_top = .; + __kernel_end = .; /DISCARD/ : { diff --git a/kernel/src/entry.s b/kernel/src/entry.s index 3f87166..17323ea 100644 --- a/kernel/src/entry.s +++ b/kernel/src/entry.s @@ -17,20 +17,22 @@ multiboot: dd FLAGS dd CHECK -section .bss -align 16 ; Initialize stack -stack_bottom: +section .bss +align 16 +global __kernel_stack_top +global __kernel_stack_bottom +__kernel_stack_bottom: resb 16384 -stack_top: +__kernel_stack_top: ; Entry point section .text global _start extern kmain _start: - mov esp, stack_top ; Setup stack + mov esp, __kernel_stack_top push eax push ebx call kmain ; Call kernel main diff --git a/kernel/src/gdt.c b/kernel/src/gdt.c index 2f3b339..a3af72e 100644 --- a/kernel/src/gdt.c +++ b/kernel/src/gdt.c @@ -2,22 +2,9 @@ #include #include -static struct gdt_entries gdt; +static struct gdt_entry gdt[GDT_ENTRIES]; static struct gdt_pointer gdtp; 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) { __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) { // Null descriptor (0) - gdt.descriptors[0].limit = 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; + gdt[0] = GDT_DESC(0, 0, 0, 0); // Kernel code (8) - gdt.descriptors[1].limit = 0xffff; - 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; + gdt[1] = GDT_DESC(0xfffff, 0, 0x9a, 0xc); // Kernel data (16) - gdt.descriptors[2].limit = 0xffff; - 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; + gdt[2] = GDT_DESC(0xfffff, 0, 0x92, 0xc); - // SYSENTER/SYSEXIT - gdt.descriptors[3] = (struct gdt_entry){ 0 }; // (24) - gdt.descriptors[4] = (struct gdt_entry){ 0 }; // (32) + // User code (24) + gdt[3] = GDT_DESC(0xfffff, 0, 0xfa, 0xc); - // User code (40) - gdt.descriptors[5].limit = 0; - 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 (32) + gdt[4] = GDT_DESC(0xfffff, 0, 0xf2, 0xc); - // User data (48) - gdt.descriptors[6].limit = 0; - gdt.descriptors[6].baseLow = 0; - gdt.descriptors[6].baseMid = 0; - gdt.descriptors[6].access = 0xf2; - gdt.descriptors[6].granulatiry = 0; - gdt.descriptors[6].baseHigh = 0; + // TSS (40) + memset(&tss, 0, sizeof(tss)); + gdt[5] = GDT_DESC(sizeof(tss) - 1, (uint32_t)&tss, 0x89, 0x00); + tss.iopb = sizeof(struct tss_pointer); + tss.esp0 = __kernel_stack_top; + tss.ss0 = GDT_KERNEL_DATA; - // TSS (56) - gdt.tss.length = 104; - 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; + // GDT Pointer + gdtp.limit = sizeof(gdt) - 1; gdtp.base = (uint32_t)&gdt; gdt_reload(); + tss_reload(); - memset(tssp, 0, sizeof(struct tss_pointer)); - gdt_loadTss(tssp); return 0; } diff --git a/kernel/src/kernel.c b/kernel/src/kernel.c index e7a815d..b7f5c6a 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kernel.c @@ -27,7 +27,6 @@ void kmain(void* ptr, uint32_t magic) { gdt_init(); // isr_init(); // pag_init(); - while (1); debugf("Basic initialization complete!\n");