Code: Select all
/* The bootloader will look at this image and start execution at the symbol
designated at the entry point. */
ENTRY(kstart)
INPUT(
obj/kernel.o
obj/terminal.o
obj/mem.o
obj/idt.o
obj/gdt.o
obj/paging.o
obj/acpi.o
)
OUTPUT(kernel.elf)
OUTPUT_FORMAT(elf32-i386)
STARTUP(obj/kstart.o)
/* Tell where the various sections of the object files will be put in the final
kernel image. */
SECTIONS
{
/* Begin putting sections at the higher half. */
. = 0xC0000000;
/* the .text section. */
.text : ALIGN(4K)
{
*(.text)
}
/* Read-only data. */
.rodata : ALIGN(4K)
{
*(.rodata)
}
/* Read-write data (initialized) */
.data : ALIGN(4K)
{
*(.data)
}
/* Read-write data (uninitialized) and stack */
.bss : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
/* hardware tables */
. = 0xC0100000;
.gdt BLOCK(64K) :
{
gdt = .;
. = . + 64K;
}
.tss BLOCK(4K) : ALIGN(4K)
{
default_tss = .;
. = . + 4K;
}
.idt BLOCK(4K) : ALIGN(4K)
{
idt = .;
. = . + 4K;
}
.paging BLOCK(4K) : ALIGN(4K)
{
page_directory = .;
. = . + 4K;
page_tables = .;
. = . + (1K * 4K);
}
/* set up the stack */
.stack : ALIGN(4M)
{
stack_base = .;
*(.stack)
}
}
When I went to replace the stub GDT from my bootloader with one constructed by and accessible to the kernel, it worked exactly as before.
Code: Select all
void reset_gdt()
{
struct GDT_R gdt_r = { sizeof(union GDT_Entry) * MAX_GDT_ENTRIES, gdt };
union GDT_Entry *entry = gdt;
// set the null GDT entry
entry->raw_entry = 0;
// system code selector
set_gdt_entry(++entry, 0x0fffff, 0, true, true, RING_0);
// system data selector
set_gdt_entry(++entry, 0x0fffff, 0, false, true, RING_0);
// system TSS selector
set_gdt_entry(entry, (uint32_t) default_tss, sizeof(struct TSS), false, true, RING_0);
(entry++)->fields.access.non_sys = false;
// user code selector
set_gdt_entry(++entry, 0x08ffff, 0, true, true, RING_3);
// user data selector
set_gdt_entry(++entry, 0x08ffff, 0, false, true, RING_3);
// set the GDT register
__asm__ __volatile__ (
"lgdt %0"
:
: "m" (gdt_r));
}
I am not certain how to check this further. I know that there is a SGDT instruction, and I suppose I could write a function to check the GDTR's values using that, but I am not certain just what that would accomplish.
Can anyone see anything I've missed?