Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "user/pishell"]
path = user/pishell
url = git@github.com:ryuukumar/pishell.git
[submodule "lib/newlib-cygwin"]
path = lib/newlib-cygwin
url = https://sourceware.org/git/newlib-cygwin.git
Expand Down
2 changes: 2 additions & 0 deletions kernel/include/kernel/idt.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ typedef void (*irq_handler_t) (registers_t*);
void init_idt (void);
void idt_register_handler (int vector, irq_handler_t handler);
void idt_set_flags (int vector, uint8_t gate_type, uint8_t dpl, uint8_t ist);

void log_registers_to_serial (registers_t* registers);
1 change: 1 addition & 0 deletions kernel/include/kernel/memmgt.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ void* get_vaddr_from_phys_addr (uint64_t phys_address);
void* vaddr_t_to_ptr (vaddr_t* virtual_addr);
bool is_vaddr_t_user (vaddr_t* addr);
bool is_vaddr_t_lt (vaddr_t* a, vaddr_t* b);
bool is_vaddr_t_eq (vaddr_t a, vaddr_t b);

void* alloc_vpages (size_t req_count, bool user);
void* alloc_vpage (bool user);
Expand Down
22 changes: 17 additions & 5 deletions kernel/src/kernel/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ bool verify_elf_loadable (elf64_header_t* elf) {
}

