Moved processes to be in ring 3

This commit is contained in:
Xnoe 2021-12-02 19:36:52 +00:00
parent a9ec673b24
commit 2ecc53ee91
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
10 changed files with 91 additions and 75 deletions

View File

@ -36,10 +36,8 @@ namespace xnoe {
if (exists) if (exists)
current->elem = xnoe::tuple<key, value>(k, v); current->elem = xnoe::tuple<key, value>(k, v);
else { else
printf("Appended.\n");
list->append(xnoe::tuple<key, value>(k, v)); list->append(xnoe::tuple<key, value>(k, v));
}
} }
xnoe::Maybe<value> get(key k) { xnoe::Maybe<value> get(key k) {

View File

@ -1,47 +1,45 @@
#include "gdt.h" #include "gdt.h"
constexpr tss_struct::tss_struct() : tss_struct tss = (tss_struct) {
link(0), .link = 0,
_reserved0(0), ._reserved0 = 0,
esp0(0), .esp0 = 0xc1006000,
ss0(0), .ss0 = 0x10,
_reserved1(0), ._reserved1 = 0,
esp1(0), .esp1 = 0,
ss1(0), .ss1 = 0,
_reserved2(0), ._reserved2 = 0,
esp2(0), .esp2 = 0,
ss2(0), .ss2 = 0,
_reserved3(0), ._reserved3 = 0,
cr3(0), .cr3 = 0,
eip(0), .eip = 0,
eflags(0), .eflags = 0,
eax(0), .eax = 0,
ebx(0), .ebx = 0,
ecx(0), .ecx = 0,
edx(0), .edx = 0,
esp(0), .esp = 0,
ebp(0), .ebp = 0,
esi(0), .esi = 0,
edi(0), .edi = 0,
es(0), .es = 0,
_reserved4(0), ._reserved4 = 0,
cs(0), .cs = 0,
_reserved5(0), ._reserved5 = 0,
ss(0), .ss = 0,
_reserved6(0), ._reserved6 = 0,
ds(0), .ds = 0,
_reserved7(0), ._reserved7 = 0,
fs(0), .fs = 0,
_reserved8(0), ._reserved8 = 0,
gs(0), .gs = 0,
_reserved9(0), ._reserved9 = 0,
ldtr(0), .ldtr = 0,
_reserved10(0), ._reserved10 = 0,
_reserved11(0), ._reserved11 = 0,
iopb(0) .iopb = 104
{} };
tss_struct tss = tss_struct();
constexpr gdt_entry::gdt_entry(uint32_t limit, uint32_t base, bool rw, bool exec, bool system, uint8_t ring) : constexpr gdt_entry::gdt_entry(uint32_t limit, uint32_t base, bool rw, bool exec, bool system, uint8_t ring) :
limit_lo(limit & 0xffff), limit_lo(limit & 0xffff),
@ -81,9 +79,13 @@ constexpr gdt_entry::gdt_entry() :
gdt_entry gdt[] = { gdt_entry gdt[] = {
gdt_entry(), // Null Segment gdt_entry(), // Null Segment
gdt_entry(0xfffff, 0, 1, 1, 1, 0), // Code Segment gdt_entry(0xfffff, 0, 1, 1, 1, 0), // Kernel Code Segment
gdt_entry(0xfffff, 0, 1, 0, 1, 0), // Data Segment gdt_entry(0xfffff, 0, 1, 0, 1, 0), // Kernel Data Segment
gdt_entry(sizeof(tss), &tss, 0, 1, 0, 0) // Task State Segment 1
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){ gdt_descr descr = (gdt_descr){
@ -92,9 +94,12 @@ gdt_descr descr = (gdt_descr){
}; };
void init_gdt() { 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;" asm volatile("lgdt %0;"
"mov $0x10, %%eax;" "mov $0x10, %%eax;"
"mov %%eax, %%ss;" "mov %%eax, %%ss;"
"mov $0x10, %%eax;" "mov %%eax, %%ds;"
"mov %%eax, %%ds" : : "m" (descr)); "mov $0x28, %%ax;"
"ltr %%ax" : : "m" (descr));
} }

View File

@ -42,9 +42,10 @@ struct __attribute__((packed)) tss_struct {
uint16_t _reserved10; uint16_t _reserved10;
uint16_t _reserved11; uint16_t _reserved11;
uint16_t iopb; uint16_t iopb;
constexpr tss_struct();
}; };
extern tss_struct tss;
struct __attribute__((packed)) gdt_entry { struct __attribute__((packed)) gdt_entry {
uint32_t limit_lo : 16; uint32_t limit_lo : 16;
uint32_t base_lo : 16; uint32_t base_lo : 16;

View File

@ -2,14 +2,17 @@
GateEntry idt[256]; 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; uint32_t handler_addr = (uint32_t)handler;
uint16_t* handler_halves = (uint16_t*)&handler_addr; uint16_t* handler_halves = (uint16_t*)&handler_addr;
idt[interrupt_number] = (GateEntry){ idt[interrupt_number] = (GateEntry) {
.offset_low = handler_halves[0], .offset_low = handler_halves[0],
.selector = code_segment, .selector = code_segment,
.zero = 0, .zero = 0,
.type = type, .type = type,
.zero1 = 0,
.privilege = privilege,
.present = 1,
.offset_high = handler_halves[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) { __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"); while (1) asm("hlt");
} }
@ -168,10 +171,10 @@ void init_idt() {
for (int i=0; i<256; i++) for (int i=0; i<256; i++)
set_entry(i, 0x08, &ignore_interrupt, 0x8E); set_entry(i, 0x08, &ignore_interrupt, 0x8E);
set_entry(0x20, 0x08, &context_switch, 0x8E); set_entry(0x20, 0x08, &context_switch, 0xE);
set_entry(0xD, 0x08, &gpf, 0x8E); set_entry(0xD, 0x08, &gpf, 0xE);
set_entry(0xE, 0x08, &page_fault, 0x8E); set_entry(0xE, 0x08, &page_fault, 0xE);
set_entry(0x7f, 0x08, &syscall, 0x8E); set_entry(0x7f, 0x08, &syscall, 0xE, 3);
outb(0x20, 0x11); outb(0x20, 0x11);
outb(0xA0, 0x11); outb(0xA0, 0x11);

View File

@ -13,7 +13,7 @@ struct interrupt_frame {
uint32_t eflags; uint32_t eflags;
}; };
extern void load_idt(); 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 init_idt();
void enable_idt(); void enable_idt();
@ -21,7 +21,10 @@ struct __attribute__((packed)) GateEntry{
uint16_t offset_low; uint16_t offset_low;
uint16_t selector; uint16_t selector;
uint8_t zero; 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; uint16_t offset_high;
} ; } ;

View File

@ -47,8 +47,6 @@ int main() {
Global::currentProc = &kernel; Global::currentProc = &kernel;
Process* p1 = kernel.createProcess("WORLD BIN"); Process* p1 = kernel.createProcess("WORLD BIN");
Process* p2 = kernel.createProcess("HELLO BIN");
kernel.destroyProcess(p2);
init_keyboard(); init_keyboard();

View File

@ -104,11 +104,11 @@ PageTable::~PageTable() {
delete page_table; 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){ page_table[index] = (PTE){
.present = 1, .present = 1,
.read_write = 1, .read_write = 1,
.privilege = 0, .privilege = privilege,
.write_through_cache = 0, .write_through_cache = 0,
.disable_cache = 0, .disable_cache = 0,
.accessed = 0, .accessed = 0,
@ -168,7 +168,7 @@ PageDirectory::~PageDirectory() {
delete page_directory; 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; split_addr* split = (split_addr*)&virt;
if (!page_tables[split->pd_index].virt_addr) 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){ page_directory[split->pd_index] = (PDE){
.present = 1, .present = 1,
.read_write = 1, .read_write = 1,
.privilege = 0, .privilege = privilege,
.write_through_cache = 0, .write_through_cache = 0,
.disable_cache = 0, .disable_cache = 0,
.accessed = 0, .accessed = 0,
@ -188,7 +188,7 @@ void PageDirectory::map(uint32_t phys, uint32_t virt) {
.address = page_tables[split->pd_index].phys_addr .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"); 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; 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->PD = page_directory;
this->virt = virt; this->virt = virt;
this->virt_alloc_base = virt_alloc_base; this->virt_alloc_base = virt_alloc_base;
this->privilege = privilege;
} }
Allocator::~Allocator() { Allocator::~Allocator() {
@ -238,7 +239,7 @@ void* Allocator::allocate(uint32_t size) {
for (int i=0; i<count; i++) { for (int i=0; i<count; i++) {
uint32_t phys_addr = this->phys->find_next_available_from(0); uint32_t phys_addr = this->phys->find_next_available_from(0);
this->phys->mark_unavailable(phys_addr); 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; return virt_addr;

View File

@ -47,7 +47,7 @@ struct PageTable {
~PageTable(); // Delete page_table ~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); void unmap_table(uint32_t index);
uint32_t get_physical_address(uint32_t index); uint32_t get_physical_address(uint32_t index);
@ -68,7 +68,7 @@ public:
~PageDirectory(); // Delete the page tables and page_directory ~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); void unmap(uint32_t virt);
uint32_t virtual_to_physical(uint32_t virt); uint32_t virtual_to_physical(uint32_t virt);
@ -82,11 +82,12 @@ protected:
PageMap* virt; PageMap* virt;
uint32_t virt_alloc_base; uint32_t virt_alloc_base;
uint8_t privilege;
public: public:
PageDirectory* PD; PageDirectory* PD;
Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); 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 ~Allocator(); // Delete virt and PD

View File

@ -23,7 +23,7 @@ Process::Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageM
} }
Process::Process(uint32_t PID) Process::Process(uint32_t PID)
: Allocator(new PageDirectory, new PageMap, 0) { : Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) {
this->PID = PID; this->PID = PID;
this->page_remaining = 0; this->page_remaining = 0;
this->last_page_pointer = 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) 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->PID = PID;
this->page_remaining = 0; this->page_remaining = 0;
this->last_page_pointer = 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 // We also need to initialise ESP and the stack
uint32_t* stack32 = ((uint32_t)this->stack + 0x8000); uint32_t* stack32 = ((uint32_t)this->stack + 0x8000);
stack32--; stack32--;
*stack32 = 0x23;
stack32--;
*stack32 = ((uint32_t)this->stack + 0x8000);
stack32--;
*stack32 = 0x200; // EFLAGS *stack32 = 0x200; // EFLAGS
stack32--; stack32--;
*stack32 = 8; // CS 0x08 *stack32 = 27; // CS 0x08
stack32--; stack32--;
*stack32 = (uint32_t)program_data; *stack32 = (uint32_t)program_data;

View File

@ -80,6 +80,8 @@ void readline(int max, char* buffer) {
} }
int main() { int main() {
print ("Hello from Ring 3!\n");
char buffer[128]; char buffer[128];
while (1) { while (1) {
for (int i=0; i<128; i++) for (int i=0; i<128; i++)