From 2ecc53ee91199178429da7e862765026ee6ca3f2 Mon Sep 17 00:00:00 2001 From: Xnoe Date: Thu, 2 Dec 2021 19:36:52 +0000 Subject: [PATCH] Moved processes to be in ring 3 --- src/kernel/datatypes/hashtable.h | 4 +- src/kernel/gdt.cpp | 99 +++++++++++++++++--------------- src/kernel/gdt.h | 3 +- src/kernel/idt.cpp | 17 +++--- src/kernel/idt.h | 7 ++- src/kernel/kmain.cpp | 2 - src/kernel/memory.cpp | 15 ++--- src/kernel/memory.h | 7 ++- src/kernel/process.cpp | 10 +++- src/program/world.c | 2 + 10 files changed, 91 insertions(+), 75 deletions(-) diff --git a/src/kernel/datatypes/hashtable.h b/src/kernel/datatypes/hashtable.h index 0376613..c6438a8 100644 --- a/src/kernel/datatypes/hashtable.h +++ b/src/kernel/datatypes/hashtable.h @@ -36,10 +36,8 @@ namespace xnoe { if (exists) current->elem = xnoe::tuple(k, v); - else { - printf("Appended.\n"); + else list->append(xnoe::tuple(k, v)); - } } xnoe::Maybe get(key k) { diff --git a/src/kernel/gdt.cpp b/src/kernel/gdt.cpp index 0c062fa..c387c3c 100644 --- a/src/kernel/gdt.cpp +++ b/src/kernel/gdt.cpp @@ -1,47 +1,45 @@ #include "gdt.h" -constexpr tss_struct::tss_struct() : - link(0), - _reserved0(0), - esp0(0), - ss0(0), - _reserved1(0), - esp1(0), - ss1(0), - _reserved2(0), - esp2(0), - ss2(0), - _reserved3(0), - cr3(0), - eip(0), - eflags(0), - eax(0), - ebx(0), - ecx(0), - edx(0), - esp(0), - ebp(0), - esi(0), - edi(0), - es(0), - _reserved4(0), - cs(0), - _reserved5(0), - ss(0), - _reserved6(0), - ds(0), - _reserved7(0), - fs(0), - _reserved8(0), - gs(0), - _reserved9(0), - ldtr(0), - _reserved10(0), - _reserved11(0), - iopb(0) -{} - -tss_struct tss = tss_struct(); +tss_struct tss = (tss_struct) { + .link = 0, + ._reserved0 = 0, + .esp0 = 0xc1006000, + .ss0 = 0x10, + ._reserved1 = 0, + .esp1 = 0, + .ss1 = 0, + ._reserved2 = 0, + .esp2 = 0, + .ss2 = 0, + ._reserved3 = 0, + .cr3 = 0, + .eip = 0, + .eflags = 0, + .eax = 0, + .ebx = 0, + .ecx = 0, + .edx = 0, + .esp = 0, + .ebp = 0, + .esi = 0, + .edi = 0, + .es = 0, + ._reserved4 = 0, + .cs = 0, + ._reserved5 = 0, + .ss = 0, + ._reserved6 = 0, + .ds = 0, + ._reserved7 = 0, + .fs = 0, + ._reserved8 = 0, + .gs = 0, + ._reserved9 = 0, + .ldtr = 0, + ._reserved10 = 0, + ._reserved11 = 0, + .iopb = 104 +}; constexpr gdt_entry::gdt_entry(uint32_t limit, uint32_t base, bool rw, bool exec, bool system, uint8_t ring) : limit_lo(limit & 0xffff), @@ -81,9 +79,13 @@ constexpr gdt_entry::gdt_entry() : gdt_entry gdt[] = { gdt_entry(), // Null Segment - gdt_entry(0xfffff, 0, 1, 1, 1, 0), // Code Segment - gdt_entry(0xfffff, 0, 1, 0, 1, 0), // Data Segment - gdt_entry(sizeof(tss), &tss, 0, 1, 0, 0) // Task State Segment 1 + gdt_entry(0xfffff, 0, 1, 1, 1, 0), // Kernel Code Segment + gdt_entry(0xfffff, 0, 1, 0, 1, 0), // Kernel Data Segment + + gdt_entry(0xfffff, 0, 1, 1, 1, 3), // User Code Segment + gdt_entry(0xfffff, 0, 1, 0, 1, 3), // User Data Segment + + gdt_entry() // Empty Task State Segment }; gdt_descr descr = (gdt_descr){ @@ -92,9 +94,12 @@ gdt_descr descr = (gdt_descr){ }; void init_gdt() { + gdt[5] = gdt_entry(sizeof(tss), &tss, 0, 1, 0, 0); // Initialise the TSS. + gdt[5].accessed = 1; asm volatile("lgdt %0;" "mov $0x10, %%eax;" "mov %%eax, %%ss;" - "mov $0x10, %%eax;" - "mov %%eax, %%ds" : : "m" (descr)); + "mov %%eax, %%ds;" + "mov $0x28, %%ax;" + "ltr %%ax" : : "m" (descr)); } \ No newline at end of file diff --git a/src/kernel/gdt.h b/src/kernel/gdt.h index 2309896..b1b4a3c 100644 --- a/src/kernel/gdt.h +++ b/src/kernel/gdt.h @@ -42,9 +42,10 @@ struct __attribute__((packed)) tss_struct { uint16_t _reserved10; uint16_t _reserved11; uint16_t iopb; - constexpr tss_struct(); }; +extern tss_struct tss; + struct __attribute__((packed)) gdt_entry { uint32_t limit_lo : 16; uint32_t base_lo : 16; diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 553fc1a..8ce6d08 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -2,14 +2,17 @@ GateEntry idt[256]; -void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type) { +void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type, uint8_t privilege) { uint32_t handler_addr = (uint32_t)handler; uint16_t* handler_halves = (uint16_t*)&handler_addr; - idt[interrupt_number] = (GateEntry){ + idt[interrupt_number] = (GateEntry) { .offset_low = handler_halves[0], .selector = code_segment, .zero = 0, .type = type, + .zero1 = 0, + .privilege = privilege, + .present = 1, .offset_high = handler_halves[1] }; } @@ -31,7 +34,7 @@ __attribute__((interrupt)) void ignore_interrupt(interrupt_frame* frame) { } __attribute__((interrupt)) void gpf(interrupt_frame* frame, uint32_t err_code) { - printf("General Protection Fault %d\n", err_code); + printf("General Protection Fault %x\n", err_code); while (1) asm("hlt"); } @@ -168,10 +171,10 @@ void init_idt() { for (int i=0; i<256; i++) set_entry(i, 0x08, &ignore_interrupt, 0x8E); - set_entry(0x20, 0x08, &context_switch, 0x8E); - set_entry(0xD, 0x08, &gpf, 0x8E); - set_entry(0xE, 0x08, &page_fault, 0x8E); - set_entry(0x7f, 0x08, &syscall, 0x8E); + set_entry(0x20, 0x08, &context_switch, 0xE); + set_entry(0xD, 0x08, &gpf, 0xE); + set_entry(0xE, 0x08, &page_fault, 0xE); + set_entry(0x7f, 0x08, &syscall, 0xE, 3); outb(0x20, 0x11); outb(0xA0, 0x11); diff --git a/src/kernel/idt.h b/src/kernel/idt.h index 4df1f3d..11a6004 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -13,7 +13,7 @@ struct interrupt_frame { uint32_t eflags; }; extern void load_idt(); -void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type); +void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type, uint8_t privilege = 0); void init_idt(); void enable_idt(); @@ -21,7 +21,10 @@ struct __attribute__((packed)) GateEntry{ uint16_t offset_low; uint16_t selector; uint8_t zero; - uint8_t type; + uint8_t type : 4; + uint8_t zero1 : 1; + uint8_t privilege : 2; + uint8_t present : 1; uint16_t offset_high; } ; diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index afe1354..23f29f2 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -47,8 +47,6 @@ int main() { Global::currentProc = &kernel; Process* p1 = kernel.createProcess("WORLD BIN"); - Process* p2 = kernel.createProcess("HELLO BIN"); - kernel.destroyProcess(p2); init_keyboard(); diff --git a/src/kernel/memory.cpp b/src/kernel/memory.cpp index 77dc9b1..f5e9d4c 100644 --- a/src/kernel/memory.cpp +++ b/src/kernel/memory.cpp @@ -104,11 +104,11 @@ PageTable::~PageTable() { delete page_table; } -void PageTable::map_table(uint32_t index, uint32_t addr) { +void PageTable::map_table(uint32_t index, uint32_t addr, uint8_t privilege) { page_table[index] = (PTE){ .present = 1, .read_write = 1, - .privilege = 0, + .privilege = privilege, .write_through_cache = 0, .disable_cache = 0, .accessed = 0, @@ -168,7 +168,7 @@ PageDirectory::~PageDirectory() { delete page_directory; } -void PageDirectory::map(uint32_t phys, uint32_t virt) { +void PageDirectory::map(uint32_t phys, uint32_t virt, uint8_t privilege) { split_addr* split = (split_addr*)&virt; if (!page_tables[split->pd_index].virt_addr) @@ -177,7 +177,7 @@ void PageDirectory::map(uint32_t phys, uint32_t virt) { page_directory[split->pd_index] = (PDE){ .present = 1, .read_write = 1, - .privilege = 0, + .privilege = privilege, .write_through_cache = 0, .disable_cache = 0, .accessed = 0, @@ -188,7 +188,7 @@ void PageDirectory::map(uint32_t phys, uint32_t virt) { .address = page_tables[split->pd_index].phys_addr }; - page_tables[split->pd_index].map_table(split->pt_index, phys >> 12); + page_tables[split->pd_index].map_table(split->pt_index, phys >> 12, privilege); asm volatile ("invlpg (%0)" : : "r" (virt) : "memory"); } @@ -217,11 +217,12 @@ Allocator::Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt this->virt_alloc_base = virt_alloc_base; } -Allocator::Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base) { +Allocator::Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base, uint8_t privilege) { this->PD = page_directory; this->virt = virt; this->virt_alloc_base = virt_alloc_base; + this->privilege = privilege; } Allocator::~Allocator() { @@ -238,7 +239,7 @@ void* Allocator::allocate(uint32_t size) { for (int i=0; iphys->find_next_available_from(0); this->phys->mark_unavailable(phys_addr); - this->PD->map(phys_addr, virt_addr + 4096 * i); + this->PD->map(phys_addr, virt_addr + 4096 * i, this->privilege); } return virt_addr; diff --git a/src/kernel/memory.h b/src/kernel/memory.h index b92cbee..c008c4a 100644 --- a/src/kernel/memory.h +++ b/src/kernel/memory.h @@ -47,7 +47,7 @@ struct PageTable { ~PageTable(); // Delete page_table - void map_table(uint32_t index, uint32_t addr); + void map_table(uint32_t index, uint32_t addr, uint8_t privilege=0); void unmap_table(uint32_t index); uint32_t get_physical_address(uint32_t index); @@ -68,7 +68,7 @@ public: ~PageDirectory(); // Delete the page tables and page_directory - void map(uint32_t phys, uint32_t virt); + void map(uint32_t phys, uint32_t virt, uint8_t privilege=0); void unmap(uint32_t virt); uint32_t virtual_to_physical(uint32_t virt); @@ -82,11 +82,12 @@ protected: PageMap* virt; uint32_t virt_alloc_base; + uint8_t privilege; public: PageDirectory* PD; Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); - Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base); + Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base, uint8_t privilege); ~Allocator(); // Delete virt and PD diff --git a/src/kernel/process.cpp b/src/kernel/process.cpp index 04d7e3a..615da5f 100644 --- a/src/kernel/process.cpp +++ b/src/kernel/process.cpp @@ -23,7 +23,7 @@ Process::Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageM } Process::Process(uint32_t PID) -: Allocator(new PageDirectory, new PageMap, 0) { +: Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) { this->PID = PID; this->page_remaining = 0; this->last_page_pointer = 0; @@ -31,7 +31,7 @@ Process::Process(uint32_t PID) } Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename) -: Allocator(new PageDirectory, new PageMap, 0) { +: Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) { this->PID = PID; this->page_remaining = 0; this->last_page_pointer = 0; @@ -50,9 +50,13 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha // We also need to initialise ESP and the stack uint32_t* stack32 = ((uint32_t)this->stack + 0x8000); stack32--; + *stack32 = 0x23; + stack32--; + *stack32 = ((uint32_t)this->stack + 0x8000); + stack32--; *stack32 = 0x200; // EFLAGS stack32--; - *stack32 = 8; // CS 0x08 + *stack32 = 27; // CS 0x08 stack32--; *stack32 = (uint32_t)program_data; diff --git a/src/program/world.c b/src/program/world.c index f13cc48..01a0f8f 100644 --- a/src/program/world.c +++ b/src/program/world.c @@ -80,6 +80,8 @@ void readline(int max, char* buffer) { } int main() { + print ("Hello from Ring 3!\n"); + char buffer[128]; while (1) { for (int i=0; i<128; i++)