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
13 changes: 12 additions & 1 deletion kernel/kernel.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

#include "libc/stdio.h"
#include "pmm.h"
#include "printf/printf_support.h"
#include "terminal/terminal.h"
#include <limine.h>
Expand All @@ -15,6 +15,12 @@ static volatile struct limine_entry_point_request entry_request = {
.entry = entry,
};

struct limine_memmap_request limine_memmap_request = {
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0,
.response = NULL,
};

static void hcf(void)
{
asm("cli");
Expand Down Expand Up @@ -43,6 +49,11 @@ void entry(void)

printf("Hello Kernel Mode!\n");

pmm_t pmm;
pmm_init(&pmm, limine_memmap_request.response);
void* page = pmm_alloc_pages(&pmm, 1);
printf("ALLOCATED PAGE: %p\n", page);

cleanup:
hcf();
}
67 changes: 67 additions & 0 deletions kernel/pmm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "pmm.h"

#include "utility/macro.h"

void pmm_init(pmm_t* pmm, struct limine_memmap_response* limine_memmap)
{
pmm_node_t* current = NULL;

for (size_t i = 0; i < limine_memmap->entry_count; i++) {
struct limine_memmap_entry* entry = limine_memmap->entries[i];
if (LIMINE_MEMMAP_USABLE == entry->type) {
pmm_node_t node = { .next = NULL,
.prev = current,
.base = (void*)(entry->base + PAGE_SIZE),
.no_pages = (entry->length / PAGE_SIZE) - 1,
.kind = PMM_NOT_ALLOCATED };
pmm_node_t* node_ptr = (void*)entry->base;
*node_ptr = node;

if (NULL == current) {
pmm->first_node = node_ptr;
} else {
current->next = node_ptr;
}
current = node_ptr;
}
}
}

void* pmm_alloc_pages(pmm_t* pmm, size_t no_pages)
{
pmm_node_t* current = pmm->first_node;

while (NULL != current) {
if ((PMM_NOT_ALLOCATED == current->kind)
&& (current->no_pages >= no_pages)) {
break;
}

current = current->next;
}

if (NULL == current) {
return NULL;
}

size_t leftover_pages = current->no_pages - no_pages;
if (0 == leftover_pages) {
current->kind = PMM_ALLOCATED;
return current->base;
}

pmm_node_t* new_node = // may has bug
add_pointer(pmm_node_t*, current->base, no_pages * PAGE_SIZE);

new_node->next = current->next;
new_node->prev = current;
new_node->base = add_pointer(void*, new_node->base, PAGE_SIZE);
new_node->no_pages = leftover_pages - 1;
new_node->kind = PMM_NOT_ALLOCATED;

current->next = new_node;
current->no_pages = no_pages;
current->kind = PMM_ALLOCATED;

return current->base;
}
24 changes: 24 additions & 0 deletions kernel/pmm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <limine.h>
#include <stddef.h>

#define PAGE_SIZE ((size_t)0x1000)

typedef enum {
PMM_NOT_ALLOCATED,
PMM_ALLOCATED,
} pmm_node_kind_t;

typedef struct pmm_node_t {
struct pmm_node_t* next;
struct pmm_node_t* prev;
void* base;
size_t no_pages;
pmm_node_kind_t kind;
} pmm_node_t;

typedef struct {
pmm_node_t* first_node;
} pmm_t;

void pmm_init(pmm_t* pmm, struct limine_memmap_response* limine_memmap);
void* pmm_alloc_pages(pmm_t* pmm, size_t no_pages);