Skip to content

Commit

Permalink
Fix prepare_virtual_memory_environment bug (#177)
Browse files Browse the repository at this point in the history
* Fix prepare_virtual_memory_environment bug

* minor fixes on comments and extra whitespaces
  • Loading branch information
dreamos82 authored Sep 1, 2023
1 parent 19075db commit a4ba1d0
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 24 deletions.
6 changes: 3 additions & 3 deletions src/kernel/arch/x86_64/system/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ void page_fault_handler(uint64_t error_code) {
uint64_t cr2_content = 0;
uint64_t pd;
uint64_t pdpr;
uint64_t pml4;
uint64_t pml4;
asm ("mov %%cr2, %0" : "=r" (cr2_content) );
loglinef(Verbose, "-- Error code value: %d", error_code);
loglinef(Verbose, "-- Faulting address: 0x%X", cr2_content);
cr2_content = cr2_content & VM_OFFSET_MASK;
loglinef(Verbose, "-- Address prepared for PD/PT extraction: %x", cr2_content);
pd = PD_ENTRY(cr2_content);
pd = PD_ENTRY(cr2_content);
pdpr = PDPR_ENTRY(cr2_content);
pml4 = PML4_ENTRY(cr2_content);
loglinef(Verbose, "Error flags: FETCH(%d) - RSVD(%d) - ACCESS(%d) - WRITE(%d) - PRESENT(%d)", \
Expand Down Expand Up @@ -59,7 +59,7 @@ void invalidate_page_table( uint64_t *table_address ) {
}

/**
* This function given an address if it is not in the higher half, it return the same address + HIGHER_HALF_ADDRESS_OFFSET already defined.
* This function given an address if it is not in the higher half, it return the same address + HIGHER_HALF_ADDRESS_OFFSET already defined.
*
*
* @param address the physical address we want to map
Expand Down
9 changes: 6 additions & 3 deletions src/kernel/mem/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@ void *vmm_alloc(size_t size, size_t flags, VmmInfo *vmm_info) {

size_t required_pages = get_number_of_pages_from_size(size);
size_t arch_flags = vm_parse_flags(flags);
loglinef(Verbose, "(%s): Testing vm_parse_flags: 0x%x", __FUNCTION__, arch_flags);
loglinef(Verbose, "(%s): Testing vm_parse_flags: 0x%x required pages: %d - address to ret: 0x%x", __FUNCTION__, arch_flags, required_pages, address_to_return);

for ( int i = 0; i < required_pages; i++ ) {
void * frame = pmm_alloc_frame();
loglinef(Verbose, "(%s): mapping frame: 0x%x into: 0x%x", __FUNCTION__, frame, ((void *)address_to_return + (i * PAGE_SIZE_IN_BYTES)));
map_phys_to_virt_addr((void*) frame, (void *)address_to_return + (i * PAGE_SIZE_IN_BYTES), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
}
}
Expand Down Expand Up @@ -304,7 +305,7 @@ void *map_phys_to_virt_addr(void* physical_address, void* address, size_t flags)

uint64_t *pd_table = (uint64_t *) (SIGN_EXTENSION | ENTRIES_TO_ADDRESS(510l,510l, (uint64_t) pml4_e, (uint64_t) pdpr_e));
uint16_t pd_e = PD_ENTRY((uint64_t) address);
//loglinef(Verbose, "(map_phys_to_virt_addr) Pml4: %u - pdpr: %u - pd: %u", pml4_e, pdpr_e, pd_e);
// loglinef(Verbose, "(map_phys_to_virt_addr) Pml4: %u - pdpr: %u - pd: %u - flags: 0x%x to address: 0x%x", pml4_e, pdpr_e, pd_e, flags, address);
uint8_t user_mode_status = 0;

#if SMALL_PAGES == 1
Expand All @@ -322,9 +323,9 @@ void *map_phys_to_virt_addr(void* physical_address, void* address, size_t flags)
// If the pml4_e item in the pml4 table is not present, we need to create a new one.
// Every entry in pml4 table points to a pdpr table
if( !(pml4_table[pml4_e] & 0b1) ) {
//loglinef(Verbose, "(%s): need to allocate pml4 for address: 0x%x", __FUNCTION__, (uint64_t) address);
uint64_t *new_table = pmm_alloc_frame();
pml4_table[pml4_e] = (uint64_t) new_table | user_mode_status | WRITE_BIT | PRESENT_BIT;
// loglinef(Verbose, "(%s): need to allocate pml4 for address: 0x%x - Entry value: 0x%x - phys_address: 0x%x", __FUNCTION__, (uint64_t) address, pml4_table[pml4_e], new_table);
clean_new_table(pdpr_table);
}

Expand All @@ -335,6 +336,7 @@ void *map_phys_to_virt_addr(void* physical_address, void* address, size_t flags)
if( !(pdpr_table[pdpr_e] & 0b1) ) {
uint64_t *new_table = pmm_alloc_frame();
pdpr_table[pdpr_e] = (uint64_t) new_table | user_mode_status | WRITE_BIT | PRESENT_BIT;
// loglinef(Verbose, "(%s): PDPR entry value: 0x%x", __FUNCTION__, pdpr_table[pdpr_e]);
clean_new_table(pd_table);
}

Expand All @@ -347,6 +349,7 @@ void *map_phys_to_virt_addr(void* physical_address, void* address, size_t flags)
clean_new_table(pt_table);
#elif SMALL_PAGES == 0
pd_table[pd_e] = (uint64_t) (physical_address) | HUGEPAGE_BIT | flags;
// loglinef(Verbose, "(%s): PD Flags: 0x%x entry value: 0x%x", __FUNCTION__, flags, pd_table[pd_e]);
#endif
}

Expand Down
4 changes: 2 additions & 2 deletions src/kernel/mem/vmm_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ bool is_address_aligned(size_t value, size_t alignment) {
*
*
* @param flags vmm flags
* @return architecture independat flags
* @return architecture dependant flags
*/
size_t vm_parse_flags( size_t flags ) {
flags = flags & ~(1 << 7);
flags = flags & ~(1 << 7);
return flags;
}
22 changes: 11 additions & 11 deletions src/kernel/scheduling/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ cpu_status_t* schedule(cpu_status_t* cur_status) {
//loglinef(Verbose, "Current thread %d status is sleeping!", current_executing_thread->tid);
current_executing_thread->ticks = SCHEDULER_NUMBER_OF_TICKS;
}

if (current_executing_thread->ticks++ < SCHEDULER_NUMBER_OF_TICKS) {
return cur_status;
}
Expand All @@ -67,7 +67,7 @@ cpu_status_t* schedule(cpu_status_t* cur_status) {

while (current_thread->tid != prev_thread_tid) {
if (current_thread->status == SLEEP) {
loglinef(Verbose, "(schedule) This thread %d is sleeping", current_thread->tid);
loglinef(Verbose, "(schedule) This thread %d is sleeping", current_thread->tid);
//loglinef(Verbose, "Current uptime: %d - wakeup: %d", get_kernel_uptime(), current_thread->wakeup_time);
if ( get_kernel_uptime() > current_thread->wakeup_time) {
//loglinef(Verbose, "(schedule) --->WAKING UP: %d - thread_name: %s", current_thread->tid, current_thread->thread_name);
Expand All @@ -76,7 +76,7 @@ cpu_status_t* schedule(cpu_status_t* cur_status) {
break;
}
}

if (current_thread->status == DEAD) {
remove_thread_from_task(current_thread->tid, current_thread->parent_task);
scheduler_delete_thread(current_thread->tid);
Expand All @@ -85,14 +85,14 @@ cpu_status_t* schedule(cpu_status_t* cur_status) {
break;
}
prev_thread_tid = current_thread->tid;
current_thread = scheduler_get_next_thread();
current_thread = scheduler_get_next_thread();
}

thread_to_execute->status = RUN;
thread_to_execute->ticks = 0;
current_executing_thread = thread_to_execute;
task_t *current_task = current_executing_thread->parent_task;
load_cr3(current_task->vm_root_page_table);
load_cr3(current_task->vm_root_page_table);
//loglinef(Verbose, "(schedule) leaving schedule...");
return current_executing_thread->execution_frame;
}
Expand All @@ -106,7 +106,7 @@ void scheduler_add_task(task_t* task) {
}

void scheduler_add_thread(thread_t* thread) {
thread->next = thread_list;
thread->next = thread_list;
thread_list_size++;
thread_list = thread;
loglinef(Verbose, "(scheduler_add_thread) Adding thread: %s - %d", thread_list->thread_name, thread_list->tid);
Expand All @@ -120,22 +120,22 @@ void scheduler_delete_thread(size_t thread_id) {
loglinef(Verbose, "(scheduler_delete_thread) Called with thread id: %d", thread_id);
thread_t *thread_item = thread_list;
thread_t *prev_item = NULL;

// First thing: we should search for the thread to be deleted.
while (thread_item != NULL && thread_item->tid != thread_id ) {
prev_item = thread_item;
thread_item = thread_item->next;
}

if (thread_item == NULL) {
return;
}

kfree(thread_item->execution_frame);
kfree(thread_item->stack - THREAD_DEFAULT_STACK_SIZE);

if (thread_item == thread_list) {
// If thread_item == thread_list it means that it is the first item so we just need
// If thread_item == thread_list it means that it is the first item so we just need
// to make the root of the stack to point to the next item
thread_list = thread_list->next;
thread_list_size--;
Expand All @@ -159,7 +159,7 @@ thread_t* scheduler_get_next_thread() {
if (current_executing_thread->next == NULL) {
return thread_list;
}
return current_executing_thread->next;
return current_executing_thread->next;
}

size_t scheduler_get_queue_size() {
Expand Down
11 changes: 7 additions & 4 deletions src/kernel/scheduling/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ task_t* create_task(char *name, void (*_entry_point)(void *), void *args) {
}

void prepare_virtual_memory_environment(task_t* task) {
loglinef(Verbose, "(prepare_virtual_memory_environment) Placeholder for virtual_memory");
// Steps:
// 1. Prepare resources: allocatin an array of VM_PAGES_PER_TABLE
// Make sure this address is physical, then it needs to be mapped to a virtual one.a
Expand All @@ -50,10 +49,14 @@ void prepare_virtual_memory_environment(task_t* task) {
// 2. We will map the whole higher half of the kernel, this means from pml4 item 256 to 511
// ((uint64_t *)task->vm_root_page_table)[0] = p4_table[0];
for(int i = 255; i < VM_PAGES_PER_TABLE; i++) {
((uint64_t *)vm_root_vaddress)[i] = p4_table[i];
if(p4_table[i] != 0) {
if ( i == 510 ) {
((uint64_t *)vm_root_vaddress)[i] = (uint64_t) (task->vm_root_page_table) | VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE;
loglinef(Verbose, "(%s): Mapping recursive entry: 0x%x", __FUNCTION__, ((uint64_t *)vm_root_vaddress)[i]);
} else {
((uint64_t *)vm_root_vaddress)[i] = p4_table[i];
}
if (p4_table[i] != 0) {
loglinef(Verbose, "(prepare_virtual_memory_environment): %d: o:0x%x - c:0x%x - t:0x%x", i, p4_table[i], kernel_settings.paging.page_root_address[i], ((uint64_t*)vm_root_vaddress)[i]);

}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/kernel/scheduling/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ thread_t* create_thread(char* thread_name, void (*_entry_point)(void *), void* a

if (parent_task != NULL) {
add_thread_to_task(parent_task, new_thread);
} else {
loglinef(Fatal, "(%s): Cannot create thread without parent task");
}

scheduler_add_thread(new_thread);
Expand Down Expand Up @@ -144,7 +146,9 @@ void noop3(char *c) {
loglinef(Verbose, "(noop3): test_addr[0] = %d", test_addr[0]);
task_t *current_task = current_executing_thread->parent_task;
uint64_t *tmp_var = vmm_alloc(0x1000, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, &(current_task->vmm_data));
loglinef(Verbose, "(%s) Tmp var address returned by vmm_alloc: 0x%x", __FUNCTION__, tmp_var);
loglinef(Verbose, "(%s) task name: %s - Tmp var address returned by vmm_alloc: 0x%x", __FUNCTION__, current_task->task_name, tmp_var);
tmp_var[0] = 0x1234;
loglinef(Verbose, "(%s) Tmp var address returned by vmm_alloc: 0x%x==0x1234 ", __FUNCTION__, tmp_var[0]);
}

char *get_thread_status(thread_t *thread) {
Expand Down

0 comments on commit a4ba1d0

Please sign in to comment.