Skip to content
Open
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
2 changes: 2 additions & 0 deletions sources/kernel/include/memory/pages.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#pragma once

#include <hal/intdef.h>
#include <process/mutex.h>
#include "memmap.h"

class CPage_Manager
{
private:
uint8_t mPage_Bitmap[mem::PageCount / 8];
CMutex* mutex;

void Mark(uint32_t page_idx, bool used);

Expand Down
23 changes: 23 additions & 0 deletions sources/kernel/include/memory/user_task_heap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once
#include <hal/intdef.h>
#include <process/process.h>
#include <memory/mmu.h>

struct TTask_Struct;

struct TPage_List_Node {
uint32_t used_space;
uint32_t virt_user_addr;
void* page_start;
TPage_List_Node* next;
};

class CUser_Task_Heap_Manager {
private:
TPage_List_Node* first_page;
void* Allocate_New_Page(TTask_Struct* task);

public:
CUser_Task_Heap_Manager();
void* Alloc(uint32_t size, TTask_Struct* task);
};
6 changes: 6 additions & 0 deletions sources/kernel/include/process/process.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <memory/user_task_heap.h>

// maximalni pocet otevrenych souboru
constexpr uint32_t Max_Process_Opened_Files = 16;
Expand Down Expand Up @@ -36,6 +37,8 @@ struct TCPU_Context

class IFile;

struct CUser_Task_Heap_Manager;

// struktura procesu (tasku, ...)
struct TTask_Struct
{
Expand All @@ -50,4 +53,7 @@ struct TTask_Struct
// maximalni podporovany rozsah cekani je 0x7FFFFFFF, jelikoz muze citac pretect; diference je vzdy pocitana i s moznosti preteceni
uint32_t deadline; // deadline dokonceni tasku
uint32_t notified_deadline; // deadline nastavena po nasledujicim probuzeni procesu
uint32_t heap_base;
uint32_t heap_next;
CUser_Task_Heap_Manager* heap_manager;
};
5 changes: 5 additions & 0 deletions sources/kernel/include/process/swi.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ enum class NSWI_Process_Service
// IN: r0 = subservice (NDeadline_Subservice), r1 = ukazatel na prepravku dle druhu pozadavku
// OUT: r0 = infikator uspechu (NSWI_Result_Code)
Deadline = 5,

// Alokuje pamet pro proces
// IN: r0 = velikost pameti k alokaci v bytech
// OUT: r0 = ukazatel na alokovanou pamet nebo nullptr
Malloc = 6,
};

enum class NSWI_Filesystem_Service
Expand Down
6 changes: 5 additions & 1 deletion sources/kernel/src/memory/pages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ CPage_Manager::CPage_Manager()
mPage_Bitmap[i] = 0;

// nutno dodat, ze strankovatelna pamet implicitne nezahrnuje pamet, kam se nahralo jadro
mutex = new CMutex();
}

void CPage_Manager::Mark(uint32_t page_idx, bool used)
Expand All @@ -23,7 +24,8 @@ uint32_t CPage_Manager::Alloc_Page()
{
// VELMI jednoduchy alokator stranek, prochazi bitmapu a hleda prvni volne misto
// to je samozrejme O(n) a pro prakticke pouziti ne uplne dobre, ale k tomuto problemu az jindy

bool locked = mutex->Lock();

uint32_t i, j;

// projdeme vsechny stranky
Expand All @@ -40,11 +42,13 @@ uint32_t CPage_Manager::Alloc_Page()
// oznacime
const uint32_t page_idx = i*8 + j;
Mark(page_idx, true);
mutex->Unlock();
return mem::LowMemory + page_idx * mem::PageSize;
}
}
}
}
mutex->Unlock();

return 0;
}
Expand Down
61 changes: 61 additions & 0 deletions sources/kernel/src/memory/user_task_heap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <memory/user_task_heap.h>
#include <memory/kernel_heap.h>
#include <memory/pages.h>
#include <memory/memmap.h>
#include <process/process.h>
#include <drivers/uart.h>
#include <stdstring.h>

CUser_Task_Heap_Manager::CUser_Task_Heap_Manager()
: first_page{nullptr}
{
//
}

void* CUser_Task_Heap_Manager::Allocate_New_Page(TTask_Struct* task) {
void* page_data = reinterpret_cast<void*>(sPage_Manager.Alloc_Page());

unsigned long ttbr0_phys_address = task->cpu_context.ttbr0 & ~0x00003FFF;
unsigned long ttbr0_address = ttbr0_phys_address + mem::MemoryVirtualBase;
uint32_t phys_addr_page_start = reinterpret_cast<uint32_t>(page_data) - mem::MemoryVirtualBase;
map_memory(reinterpret_cast<uint32_t*>(ttbr0_address), phys_addr_page_start, task->heap_next);

return page_data;
}

