Kernel: move GDT initialization to boot.S

This commit is contained in:
Bananymous 2023-01-22 00:47:25 +02:00
parent aac7595a47
commit 491610db2c
5 changed files with 88 additions and 132 deletions

View File

@ -1,113 +0,0 @@
#include <kernel/GDT.h>
#include <stdint.h>
namespace GDT
{
union SegmentDesriptor
{
struct
{
uint16_t limit_lo;
uint16_t base_lo;
uint8_t base_hi1;
uint8_t type : 4;
uint8_t system : 1;
uint8_t DPL : 2;
uint8_t present : 1;
uint8_t limit_hi : 4;
uint8_t flags : 4;
uint8_t base_hi2;
} __attribute__((packed));
struct
{
uint32_t low;
uint32_t high;
} __attribute__((packed));
SegmentDesriptor() : low(0), high(0) {}
SegmentDesriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t _flags)
: low(0), high(0)
{
set_base(base);
set_limit(limit);
high |= ((uint16_t)access) << 8;
flags = _flags;
}
void set_base(uint32_t base)
{
base_lo = base & 0xFFFF;
base_hi1 = (base >> 16) & 0x00FF;
base_hi2 = (base >> 24) & 0x00FF;
}
void set_limit(uint32_t limit)
{
limit_lo = limit & 0xFFFF;
limit_hi = (limit >> 16) & 0x00FF;
}
} __attribute__((packed));
struct GDTR
{
uint16_t size;
void* address;
} __attribute__((packed));
static GDTR s_gdtr;
static SegmentDesriptor s_gdt[5];
extern "C" void load_gdt(void* gdt_ptr);
asm(
".global load_gdt;"
"load_gdt:"
"movl 4(%esp),%eax;"
"lgdt (%eax);"
"movw $0x10, %ax;"
"movw %ax, %ds;"
"movw %ax, %es;"
"movw %ax, %fs;"
"movw %ax, %gs;"
"movw %ax, %ss;"
"jmp $0x08,$flush;"
"flush:"
"ret;"
);
void write_entry_raw(uint8_t segment, uint32_t low, uint32_t high)
{
uint8_t index = segment >> 3;
s_gdt[index].low = low;
s_gdt[index].high = high;
}
void write_entry(uint8_t segment, SegmentDesriptor descriptor)
{
write_entry_raw(segment, descriptor.low, descriptor.high);
}
void initialize()
{
s_gdtr.address = s_gdt;
s_gdtr.size = sizeof(s_gdt) - 1;
write_entry(0x00, { 0, 0x00000, 0x00, 0x0 }); // null
write_entry(0x08, { 0, 0xFFFFF, 0x9A, 0xC }); // kernel code
write_entry(0x10, { 0, 0xFFFFF, 0x92, 0xC }); // kernel data
write_entry(0x18, { 0, 0xFFFFF, 0xFA, 0xC }); // user code
write_entry(0x20, { 0, 0xFFFFF, 0xF2, 0xC }); // user data
load_gdt(&s_gdtr);
}
}

View File

@ -29,6 +29,13 @@
g_kernel_cmdline:
.skip 4096
.global g_gdtr
g_gdtr:
.skip 2 + 4
.global g_gdt
g_gdt:
.skip 5 * 8
# Reserve memory for paging structures,
# we will identity map first 4 MiB
@ -110,19 +117,7 @@ enable_sse:
movl %eax, %cr4
ret
.global _start
.type _start, @function
_start:
# Initialize stack and multiboot info
movl $stack_top, %esp
movl %eax, g_multiboot_magic
movl %ebx, g_multiboot_info
# Copy kernel command line to known location
call copy_kernel_commandline
call check_requirements
call enable_sse
initialize_paging:
# identity map first 4 MiB
movl $(0x00000000 + 0x83), boot_page_directory1 + 0
movl $(0x00200000 + 0x83), boot_page_directory1 + 8
@ -142,14 +137,55 @@ _start:
orl $0x80000000, %ecx
movl %ecx, %cr0
# call global constuctors
ret
initialize_gdt:
# setup gdt
movw $(5 * 8 - 1), g_gdtr
movl $(g_gdt), g_gdtr + 2
movl $(0x0000FFFF), g_gdt + 0x08
movl $(0x00CF9A00), g_gdt + 0x08 + 4
movl $(0x0000FFFF), g_gdt + 0x10
movl $(0x00CF9200), g_gdt + 0x10 + 4
movl $(0x0000FFFF), g_gdt + 0x18
movl $(0x00CFFA00), g_gdt + 0x18 + 4
movl $(0x0000FFFF), g_gdt + 0x20
movl $(0x00CFF200), g_gdt + 0x20 + 4
lgdt g_gdtr
# flush gdt
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
jmp $0x08, $flush
flush:
ret
.global _start
.type _start, @function
_start:
# Initialize stack and multiboot info
movl $stack_top, %esp
movl %eax, g_multiboot_magic
movl %ebx, g_multiboot_info
call copy_kernel_commandline
call check_requirements
call enable_sse
call initialize_paging
call initialize_gdt
call _init
# call to the kernel itself (clear ebp for stacktrace)
xorl %ebp, %ebp
call kernel_main
# call global destructors
call _fini
system_halt:

View File

@ -7,7 +7,6 @@ KERNEL_ARCH_OBJS= \
$(ARCHDIR)/APIC.o \
$(ARCHDIR)/boot.o \
$(ARCHDIR)/CPUID.o \
$(ARCHDIR)/GDT.o \
$(ARCHDIR)/IDT.o \
$(ARCHDIR)/MMU.o \
$(ARCHDIR)/Panic.o \

View File

@ -1,8 +1,44 @@
#pragma once
#include <stdint.h>
namespace GDT
{
void initialize();
union SegmentDesriptor
{
struct
{
uint16_t limit_lo;
uint16_t base_lo;
uint8_t base_hi1;
uint8_t type : 4;
uint8_t system : 1;
uint8_t DPL : 2;
uint8_t present : 1;
uint8_t limit_hi : 4;
uint8_t flags : 4;
uint8_t base_hi2;
} __attribute__((packed));
struct
{
uint32_t low;
uint32_t high;
} __attribute__((packed));
} __attribute__((packed));
struct GDTR
{
uint16_t size;
void* address;
} __attribute__((packed));
extern "C" GDTR g_gdtr[];
extern "C" SegmentDesriptor g_gdt[];
}

View File

@ -70,8 +70,6 @@ extern "C" void kernel_main()
kmalloc_initialize();
dprintln("kmalloc initialized");
GDT::initialize();
dprintln("GDT initialized");
IDT::initialize();
dprintln("IDT initialized");