Moved processes to be in ring 3
This commit is contained in:
parent
a9ec673b24
commit
2ecc53ee91
@ -36,11 +36,9 @@ namespace xnoe {
|
||||
|
||||
if (exists)
|
||||
current->elem = xnoe::tuple<key, value>(k, v);
|
||||
else {
|
||||
printf("Appended.\n");
|
||||
else
|
||||
list->append(xnoe::tuple<key, value>(k, v));
|
||||
}
|
||||
}
|
||||
|
||||
xnoe::Maybe<value> get(key k) {
|
||||
xnoe::linkedlist<xnoe::tuple<key, value>>* list = &table[xnoe::hash<key>(k) % 4096];
|
||||
|
@ -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));
|
||||
}
|
@ -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;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
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) {
|
||||
@ -10,6 +10,9 @@ void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, u
|
||||
.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);
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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; i<count; i++) {
|
||||
uint32_t phys_addr = this->phys->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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user