void* CUser_Task_Heap_Manager::Alloc(uint32_t size, TTask_Struct* task) {
if (size > mem::PageSize) {
return nullptr;
}


if (first_page == nullptr) {
first_page = sKernelMem.Alloc<TPage_List_Node>();
first_page->used_space = 0;
first_page->virt_user_addr = task->heap_base;
first_page->page_start = Allocate_New_Page(task);
first_page->next = nullptr;
task->heap_next += mem::PageSize;
}

TPage_List_Node* current_page = first_page;
while (current_page->next != nullptr && mem::PageSize - current_page->used_space < size) {
current_page = current_page->next;
}

if (mem::PageSize - current_page->used_space < size) {
TPage_List_Node* new_page = sKernelMem.Alloc<TPage_List_Node>();
new_page->used_space = 0;
new_page->virt_user_addr = task->heap_next;
new_page->page_start = Allocate_New_Page(task);
new_page->next = nullptr;
task->heap_next += mem::PageSize;

current_page->next = new_page;
current_page = new_page;
}

uint32_t alloc_addr = current_page->virt_user_addr + current_page->used_space;
current_page->used_space += size;
return reinterpret_cast<void*>(alloc_addr);
}
9 changes: 9 additions & 0 deletions sources/kernel/src/process/process_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ uint32_t CProcess_Manager::Create_Process(unsigned char* elf_file_data, unsigned
task->state = NTask_State::New;
task->deadline = Indefinite; // task si zatim nestanovil deadline, udela to az to bude aktualni v deadline syscallu
task->notified_deadline = Indefinite;
task->heap_manager = new CUser_Task_Heap_Manager();

// lr = co zacit vykonavat po bootstrapu, 0x8000 je misto, kam je relokovany v kazde nasi binarce symbol _start, tedy vstupni bod programu
//task->cpu_context.lr = 0x8000;
Expand All @@ -123,6 +124,9 @@ uint32_t CProcess_Manager::Create_Process(unsigned char* elf_file_data, unsigned
// pozn. zasobnik roste na druhou stranu, takze musime SP nastavit na konec stranky
task->cpu_context.sp = 0x90000000 + mem::PageSize;

task->heap_base = 0x21000000;
task->heap_next = task->heap_base;

// alokujeme stranku pro kod a pro zasobnik
uint32_t code_page_phys = static_cast<unsigned long>(sPage_Manager.Alloc_Page()) - mem::MemoryVirtualBase;
uint32_t stack_page_phys = static_cast<unsigned long>(sPage_Manager.Alloc_Page()) - mem::MemoryVirtualBase;
Expand Down Expand Up @@ -308,6 +312,11 @@ void CProcess_Manager::Handle_Process_SWI(NSWI_Process_Service svc_idx, uint32_t
}
break;
}
case NSWI_Process_Service::Malloc: {
TTask_Struct* task = mCurrent_Task_Node->task;
target.r0 = reinterpret_cast<uint32_t>(task->heap_manager->Alloc(r0, task));
break;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions sources/stdlib/include/stdfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ uint32_t get_active_process_count();
uint32_t get_tick_count();
void set_task_deadline(uint32_t tick_count_required);
uint32_t get_task_ticks_to_deadline();
void* malloc(uint32_t size, uint32_t uart);

uint32_t open(const char* filename, NFile_Open_Mode mode);
uint32_t read(uint32_t file, char* const buffer, uint32_t size);
Expand Down
37 changes: 37 additions & 0 deletions sources/stdlib/src/stdfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,43 @@ uint32_t get_task_ticks_to_deadline()
return ticks;
}

const uint32_t min_alloc_size = 128;
static uint32_t used = 0;
static uint32_t allocated = 0;
static uint32_t memory_block_base = 0;

void* malloc(uint32_t size, uint32_t uart) {
if (allocated < size && min_alloc_size < size) {
void* ptr;
asm volatile("mov r0, %0" : : "r" (size));
asm volatile("swi 6");
asm volatile("mov %0, r0" : "=r" (ptr));
return ptr;
}

if (used + size > allocated) {
void* ptr;
asm volatile("mov r0, %0" : : "r" (min_alloc_size));
asm volatile("swi 6");
asm volatile("mov %0, r0" : "=r" (ptr));
if (ptr == nullptr) {
return nullptr;
}

if ((uint32_t)ptr - min_alloc_size == memory_block_base) {
allocated += min_alloc_size;
} else {
memory_block_base = (uint32_t)ptr;
allocated = min_alloc_size;
used = 0;
}
}

uint32_t addr = memory_block_base + used;
used += size;
return (void*)addr;
}

const char Pipe_File_Prefix[] = "SYS:pipe/";

uint32_t pipe(const char* name, uint32_t buf_size)
Expand Down
2 changes: 1 addition & 1 deletion sources/userspace/logger_task/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ int main(int argc, char** argv)
}

return 0;
}
}