gdt idt stuff

This commit is contained in:
2026-06-12 23:03:00 -04:00
parent 5e823e570b
commit 00fb70c25b
7 changed files with 67 additions and 19 deletions

View File

@@ -57,6 +57,12 @@ void vga_initialize()
void vga_putchar(char c)
{
if (c == '\n') {
terminal_row++;
terminal_column = 0;
return;
}
const size_t index = terminal_row * VGA_WIDTH + terminal_column;
terminal_buffer[index] = vga_entry(c, terminal_color);
if (++terminal_column == VGA_WIDTH) {

View File

@@ -40,23 +40,44 @@
#define GDT_DATA_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
SEG_PRIV(3) | SEG_DATA_RDWR
typedef struct __attribute__((packed)) {
uint16_t limit;
uint32_t base;
} gdt_ptr_t;
uint64_t gdt[5];
gdt_ptr_t gdtr;
extern void load_gdt();
uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag)
{
uint64_t descriptor;
// Create the high 32 bit segment
descriptor = limit & 0x000F0000; // set limit bits 19:16
descriptor |= (flag << 8) & 0x00F0FF00; // set type, p, dpl, s, g, d/b, l and avl fields
descriptor |= (base >> 16) & 0x000000FF; // set base bits 23:16
descriptor |= base & 0xFF000000; // set base bits 31:24
descriptor = limit & 0x000F0000;
descriptor |= (flag << 8) & 0x00F0FF00;
descriptor |= (base >> 16) & 0x000000FF;
descriptor |= base & 0xFF000000;
// Shift by 32 to allow for low part of segment
descriptor <<= 32;
// Create the low 32 bit segment
descriptor |= base << 16; // set base bits 15:0
descriptor |= limit & 0x0000FFFF; // set limit bits 15:0
descriptor |= base << 16;
descriptor |= limit & 0x0000FFFF;
return descriptor;
}
void init_gdt() {
gdt[0] = create_descriptor(0, 0, 0);
gdt[1] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL0));
gdt[2] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL0));
gdt[3] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL3));
gdt[4] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL3));
gdtr.limit = 5 * sizeof(uint64_t) - 1;
gdtr.base = (uint32_t)&gdt;
load_gdt();
}

14
kernel/gdt_stubs.s Normal file
View File

@@ -0,0 +1,14 @@
.code32
.extern gdtr
.global load_gdt
load_gdt:
lgdt gdtr
ljmpl $0x08, $reload_segments
reload_segments:
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
ret

View File

@@ -54,5 +54,4 @@ void init_idt() {
}
load_idt();
enable_int();
}

View File

@@ -3,17 +3,17 @@
#include <stdint.h>
typedef struct {
typedef struct __attribute__((packed)){
uint16_t isr_low; // The lower 16 bits of the ISR's address
uint16_t kernel_cs; // The GDT segment selector the CPU will load into CS
uint8_t reserved; // Set to 0
uint8_t attributes;// Type and attributes flags
uint16_t isr_high; // The higher 16 bits of the ISR's address
} idt_entry __attribute__((packed));
} idt_entry;
typedef struct {
typedef struct __attribute__((packed)){
uint16_t limit;
uint32_t base;
} idt_ptr __attribute__((packed));
} idt_ptr;
#endif

View File

@@ -6,7 +6,7 @@
#include <stdint.h>
extern void init_idt();
extern idt_entry create_idt_entry(uint32_t addr, uint16_t segment, uint8_t attributes);
extern void init_gdt();
void kernel_main(void)
{
@@ -15,7 +15,11 @@ void kernel_main(void)
kout = &vga_print_stream;
kout->trunc();
kprint("RockOS booting...");
kprint("RockOS booting...\n");
init_gdt();
kprint("GDT set\n");
init_idt();
kprint("IDT set\n");
}

View File

@@ -6,6 +6,7 @@ OSNAME := rockos
C_SOURCES := $(shell find kernel -type f -name '*.c')
S_SOURCES := $(shell find kernel -type f -name '*.s')
# This correctly generates paths like obj/kernel/main.o
OBJECTS := $(patsubst %.c, obj/%.o, $(C_SOURCES)) $(patsubst %.s, obj/%.o, $(S_SOURCES))
CFLAGS := -ffreestanding -O2 -Wall -Wextra -Ikernel
@@ -13,6 +14,8 @@ LDFLAGS := -T kernel/linker.ld
.PHONY: all run clean
all: $(OSNAME).iso
$(OSNAME).bin: $(OBJECTS)
$(LD) $(LDFLAGS) -o $@ $(OBJECTS)
@@ -22,11 +25,12 @@ $(OSNAME).iso: $(OSNAME).bin grub.cfg
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o $(OSNAME).iso isodir
obj/%.o: %.c
# FIX: Pattern rules now explicitly expect the 'kernel' directory layout
obj/kernel/%.o: kernel/%.c
@mkdir -p $(dir $@)
$(CC) -c $< -o $@ $(CFLAGS)
obj/%.o: %.s
obj/kernel/%.o: kernel/%.s
@mkdir -p $(dir $@)
$(CC) -c $< -o $@ $(CFLAGS)