gdt idt stuff
This commit is contained in:
@@ -57,6 +57,12 @@ void vga_initialize()
|
|||||||
|
|
||||||
void vga_putchar(char c)
|
void vga_putchar(char c)
|
||||||
{
|
{
|
||||||
|
if (c == '\n') {
|
||||||
|
terminal_row++;
|
||||||
|
terminal_column = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const size_t index = terminal_row * VGA_WIDTH + terminal_column;
|
const size_t index = terminal_row * VGA_WIDTH + terminal_column;
|
||||||
terminal_buffer[index] = vga_entry(c, terminal_color);
|
terminal_buffer[index] = vga_entry(c, terminal_color);
|
||||||
if (++terminal_column == VGA_WIDTH) {
|
if (++terminal_column == VGA_WIDTH) {
|
||||||
|
|||||||
41
kernel/gdt.c
41
kernel/gdt.c
@@ -40,23 +40,44 @@
|
|||||||
#define GDT_DATA_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
|
#define GDT_DATA_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
|
||||||
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
|
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
|
||||||
SEG_PRIV(3) | SEG_DATA_RDWR
|
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 create_descriptor(uint32_t base, uint32_t limit, uint16_t flag)
|
||||||
{
|
{
|
||||||
uint64_t descriptor;
|
uint64_t descriptor;
|
||||||
|
|
||||||
// Create the high 32 bit segment
|
descriptor = limit & 0x000F0000;
|
||||||
descriptor = limit & 0x000F0000; // set limit bits 19:16
|
descriptor |= (flag << 8) & 0x00F0FF00;
|
||||||
descriptor |= (flag << 8) & 0x00F0FF00; // set type, p, dpl, s, g, d/b, l and avl fields
|
descriptor |= (base >> 16) & 0x000000FF;
|
||||||
descriptor |= (base >> 16) & 0x000000FF; // set base bits 23:16
|
descriptor |= base & 0xFF000000;
|
||||||
descriptor |= base & 0xFF000000; // set base bits 31:24
|
|
||||||
|
|
||||||
// Shift by 32 to allow for low part of segment
|
|
||||||
descriptor <<= 32;
|
descriptor <<= 32;
|
||||||
|
|
||||||
// Create the low 32 bit segment
|
descriptor |= base << 16;
|
||||||
descriptor |= base << 16; // set base bits 15:0
|
descriptor |= limit & 0x0000FFFF;
|
||||||
descriptor |= limit & 0x0000FFFF; // set limit bits 15:0
|
|
||||||
|
|
||||||
return descriptor;
|
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
14
kernel/gdt_stubs.s
Normal 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
|
||||||
@@ -54,5 +54,4 @@ void init_idt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
load_idt();
|
load_idt();
|
||||||
enable_int();
|
|
||||||
}
|
}
|
||||||
@@ -3,17 +3,17 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct __attribute__((packed)){
|
||||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
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
|
uint16_t kernel_cs; // The GDT segment selector the CPU will load into CS
|
||||||
uint8_t reserved; // Set to 0
|
uint8_t reserved; // Set to 0
|
||||||
uint8_t attributes;// Type and attributes flags
|
uint8_t attributes;// Type and attributes flags
|
||||||
uint16_t isr_high; // The higher 16 bits of the ISR's address
|
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;
|
uint16_t limit;
|
||||||
uint32_t base;
|
uint32_t base;
|
||||||
} idt_ptr __attribute__((packed));
|
} idt_ptr;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern void init_idt();
|
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)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
@@ -15,7 +15,11 @@ void kernel_main(void)
|
|||||||
kout = &vga_print_stream;
|
kout = &vga_print_stream;
|
||||||
kout->trunc();
|
kout->trunc();
|
||||||
|
|
||||||
kprint("RockOS booting...");
|
kprint("RockOS booting...\n");
|
||||||
|
|
||||||
|
init_gdt();
|
||||||
|
kprint("GDT set\n");
|
||||||
|
|
||||||
init_idt();
|
init_idt();
|
||||||
|
kprint("IDT set\n");
|
||||||
}
|
}
|
||||||
|
|||||||
8
makefile
8
makefile
@@ -6,6 +6,7 @@ OSNAME := rockos
|
|||||||
C_SOURCES := $(shell find kernel -type f -name '*.c')
|
C_SOURCES := $(shell find kernel -type f -name '*.c')
|
||||||
S_SOURCES := $(shell find kernel -type f -name '*.s')
|
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))
|
OBJECTS := $(patsubst %.c, obj/%.o, $(C_SOURCES)) $(patsubst %.s, obj/%.o, $(S_SOURCES))
|
||||||
|
|
||||||
CFLAGS := -ffreestanding -O2 -Wall -Wextra -Ikernel
|
CFLAGS := -ffreestanding -O2 -Wall -Wextra -Ikernel
|
||||||
@@ -13,6 +14,8 @@ LDFLAGS := -T kernel/linker.ld
|
|||||||
|
|
||||||
.PHONY: all run clean
|
.PHONY: all run clean
|
||||||
|
|
||||||
|
all: $(OSNAME).iso
|
||||||
|
|
||||||
$(OSNAME).bin: $(OBJECTS)
|
$(OSNAME).bin: $(OBJECTS)
|
||||||
$(LD) $(LDFLAGS) -o $@ $(OBJECTS)
|
$(LD) $(LDFLAGS) -o $@ $(OBJECTS)
|
||||||
|
|
||||||
@@ -22,11 +25,12 @@ $(OSNAME).iso: $(OSNAME).bin grub.cfg
|
|||||||
cp grub.cfg isodir/boot/grub/grub.cfg
|
cp grub.cfg isodir/boot/grub/grub.cfg
|
||||||
grub-mkrescue -o $(OSNAME).iso isodir
|
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 $@)
|
@mkdir -p $(dir $@)
|
||||||
$(CC) -c $< -o $@ $(CFLAGS)
|
$(CC) -c $< -o $@ $(CFLAGS)
|
||||||
|
|
||||||
obj/%.o: %.s
|
obj/kernel/%.o: kernel/%.s
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(CC) -c $< -o $@ $(CFLAGS)
|
$(CC) -c $< -o $@ $(CFLAGS)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user