int load_elf (const char* filepath, process* target_process, uintptr_t* entry_point_r) {
int64_t err = 0;

// TODO: open file as readonly once flags implemented
int64_t fd = (int64_t)sys_open ((uint64_t)filepath, 0ull, 0ull);
if (fd < 0) return fd;
Expand All @@ -49,8 +51,13 @@ int load_elf (const char* filepath, process* target_process, uintptr_t* entry_po
size_t ph_size = elf_header.elf_phnum * elf_header.elf_phentsize;
elf64_pheader_t* program_headers = kmalloc (ph_size);

sys_seek ((uint64_t)fd, elf_header.elf_phoff, SEEK_SET);
sys_read ((uint64_t)fd, (uint64_t)program_headers, ph_size);
err = sys_seek ((uint64_t)fd, elf_header.elf_phoff, SEEK_SET);
if (err < 0) return err;
err = sys_read ((uint64_t)fd, (uint64_t)program_headers, ph_size);
if (err < 0)
return err;
else if (err != (int64_t)ph_size)
return -ENOEXEC;

uintptr_t init_break = 0;

Expand All @@ -69,11 +76,16 @@ int load_elf (const char* filepath, process* target_process, uintptr_t* entry_po

alloc_by_cr3 (target_process->p_cr3, (uintptr_t)start, num_pages, is_writable);

sys_seek ((uint64_t)fd, ph->p_offset, SEEK_SET);
sys_read ((uint64_t)fd, ph->p_vaddr, ph->p_filesz);
err = sys_seek ((uint64_t)fd, ph->p_offset, SEEK_SET);
if (err < 0) return err;
err = sys_read ((uint64_t)fd, ph->p_vaddr, ph->p_filesz);
if (err < 0)
return err;
else if (err != (int64_t)ph->p_filesz)
return -ENOEXEC;

if (ph->p_memsz > ph->p_filesz)
kmemset ((void*)(ph->p_vaddr + ph->p_filesz), 0, ph->p_memsz - ph->p_filesz);
kmemset_explicit ((void*)(ph->p_vaddr + ph->p_filesz), 0, ph->p_memsz - ph->p_filesz);
}

init_break = ((init_break + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
Expand Down
21 changes: 14 additions & 7 deletions kernel/src/kernel/graphics.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include <kclib/stdio.h>
#include <kernel/graphics.h>
#include <kernel/memmgt.h>
#include <stddef.h>
#include <stdint.h>

static struct limine_framebuffer* framebuffer;
static size_t frmw, frmh;
static size_t stride_pixels;
uint32_t* fb_ptr;

/*!
Expand All @@ -15,6 +18,7 @@ void init_graphics (struct limine_framebuffer* buf) {
framebuffer = buf;
frmw = framebuffer->width;
frmh = framebuffer->height;
stride_pixels = framebuffer->pitch / (framebuffer->bpp / 8);
fb_ptr = framebuffer->address;
}

Expand All @@ -36,7 +40,7 @@ Convert screen position to index.
@param x x-position
@param y y-position
*/
inline size_t postoi (int x, int y) { return x + y * frmw; }
inline size_t postoi (int x, int y) { return (size_t)x + ((size_t)y * stride_pixels); }

/*!
Place a pixel on the screen.
Expand All @@ -45,7 +49,11 @@ Place a pixel on the screen.
@param x x-position
@param y y-position
*/
static void putPixel (uint32_t color, int x, int y) { fb_ptr[postoi (x, y)] = color; }
static void putPixel (uint32_t color, int x, int y) {
if (x < 0 || y < 0) return;
if ((size_t)x >= frmw || (size_t)y >= frmh) return;
fb_ptr[postoi (x, y)] = color;
}

/*!
Place a character on the screen
Expand Down Expand Up @@ -74,9 +82,8 @@ Draw a white border around the screen.
@param padding pixels to leave around the edges
*/
void drawBorder (size_t padding) {
for (size_t i = 0; i < frmw * frmh; i++)
if (i % frmw == padding || i % frmw == frmw - padding)
fb_ptr[i] = 0xffffff;
else if (i / frmw == padding || i / frmw == frmh - padding)
fb_ptr[i] = 0xffffff;
for (size_t y = 0; y < frmh; y++)
for (size_t x = 0; x < frmw; x++)
if (x == padding || x + padding + 1 == frmw || y == padding || y + padding + 1 == frmh)
putPixel (0xffffff, (int)x, (int)y);
}
6 changes: 4 additions & 2 deletions kernel/src/kernel/handlers.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include <kclib/stdio.h>
#include <kernel/handlers.h>
#include <kernel/idt.h>
#include <kernel/process.h>

void handle_gpf (registers_t* registers) {
(void)registers;
kserial_printf ("\nOopsy! Looks like someone tried to execute a disallowed instruction!");
kserial_printf ("Triggered GPF on PID #%lld\n", get_current_process ()->p_id);
log_registers_to_serial (registers);
for (;;)
;
}
Expand Down
46 changes: 23 additions & 23 deletions kernel/src/kernel/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,33 @@ static void idt_set_gate (uint8_t vector, void* isr, uint8_t gate_type, uint8_t
descriptor->present = present & 0x01;
}

static void log_registers_to_serial (registers_t* registers) {
void log_registers_to_serial (registers_t* registers) {
kserial_printf ("\n--- Interrupt/Exception Caught ---\n");

kserial_printf ("interrupt_number: 0x%llx\n", registers->interrupt_number);
kserial_printf ("error_code: 0x%llx\n", registers->error_code);
kserial_printf ("rip: 0x%llx\n", registers->rip);
kserial_printf ("cs: 0x%llx\n", registers->cs);
kserial_printf ("rflags: 0x%llx\n", registers->rflags);
kserial_printf ("rsp: 0x%llx\n", registers->rsp);
kserial_printf ("ss: 0x%llx\n\n", registers->ss);

kserial_printf ("rax: 0x%llx\n", registers->rax);
kserial_printf ("rbx: 0x%llx\n", registers->rbx);
kserial_printf ("rcx: 0x%llx\n", registers->rcx);
kserial_printf ("rdx: 0x%llx\n", registers->rdx);
kserial_printf ("rsi: 0x%llx\n", registers->rsi);
kserial_printf ("rdi: 0x%llx\n", registers->rdi);
kserial_printf ("rbp: 0x%llx\n\n", registers->rbp);

kserial_printf ("r8: 0x%llx\n", registers->r8);
kserial_printf ("r9: 0x%llx\n", registers->r9);
kserial_printf ("r10: 0x%llx\n", registers->r10);
kserial_printf ("r11: 0x%llx\n", registers->r11);
kserial_printf ("r12: 0x%llx\n", registers->r12);
kserial_printf ("r13: 0x%llx\n", registers->r13);
kserial_printf ("r14: 0x%llx\n", registers->r14);
kserial_printf ("r15: 0x%llx\n", registers->r15);
kserial_printf ("rip 0x%016llx ", registers->rip);
kserial_printf ("cs 0x%016llx ", registers->cs);
kserial_printf ("rflags 0x%016llx\n", registers->rflags);
kserial_printf ("rsp 0x%016llx ", registers->rsp);
kserial_printf ("ss 0x%016llx\n\n", registers->ss);

kserial_printf ("rax 0x%016llx ", registers->rax);
kserial_printf ("rbx 0x%016llx ", registers->rbx);
kserial_printf ("rcx 0x%016llx ", registers->rcx);
kserial_printf ("rdx 0x%016llx\n", registers->rdx);
kserial_printf ("rsi 0x%016llx ", registers->rsi);
kserial_printf ("rdi 0x%016llx ", registers->rdi);
kserial_printf ("rbp 0x%016llx\n\n", registers->rbp);

kserial_printf ("r8 0x%016llx ", registers->r8);
kserial_printf ("r9 0x%016llx ", registers->r9);
kserial_printf ("r10 0x%016llx ", registers->r10);
kserial_printf ("r11 0x%016llx\n", registers->r11);
kserial_printf ("r12 0x%016llx ", registers->r12);
kserial_printf ("r13 0x%016llx ", registers->r13);
kserial_printf ("r14 0x%016llx ", registers->r14);
kserial_printf ("r15 0x%016llx\n", registers->r15);

kserial_printf ("----------------------------------\n\n");
}
Expand Down
3 changes: 1 addition & 2 deletions kernel/src/kernel/memory/memmgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ static void page_fault_handler (registers_t* registers) {
__asm__ volatile ("mov %%cr2, %0" : "=r"(cr2));

kserial_printf ("\nEncountered a page fault!\nFaulting address: 0x%llx\n", cr2);
kserial_printf ("RIP: 0x%llx, RSP: 0x%llx\n", registers->rip, registers->rsp);
kserial_printf ("Error code: 0x%llx\n", registers->error_code);
log_registers_to_serial (registers);

for (;;)
;
Expand Down
6 changes: 3 additions & 3 deletions kernel/src/kernel/memory/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ void init_physical_bitmap (struct limine_memmap_response* memmap_response) {
for (uint64_t i = 0; i < memmap_response->entry_count; i++) {
struct limine_memmap_entry* entry = memmap_response->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE) {
for (uint64_t p = entry->base / PAGE_SIZE;
p < (entry->base + entry->length) / PAGE_SIZE; p++) {
uint64_t start_page = (entry->base + PAGE_SIZE - 1) / PAGE_SIZE;
uint64_t end_page = (entry->base + entry->length) / PAGE_SIZE;
for (uint64_t p = start_page; p < end_page; p++)
if (p < bitmap_fst_page || p >= bitmap_lst_page) bitmap_clear_bit (p);
}
}
}
}
11 changes: 11 additions & 0 deletions kernel/src/kernel/memory/vaddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,14 @@ bool is_vaddr_t_lt (vaddr_t* a, vaddr_t* b) {
}
return a->pml4_index < b->pml4_index;
}

/*!
* Check if vaddr a is strictly equal to vaddr b
* @param a first vaddr
* @param b second vaddr
* @return true if a == b, false otherwise
*/
bool is_vaddr_t_eq (vaddr_t a, vaddr_t b) {
return a.pml4_index == b.pml4_index && a.pdpt_index == b.pdpt_index &&
a.pd_index == b.pd_index && a.pt_index == b.pt_index && a.offset == b.offset;
}
103 changes: 62 additions & 41 deletions kernel/src/kernel/memory/vmm.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "kclib/stdio.h"
#include <kclib/string.h>
#include <kernel/memmgt.h>
#include <kernel/memory/pmm.h>
Expand Down Expand Up @@ -187,52 +188,69 @@ static bool is_table_empty (void* table_vaddr) {
* @param last last virtual page in range
*/
void free_all_vpages_in_range (vaddr_t first, vaddr_t last) {
pml4t_entry_t* pml4t_entry = &pml4_base_ptr[first.pml4_index];
if (!pml4t_entry->present) return;

vaddr_t current = first;
while (is_vaddr_t_lt (&current, &last)) {
pml4t_entry_t* pml4t_entry = &pml4_base_ptr[current.pml4_index];

if (!pml4t_entry->present) {
current.pml4_index++;
current.pdpt_index = current.pd_index = current.pt_index = 0;
continue;
}

while (true) {
pdpt_entry_t* pdpt_base =
(pdpt_entry_t*)get_vaddr_from_frame (pml4t_entry->pdpt_base_address);
pdpt_entry_t* pdpt_entry = &pdpt_base[current.pdpt_index];

if (pdpt_entry->present) {
pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address);
pd_entry_t* pd_entry = &pd_base[current.pd_index];

if (pd_entry->present) {
pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address);
pt_entry_t* pt_entry = &pt_base[current.pt_index];

if (pt_entry->present) {
pt_entry->present = 0;
pt_entry->frame_base_address = 0;

void* current_vaddr_ptr = vaddr_t_to_ptr (&current);
__asm__ volatile ("invlpg (%0)" : : "r"(current_vaddr_ptr) : "memory");

// --- GARBAGE COLLECTION ---
// We only need to check if a table is empty when we cross its boundary OR on
// our final page.
bool on_final_pg = !is_vaddr_t_lt (&current, &last);
if (((current.pt_index == 511) || on_final_pg) && is_table_empty (pt_base)) {
free_ppage ((void*)(pd_entry->pt_base_address * PAGE_SIZE));
pd_entry->present = 0;
pd_entry->pt_base_address = 0;

if (((current.pd_index == 511) || on_final_pg) &&
is_table_empty (pd_base)) {
free_ppage ((void*)(pdpt_entry->pd_base_address * PAGE_SIZE));
pdpt_entry->present = 0;
pdpt_entry->pd_base_address = 0;
}
}
if (!pdpt_entry->present) {
current.pdpt_index++;
if (current.pdpt_index >= 512) current.pdpt_index -= 512, current.pml4_index++;
current.pd_index = current.pt_index = 0;
continue;
}

pd_entry_t* pd_base = (pd_entry_t*)get_vaddr_from_frame (pdpt_entry->pd_base_address);
pd_entry_t* pd_entry = &pd_base[current.pd_index];

if (!pd_entry->present) {
current.pd_index++;
if (current.pd_index >= 512) current.pd_index -= 512, current.pdpt_index++;
if (current.pdpt_index >= 512) current.pdpt_index -= 512, current.pml4_index++;
current.pt_index = 0;
continue;
}

pt_entry_t* pt_base = (pt_entry_t*)get_vaddr_from_frame (pd_entry->pt_base_address);
pt_entry_t* pt_entry = &pt_base[current.pt_index];

if (pt_entry->present) {
pt_entry->present = 0;
free_ppage ((void*)(pt_entry->frame_base_address * PAGE_SIZE));
pt_entry->frame_base_address = 0;

__asm__ volatile ("invlpg (%0)" : : "r"(vaddr_t_to_ptr (&current)) : "memory");
}

bool on_final_pg = !is_vaddr_t_lt (&current, &last);
if (((current.pt_index == 511) || on_final_pg) && is_table_empty (pt_base)) {
pd_entry->present = 0;
free_ppage ((void*)(pd_entry->pt_base_address * PAGE_SIZE));
pd_entry->pt_base_address = 0;

if (((current.pd_index == 511) || on_final_pg) && is_table_empty (pd_base)) {
pdpt_entry->present = 0;
free_ppage ((void*)(pdpt_entry->pd_base_address * PAGE_SIZE));
pdpt_entry->pd_base_address = 0;

if (((current.pdpt_index == 511) || on_final_pg) && is_table_empty (pdpt_base)) {
pml4t_entry->present = 0;
free_ppage ((void*)(pml4t_entry->pdpt_base_address * PAGE_SIZE));
pml4t_entry->pdpt_base_address = 0;
}
}
}

if (!is_vaddr_t_lt (&current, &last)) break;
if (on_final_pg) break;

current.pt_index++;
if (current.pt_index >= 512) {
Expand All @@ -241,6 +259,10 @@ void free_all_vpages_in_range (vaddr_t first, vaddr_t last) {
if (current.pd_index >= 512) {
current.pd_index = 0;
current.pdpt_index++;
if (current.pdpt_index >= 512) {
current.pdpt_index = 0;
current.pml4_index++;
}
}
}
}
Expand All @@ -260,8 +282,6 @@ void free_vpages (void* ptr, size_t count) {
void* phys_base = get_paddr (ptr);
if (phys_base == nullptr) return;

free_ppages (phys_base, count);

uint64_t start_ptr_64t = (uint64_t)ptr;
uint64_t last_ptr_64t = start_ptr_64t + ((count - 1) * PAGE_SIZE);

Expand All @@ -281,11 +301,11 @@ void alloc_by_cr3 (uint64_t cr3, uintptr_t start, size_t num_pages, bool write)
if (num_pages == 0) return;
pml4t_entry_t* original_ptr = pml4_base_ptr;
pml4_base_ptr = (pml4t_entry_t*)(cr3 + get_hhdm_offset ());
uintptr_t last_page_base = ALIGN_PAGE_DOWN (start + (num_pages * PAGE_SIZE) - 1);

paddr_t physmem = alloc_ppages (num_pages);
alloc_all_vpages_in_range (get_vaddr_t_from_ptr ((void*)start),
get_vaddr_t_from_ptr ((void*)(start + (num_pages * PAGE_SIZE) - 1)),
physmem);
get_vaddr_t_from_ptr ((void*)last_page_base), physmem);

(void)write; // TODO: set rw flag

Expand All @@ -296,9 +316,10 @@ void dealloc_by_cr3 (uint64_t cr3, uintptr_t start, size_t num_pages) {
if (num_pages == 0) return;
pml4t_entry_t* original_ptr = pml4_base_ptr;
pml4_base_ptr = (pml4t_entry_t*)(cr3 + get_hhdm_offset ());
uintptr_t last_page_base = ALIGN_PAGE_DOWN (start + (num_pages * PAGE_SIZE) - 1);

free_all_vpages_in_range (get_vaddr_t_from_ptr ((void*)start),
get_vaddr_t_from_ptr ((void*)(start + (num_pages * PAGE_SIZE) - 1)));
get_vaddr_t_from_ptr ((void*)last_page_base));
pml4_base_ptr = original_ptr;
}

Expand Down
Loading
Loading