Skip to content

Commit 4f9bc9c

Browse files
Add PMM
1 parent ddc14c8 commit 4f9bc9c

File tree

3 files changed

+100
-1
lines changed

3 files changed

+100
-1
lines changed

kernel/kernel.c

Lines changed: 10 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,9 @@ void entry(void)
4349

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

52+
pmm_t pmm;
53+
pmm_init(&pmm, limine_memmap_request.response);
54+
4655
cleanup:
4756
hcf();
4857
}

kernel/pmm.c

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

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)