From 00fb70c25b5d0406c137f32dbe3c0a910758e03c Mon Sep 17 00:00:00 2001 From: slinky55 Date: Fri, 12 Jun 2026 23:03:00 -0400 Subject: [PATCH] gdt idt stuff --- kernel/drivers/vga_stream_writer.c | 6 +++++ kernel/gdt.c | 41 ++++++++++++++++++++++-------- kernel/gdt_stubs.s | 14 ++++++++++ kernel/idt.c | 1 - kernel/idt.h | 8 +++--- kernel/kmain.c | 8 ++++-- makefile | 8 ++++-- 7 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 kernel/gdt_stubs.s diff --git a/kernel/drivers/vga_stream_writer.c b/kernel/drivers/vga_stream_writer.c index bd4c16a..3299185 100644 --- a/kernel/drivers/vga_stream_writer.c +++ b/kernel/drivers/vga_stream_writer.c @@ -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) { diff --git a/kernel/gdt.c b/kernel/gdt.c index d203b2c..0fffd64 100644 --- a/kernel/gdt.c +++ b/kernel/gdt.c @@ -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(); +} + diff --git a/kernel/gdt_stubs.s b/kernel/gdt_stubs.s new file mode 100644 index 0000000..760ebe7 --- /dev/null +++ b/kernel/gdt_stubs.s @@ -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 \ No newline at end of file diff --git a/kernel/idt.c b/kernel/idt.c index 5ff5be5..8dd4a26 100644 --- a/kernel/idt.c +++ b/kernel/idt.c @@ -54,5 +54,4 @@ void init_idt() { } load_idt(); - enable_int(); } \ No newline at end of file diff --git a/kernel/idt.h b/kernel/idt.h index 3869750..6f48e90 100644 --- a/kernel/idt.h +++ b/kernel/idt.h @@ -3,17 +3,17 @@ #include -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 \ No newline at end of file diff --git a/kernel/kmain.c b/kernel/kmain.c index 16de644..413c142 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -6,7 +6,7 @@ #include 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"); } diff --git a/makefile b/makefile index cef5bee..86e475c 100644 --- a/makefile +++ b/makefile @@ -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)