Skip to content

Commit cde0cf6

Browse files
Add PMM
1 parent 0347dab commit cde0cf6

File tree

3 files changed

+103
-1
lines changed

3 files changed

+103
-1
lines changed

kernel/kernel.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
21
#include "libc/stdio.h"
2+
#include "pmm.h"
33
#include "printf/printf_support.h"
44
#include "terminal/terminal.h"
55
#include <limine.h>
@@ -15,6 +15,12 @@ static volatile struct limine_entry_point_request entry_request = {
1515
.entry = entry,
1616
};
1717

18+
struct limine_memmap_request limine_memmap_request = {
19+
.id = LIMINE_MEMMAP_REQUEST,
20+
.revision = 0,
21+
.response = NULL,
22+
};
23+
1824
static void hcf(void)
1925
{
2026
asm("cli");
@@ -43,6 +49,11 @@ void entry(void)
4349

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

52+
pmm_t pmm;
53+
pmm_init(&pmm, limine_memmap_request.response);
54+
void* page = pmm_alloc_pages(&pmm, 1);
55+
printf("ALLOCATED PAGE: %p\n", page);
56+
4657
cleanup:
4758
hcf();
4859
}

kernel/pmm.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include "pmm.h"
2+
3+
#include "utility/macro.h"
4+
5+
void pmm_init(pmm_t* pmm, struct limine_memmap_response* limine_memmap)
6+
{
7+
pmm_node_t* current = NULL;
8+
9+
for (size_t i = 0; i < limine_memmap->entry_count; i++) {
10+
struct limine_memmap_entry* entry = limine_memmap->entries[i];
11+
if (LIMINE_MEMMAP_USABLE == entry->type) {
12+
pmm_node_t node = { .next = NULL,
13+
.prev = current,
14+
.base = (void*)(entry->base + PAGE_SIZE),
15+
.no_pages = (entry->length / PAGE_SIZE) - 1,
16+
.kind = PMM_NOT_ALLOCATED };
17+
pmm_node_t* node_ptr = (void*)entry->base;
18+
*node_ptr = node;
19+
20+
if (NULL == current) {
21+
pmm->first_node = node_ptr;
22+
} else {
23+
current->next = node_ptr;
24+
}
25+
current = node_ptr;
26+
}
27+
}
28+
}
29+
30+
void* pmm_alloc_pages(pmm_t* pmm, size_t no_pages)
31+
{
32+
pmm_node_t* current = pmm->first_node;
33+
34+
while (NULL != current) {
35+
if ((PMM_NOT_ALLOCATED == current->kind)
36+
&& (current->no_pages >= no_pages)) {
37+
break;
38+
}
39+
40+
current = current->next;
41+
}
42+
43+
if (NULL == current) {
44+
return NULL;
45+
}
46+
47+
size_t leftover_pages = current->no_pages - no_pages;
48+
if (0 == leftover_pages) {
49+
current->kind = PMM_ALLOCATED;
50+
return current->base;
51+
}
52+
53+
pmm_node_t* new_node = // may has bug
54+
add_pointer(pmm_node_t*, current->base, no_pages * PAGE_SIZE);
55+
56+
new_node->next = current->next;
57+
new_node->prev = current;
58+
new_node->base = add_pointer(void*, new_node->base, PAGE_SIZE);
59+
new_node->no_pages = leftover_pages - 1;
60+
new_node->kind = PMM_NOT_ALLOCATED;
61+
62+
current->next = new_node;
63+
current->no_pages = no_pages;
64+
current->kind = PMM_ALLOCATED;
65+
66+
return current->base;
67+
}

kernel/pmm.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <limine.h>
2+
#include <stddef.h>
3+
4+
#define PAGE_SIZE ((size_t)0x1000)
5+
6+
typedef enum {
7+
PMM_NOT_ALLOCATED,
8+
PMM_ALLOCATED,
9+
} pmm_node_kind_t;
10+
11+
typedef struct pmm_node_t {
12+
struct pmm_node_t* next;
13+
struct pmm_node_t* prev;
14+
void* base;
15+
size_t no_pages;
16+
pmm_node_kind_t kind;
17+
} pmm_node_t;
18+
19+
typedef struct {
20+
pmm_node_t* first_node;
21+
} pmm_t;
22+
23+
void pmm_init(pmm_t* pmm, struct limine_memmap_response* limine_memmap);
24+
void* pmm_alloc_pages(pmm_t* pmm, size_t no_pages);

0 commit comments

Comments
 (0)