enable paging
This commit is contained in:
parent
3fd90c7483
commit
faa6ce0757
|
@ -16,4 +16,57 @@ typedef struct {
|
|||
uint64_t ticks;
|
||||
} kernel_ctx_t;
|
||||
|
||||
#define GDT_NULL 0
|
||||
#define GDT_KERNEL_CODE 1
|
||||
#define GDT_KERNEL_DATA 2
|
||||
#define GDT_USER_CODE 3
|
||||
#define GDT_USER_DATA 4
|
||||
|
||||
#define RING0 0
|
||||
#define RING3 3
|
||||
|
||||
#define GDT_SEGMENT_SELECTOR(i, p) ((i << 3) | p)
|
||||
|
||||
struct gdt_entry {
|
||||
uint16_t limit_low;
|
||||
uint16_t base_low;
|
||||
uint8_t base_middle;
|
||||
uint8_t access;
|
||||
uint8_t granularity;
|
||||
uint8_t base_high;
|
||||
} __attribute__((packed));
|
||||
typedef struct gdt_entry gdt_t;
|
||||
|
||||
struct tss_entry {
|
||||
uint32_t prev_tss; // The previous TSS - with hardware task switching this is used
|
||||
uint32_t esp0; // The stack pointer to load when we change to kernel mode
|
||||
uint32_t ss0; // The stack segment to load when we change to kernel mode
|
||||
uint32_t esp1; // Unused...
|
||||
uint32_t ss1;
|
||||
uint32_t esp2;
|
||||
uint32_t ss2;
|
||||
uint32_t cr3;
|
||||
uint32_t eip;
|
||||
uint32_t eflags;
|
||||
uint32_t eax;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t ebx;
|
||||
uint32_t esp;
|
||||
uint32_t ebp;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint32_t es; // The value to load into ES when we change to kernel mode
|
||||
uint32_t cs; // The value to load into CS when we change to kernel mode
|
||||
uint32_t ss; // The value to load into SS when we change to kernel mode
|
||||
uint32_t ds; // The value to load into DS when we change to kernel mode
|
||||
uint32_t fs; // The value to load into FS when we change to kernel mode
|
||||
uint32_t gs; // The value to load into GS when we change to kernel mode
|
||||
uint32_t ldt; // Unused...
|
||||
uint16_t trap;
|
||||
uint16_t iomap_base;
|
||||
} __attribute__((packed));
|
||||
typedef struct tss_entry tss_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -75,6 +75,23 @@ jmp_user_mode:
|
|||
|
||||
iret
|
||||
|
||||
global flush_tss
|
||||
flush_tss:
|
||||
ltr [esp+4]
|
||||
ret
|
||||
|
||||
global enable_paging
|
||||
enable_paging:
|
||||
push eax
|
||||
mov eax, [esp+4]
|
||||
mov cr3, eax
|
||||
|
||||
mov eax, cr0
|
||||
or eax, 0x80000000
|
||||
mov cr0, eax
|
||||
pop eax
|
||||
ret
|
||||
|
||||
extern exception_handler
|
||||
%macro isr_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
|
@ -174,6 +191,8 @@ gdt_user_data:
|
|||
db 0b11110010
|
||||
db 0b11001111
|
||||
db 0x00
|
||||
tss:
|
||||
dq 0
|
||||
gdt_end:
|
||||
|
||||
gdtp:
|
||||
|
|
|
@ -5,18 +5,19 @@
|
|||
#include <kernel/idt.h>
|
||||
#include <kernel/pic.h>
|
||||
#include <kernel/pit.h>
|
||||
#include <stdint.h>
|
||||
|
||||
kernel_ctx_t ctx = {0};
|
||||
struct idt_entry idt[256] = {0};
|
||||
struct idtr idtr = {0};
|
||||
tss_t tss = {0};
|
||||
|
||||
extern uint32_t isr_stub_table[32];
|
||||
extern void pit_isr(void);
|
||||
extern void jmp_user_mode(uint32_t esp, uint32_t eip);
|
||||
|
||||
void test_entry(void) {
|
||||
for (;;) {}
|
||||
}
|
||||
extern void flush_tss(uint32_t segment_selector);
|
||||
extern gdt_t gdt[6];
|
||||
extern void enable_paging(uint32_t *page_directory);
|
||||
|
||||
void exception_handler(int_stack_frame_t r) {
|
||||
LOG("Exception 0x%X (0x%X) has occurred\nEAX: 0x%08X\nECX: 0x%08X\nEDX: 0x%08X\nEBX: 0x%08X\nESI: 0x%08X\nEDI: 0x%08X\nEBP: 0x%08X\nESP: 0x%08X\n",
|
||||
|
@ -31,6 +32,15 @@ void sleep(int delay) {
|
|||
cpu_relax;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32_t eip;
|
||||
uint32_t esp;
|
||||
uint32_t cr3;
|
||||
} task_t;
|
||||
|
||||
__attribute__((aligned(4096))) uint32_t page_dir[1024];
|
||||
__attribute__((aligned(4096))) uint32_t page_tab[1024];
|
||||
|
||||
void kernel(multiboot_info_t *info) {
|
||||
if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules
|
||||
if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map
|
||||
|
@ -47,21 +57,59 @@ void kernel(multiboot_info_t *info) {
|
|||
for (int i = 0; i < 32; i++) {
|
||||
idt_encode_entry(idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(1, 0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
|
||||
}
|
||||
idt_encode_entry(idt, 32, (uint32_t)pit_isr, GDT_SEGMENT_SELECTOR(1, 0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
|
||||
idt_encode_entry(idt, 32, (uint32_t)pit_isr, GDT_SEGMENT_SELECTOR(1, 0), INT_GATE_32 | INT_RING0 | INT_PRESENT);
|
||||
|
||||
idtr.size = (sizeof(struct idt_entry) * 256) - 1;
|
||||
idtr.base = (uint32_t) idt;
|
||||
|
||||
asm volatile ("lidt %0" :: "m"(idtr));
|
||||
pic_remap(PIC_1_START, PIC_2_START);
|
||||
//asm volatile ("sti" ::);
|
||||
/*
|
||||
asm volatile ("sti" ::);
|
||||
|
||||
ctx.ticks = 0;
|
||||
//pit_init();
|
||||
pit_init();
|
||||
|
||||
uint32_t base = (uint32_t)&tss;
|
||||
uint32_t limit = base + sizeof(tss_t);
|
||||
gdt[5].base_low = base & 0xFFFF;
|
||||
gdt[5].base_middle = (base >> 16) & 0xFF;
|
||||
gdt[5].base_high = (base >> 24) & 0xFF;
|
||||
gdt[5].limit_low = limit & 0xFFFF;
|
||||
gdt[5].granularity = (limit >> 16) & 0x0F;
|
||||
gdt[5].granularity |= 0x40;
|
||||
gdt[5].access = 0x89;
|
||||
tss.ss0 = GDT_SEGMENT_SELECTOR(2, RING0);
|
||||
tss.esp0 = 0;
|
||||
tss.cs = GDT_SEGMENT_SELECTOR(3, RING3);
|
||||
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(4, RING3);
|
||||
flush_tss(GDT_SEGMENT_SELECTOR(5, RING3));
|
||||
*/
|
||||
|
||||
#define PAGE_PRESENT (1<<0)
|
||||
#define PAGE_RW (1<<1)
|
||||
#define PAGE_USER (1<<2)
|
||||
|
||||
#define PAGE_DIR_INDEX(x) (((x) >> 22) & 0x3FF)
|
||||
#define PAGE_TAB_INDEX(x) (((x) >> 12) & 0x3FF)
|
||||
#define PAGE_OFFSET(x) ((x) & 0xFFF)
|
||||
|
||||
LOG("Page directory: %08X -- Page table: %08X\n", page_dir, page_tab);
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
page_tab[i] = (i * 0x1000) | PAGE_PRESENT | PAGE_RW | PAGE_USER;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
page_dir[i] = ((uint32_t)page_tab) | PAGE_PRESENT | PAGE_RW | PAGE_USER;
|
||||
}
|
||||
|
||||
enable_paging(page_dir);
|
||||
|
||||
uint32_t stack = (uint32_t)mmap_find_first_free_block();
|
||||
multi_mod_t *init = (multi_mod_t *)info->moduleaddress;
|
||||
LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X", init->mod_start, stack+0x1000);
|
||||
LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", init->mod_start, stack+0x1000);
|
||||
|
||||
jmp_user_mode(stack+0x1000, init->mod_start);
|
||||
|
||||
halt:
|
||||
|
|
Loading…
Reference in New Issue
Block a user