Skip to content

Commit

Permalink
Try to enter into usermode... with a test function
Browse files Browse the repository at this point in the history
  • Loading branch information
dreamos82 committed Nov 22, 2023
1 parent 284619e commit 499cd21
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 28 deletions.
8 changes: 8 additions & 0 deletions src/include/userspace/userspace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef __USERSPACE__
#define __USERSPACE__

#include <vmm.h>

uint64_t prepare_userspace_function(VmmInfo *vmm_info);

#endif
27 changes: 15 additions & 12 deletions src/kernel/arch/x86_64/mem/vmm_mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
uint8_t user_mode_status = 0;

if ( !is_address_higher_half((uint64_t) address) ) {
loglinef(Verbose, "(%s) address is in lower half", __FUNCTION__);
flags = flags | VMM_FLAGS_USER_LEVEL;
user_mode_status = VMM_FLAGS_USER_LEVEL;
}
Expand All @@ -29,7 +30,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
if (pml4_root != NULL) {
pml4_table = pml4_root;
loglinef(Verbose, "(%s): Entries values pml4_e: 0x%d pdpr_e: 0x%d pd_e: 0x%d", __FUNCTION__, pml4_e, pdpr_e, pd_e);
loglinef(Verbose, "(%s):\taddress: 0x%x", __FUNCTION__, address);
loglinef(Verbose, "(%s):\taddress: 0x%x, phys_address: 0x%x", __FUNCTION__, address, physical_address);
//loglinef(Verbose, "(%s):\tpml4_root address: 0x%x", __FUNCTION__, pml4_root);
//loglinef(Verbose, "(%s):\tpml4_root[pml4_e] = 0x%x pml4_table[pml4_e] = 0x%x", __FUNCTION__, pml4_root[pml4_e], pml4_table[pml4_e]);
loglinef(Verbose, "(%s):\tpdpr base_address: 0x%x", __FUNCTION__, pml4_root[pml4_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK);
Expand All @@ -42,6 +43,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
clean_new_table(new_table_hhdm);
pdpr_root = new_table_hhdm;
} else {
loglinef(Verbose, "(%s) No need to allocate pml4", __FUNCTION__);
pdpr_root = (uint64_t *) hhdm_get_variable((uintptr_t) pml4_root[pml4_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK);
}

Expand All @@ -53,33 +55,34 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
clean_new_table(new_table_hhdm);
pd_root = new_table_hhdm;
} else {
loglinef(Verbose, "(%s) No need to allocate pdpr", __FUNCTION__);
pd_root = (uint64_t *) hhdm_get_variable((uintptr_t) pdpr_root[pdpr_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK);
}

if( !(pd_root[pd_e] & 0b1) ) {
#if SMALL_PAGES == 1
uint64_t *new_table = pmm_alloc_frame();
pd_root[pd_e] = (uint64_t) new_table | user_mode_status | WRITE_BIT | PRESENT_BIT;
uint64_t *new_table_hhdm = hhdm_get_variable((uintptr_t) new_table);
clean_new_table(new_table_hhdm);
pt_root = new_table_hhdm;
uint64_t *new_table = pmm_alloc_frame();
pd_root[pd_e] = (uint64_t) new_table | user_mode_status | WRITE_BIT | PRESENT_BIT;
uint64_t *new_table_hhdm = hhdm_get_variable((uintptr_t) new_table);
clean_new_table(new_table_hhdm);
pt_root = new_table_hhdm;
#elif SMALL_PAGES == 0
pd_root[pd_e] = (uint64_t) (physical_address) | HUGEPAGE_BIT | flags | user_mode_status;
loglinef(Verbose, "(%s): PD Flags: 0x%x entry value: 0x%x", __FUNCTION__, flags, pd_root[pd_e]);
pd_root[pd_e] = (uint64_t) (physical_address) | HUGEPAGE_BIT | flags | user_mode_status;
loglinef(Verbose, "(%s): PD Flags: 0x%x entry value pd_root[0x%x]: 0x%x", __FUNCTION__, flags, pd_e, pd_root[pd_e]);
#endif
}
}

#if SMALL_PAGES == 1
uint64_t *pt_table = (uint64_t *) (SIGN_EXTENSION | ENTRIES_TO_ADDRESS(510l, (uint64_t) pml4_e, (uint64_t) pdpr_e, (uint64_t) pd_e));
//uint64_t *pt_table = (uint64_t *) (SIGN_EXTENSION | ENTRIES_TO_ADDRESS(510l, (uint64_t) pml4_e, (uint64_t) pdpr_e, (uint64_t) pd_e));
uint16_t pt_e = PT_ENTRY((uint64_t) address);
#endif

#if SMALL_PAGES == 1

// This case apply only for 4kb pages, if the pt_e entry is not present in the page table we need to allocate a new 4k page
// Every entry in the page table is a 4kb page of physical memory
if( !(pt_table[pt_e] & 0b1)) {
pt_table[pt_e] = (uint64_t) physical_address | flags;
if( !(pt_root[pt_e] & 0b1)) {
pt_root[pt_e] = (uint64_t) physical_address | flags;
}
#endif

Expand Down
12 changes: 3 additions & 9 deletions src/kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,14 @@
#include <scheduler.h>
#include <thread.h>
#include <rtc.h>
#include <fcntl.h>
#include <unistd.h>
#include <spinlock.h>
#include <task.h>
#include <tss.h>
#include <vfs.h>
#include <vm.h>
#include <vmm.h>
#include <vmm_mapping.h>
#include <userspace.h>
//#include <runtime_tests.h>

extern uint32_t FRAMEBUFFER_MEMORY_SIZE;
Expand Down Expand Up @@ -201,16 +200,10 @@ void kernel_start(unsigned long addr, unsigned long magic){
task_t* idle_task = create_task("idle", noop, &a, true);
idle_thread = idle_task->threads;
//task_t* eldi_task = create_task("eldi", noop2, &b);
task_t* userspace_task = create_task("userspace_idle", NULL, &b, false);
//create_thread("ledi", noop2, &c, eldi_task);
//create_task("sleeper", noop3, &d);
//print_thread_list(eldi_task->task_id);
/*int fd_id = open("/home/ivan/testfile.txt", 0);
loglinef(Verbose, "(kernel_main) Obtained fd id: %d fs_fd_id: %d", fd_id, vfs_opened_files[fd_id].fs_specific_id);
char buffer[15] = "";
read(fd_id, buffer, 15);
loglinef(Verbose, "(kernel_main) Output of read: %s", buffer);
int result = close(fd_id);
loglinef(Verbose, "(kernel_main) Closing file with id: %d", result);*/
//execute_runtime_tests();
start_apic_timer(kernel_settings.apic_timer.timer_ticks_base, APIC_TIMER_SET_PERIODIC, kernel_settings.apic_timer.timer_divisor);
loglinef(Verbose, "(kernel_main) (END of Mapped memory: 0x%x)", end_of_mapped_memory);
Expand All @@ -219,6 +212,7 @@ void kernel_start(unsigned long addr, unsigned long magic){
struct multiboot_tag_basic_meminfo *virt_phys_addr = (struct multiboot_tag_basic_meminfo *) hhdm_get_variable( (size_t) multiboot_basic_meminfo );
loglinef(Verbose, "(kernel_main) init_basic_system: Memory lower (in kb): %d - upper (in kb): %d", virt_phys_addr->mem_lower, virt_phys_addr->mem_upper);
logline(Info, "(kernel_main) Init end!! Starting infinite loop");
//prepare_userspace_function();
//uint64_t* vm_root_vaddress = (uint64_t *) vmm_alloc(PAGE_SIZE_IN_BYTES, VMM_FLAGS_ADDRESS_ONLY, NULL);
//void* temp_var = pmm_alloc_frame();
//map_phys_to_virt_addr_hh(temp_var, (void *) vm_root_vaddress, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/mem/hh_direct_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void hhdm_map_physical_memory() {
}

while ( address_to_map < memory_size_in_bytes) {
//loglinef(Verbose, "(direct_map_physical_memory) Mapping physical address: 0x%x", address_to_map);
//loglinef(Verbose, "(%s) Mapping physical address: 0x%x - virtual address: 0x%x", __FUNCTION__ ,address_to_map, virtual_address);
//p4_table[current_entry] = address_to_map | HUGEPAGE_BIT| WRITE_BIT | PRESENT_BIT;
map_phys_to_virt_addr((void*)address_to_map, (void*)virtual_address, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
address_to_map += PAGE_SIZE_IN_BYTES;
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/mem/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void vmm_init(vmm_level_t vmm_level, VmmInfo *vmm_info) {

// Mapping the phyiscal address for the vmm structures
map_phys_to_virt_addr_hh(vmm_root_phys, vmm_info->status.vmm_container_root, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, root_table_hh);

loglinef(Verbose, "(%s): Leaving vmm_init", __FUNCTION__);
vmm_info->status.vmm_container_root->next = NULL;
vmm_info->status.vmm_cur_container = vmm_info->status.vmm_container_root;
}
Expand Down
6 changes: 4 additions & 2 deletions src/kernel/scheduling/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ cpu_status_t* schedule(cpu_status_t* cur_status) {
prev_executing_thread = current_executing_thread;
prev_thread_tid = prev_executing_thread->tid;
current_thread = scheduler_get_next_thread();
loglinef(Verbose, "(%s): Current thread %d status is new, name: %s!", __FUNCTION__ ,current_thread->tid, current_thread->thread_name);

while (current_thread->tid != prev_thread_tid) {
if (current_thread->status == SLEEP) {
Expand All @@ -91,15 +90,18 @@ cpu_status_t* schedule(cpu_status_t* cur_status) {
current_thread = scheduler_get_next_thread();
}

loglinef(Verbose, "(%s): Current thread %d status: %d name: %s!", __FUNCTION__ , current_thread->status, current_thread->tid, current_thread->thread_name);

// We have found a thread to run, let's update it's status
thread_to_execute->status = RUN;
thread_to_execute->ticks = 0;
// ... and update the current executing thread
current_executing_thread = thread_to_execute;
task_t *current_task = current_executing_thread->parent_task;
// ... every task has it's own addressing space, so we need to update the cr3 register
loglinef(Verbose, "(%s) Loading cr3: 0x%x", __FUNCTION__, current_task->vm_root_page_table);
load_cr3(current_task->vm_root_page_table);
loglinef(Verbose, "(%s): current_thread->execution_frame->rsp: 0x%x", __FUNCTION__, current_executing_thread->execution_frame->rsp);
loglinef(Verbose, "(%s): current_thread->execution_frame->rip: 0x%x, vmm_data is: 0x%x", __FUNCTION__, current_executing_thread->execution_frame->rip, &(current_task->vmm_data));
// ... and finally we need to update the tss structure with the current thread rsp0
kernel_tss.rsp0 = (uint64_t) current_executing_thread->rsp0;
//loglinef(Verbose, "(schedule) leaving schedule...");
Expand Down
9 changes: 7 additions & 2 deletions src/kernel/scheduling/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ task_t* create_task(char *name, void (*_entry_point)(void *), void *args, bool i
} else {
vmm_init(VMM_LEVEL_USER, &(new_task->vmm_data));
}

if( _entry_point != NULL) {
if( is_supervisor) {
loglinef(Verbose, "(%s): creating new thread", __FUNCTION__);
thread_t* thread = create_thread(name, _entry_point, args, new_task, is_supervisor);
new_task->threads = thread;
} else {
loglinef(Verbose, "(%s): creating new thread userspace", __FUNCTION__);
thread_t* thread = create_thread(name, NULL, args, new_task, is_supervisor);
new_task->threads = thread;
}
scheduler_add_task(new_task);
//re-enable interrupts
Expand All @@ -52,6 +56,7 @@ void prepare_virtual_memory_environment(task_t* task) {
//void* vm_root_vaddress = vmm_alloc(PAGE_SIZE_IN_BYTES, VMM_FLAGS_ADDRESS_ONLY, NULL);
void* vm_root_vaddress = hhdm_get_variable ((uintptr_t) task->vm_root_page_table);
task->vmm_data.root_table_hhdm = (uintptr_t) vm_root_vaddress;
loglinef(Verbose, "(%s) vm_root_vaddress: %x", __FUNCTION__, vm_root_vaddress);
//map_phys_to_virt_addr(task->vm_root_page_table, vm_root_vaddress, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);

// 2. We will map the whole higher half of the kernel, this means from pml4 item 256 to 511
Expand Down
10 changes: 9 additions & 1 deletion src/kernel/scheduling/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <kheap.h>
#include <logging.h>
#include <kernel.h>
#include <userspace.h>
#include <vmm.h>

unsigned char code_to_run[] = {
Expand Down Expand Up @@ -34,7 +35,14 @@ thread_t* create_thread(char* thread_name, void (*_entry_point)(void *), void* a
new_thread->execution_frame = kmalloc(sizeof(cpu_status_t));
new_thread->execution_frame->interrupt_number = 0x101;
new_thread->execution_frame->error_code = 0x0;
new_thread->execution_frame->rip = (uint64_t) code_to_run;
if (!is_supervisor) {
loglinef(Verbose, "(%s): vmm_data address: 0x%x", __FUNCTION__, &(parent_task->vmm_data));
new_thread->execution_frame->rip = prepare_userspace_function(&(parent_task->vmm_data));
loglinef(Verbose, "(%s): using userspace function address: 0x%x", __FUNCTION__, new_thread->execution_frame->rip);
} else {
loglinef(Verbose, "(%s): using idle function", __FUNCTION__);
new_thread->execution_frame->rip = (uint64_t) code_to_run;
}
// rdi and rsi are the two arguments passed to the thread_execution_wrapper function
new_thread->execution_frame->rdi = 0;
new_thread->execution_frame->rsi = 0;
Expand Down
27 changes: 27 additions & 0 deletions src/userpsace/test_userspace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <bitmap.h>
#include <logging.h>
#include <pmm.h>
#include <userspace.h>
#include <vmm.h>
#include <vmm_mapping.h>

unsigned char infinite_loop[] = {
0xeb, 0xfe
};

uint64_t prepare_userspace_function(VmmInfo *vmm_info) {
loglinef(Verbose, "(%s): preparing userspace function vmm_data", __FUNCTION__);
if( vmm_info == NULL ) {
loglinef(Fatal, "(%s): Error: vmm_info is null");
}
void *temp_var = pmm_alloc_frame();
char *code_page = vmm_alloc(PAGE_SIZE_IN_BYTES, VMM_FLAGS_ADDRESS_ONLY | VMM_FLAGS_WRITE_ENABLE, NULL);
map_phys_to_virt_addr_hh(temp_var, (void *) code_page, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
code_page[0] = infinite_loop[0];
code_page[1] = infinite_loop[1];
char *user_code_page = vmm_alloc(PAGE_SIZE_IN_BYTES, VMM_FLAGS_ADDRESS_ONLY | VMM_FLAGS_WRITE_ENABLE | VMM_FLAGS_PRESENT | VMM_FLAGS_USER_LEVEL, vmm_info);
map_phys_to_virt_addr_hh(temp_var, (void *) user_code_page,VMM_FLAGS_USER_LEVEL | VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, (uint64_t *) vmm_info->root_table_hhdm);
//loglinef(Verbose, "(%s): user_code_page[0]: 0x%x - user_code_page[1]: 0x%x", __FUNCTION__, user_code_page[0], user_code_page[1]);
loglinef(Verbose, "(%s): leaving prparing userspace function", __FUNCTION__);
return (uint64_t) user_code_page;
}

0 comments on commit 499cd21

Please sign in to comment.