wip: separate allocators into a kernel one and a user one

This commit is contained in:
0x35c
2025-11-12 16:02:52 +01:00
parent a776a45f68
commit 9f142941c3
22 changed files with 149 additions and 56 deletions

View File

@ -59,8 +59,10 @@ void init_memory(multiboot_info_t *mbd, uint32_t magic);
void *alloc_frame(void);
int free_frame(void *frame_ptr);
int8_t add_single_page(void *frame);
void *alloc_pages(size_t size, void **phys_addr);
int free_pages(void *page_ptr, size_t size);
void *kalloc_pages(size_t size, void **phys_addr);
void *valloc_pages(size_t size, void **phys_addr);
int kfree_pages(void *page_ptr, size_t size);
int vfree_pages(void *page_ptr, size_t size);
void init_page_table(uint32_t page_table[1024], uint16_t start);
int16_t add_page_table(uint16_t pd_index);
void switch_pd(uint32_t *pd, uint32_t *cr3);

View File

@ -36,8 +36,6 @@ void isr_handler(struct registers *regs)
{
uint8_t i = 0;
while (i < ARRAY_SIZE(faults)) {
if (i == 6)
reboot();
if (i == regs->int_no)
kpanic("interrupt: %s\n", faults[i]);
i++;

View File

@ -23,10 +23,10 @@ __attribute__((noreturn)) void kpanic(const char *format, ...)
va_end(va);
uint32_t faulting_address;
// __asm__ __volatile__("mov %%cr2, %0" : "=r"(faulting_address));
// kprintf("fault at address: %p\n", faulting_address);
/* for (int i = 16; i < 32; i++) */
/* kprintf("%p\n", page_table1[i]); */
__asm__ __volatile__("mov %%cr2, %0" : "=r"(faulting_address));
kprintf("fault at address: %p\n", faulting_address);
// for (int i = 16; i < 32; i++)
// kprintf("%p\n", page_table1[i]);
// show_valloc_mem();
/* kprintf("\n\n"); */
/* print_stack(); */

View File

@ -1,9 +1,8 @@
#include "alloc.h"
#include "assert.h"
#include "kpanic.h"
#include "kprintf.h"
#include "memory.h"
#include "process.h"
#include "string.h"
Zone *kzones[3];
@ -50,11 +49,12 @@ static void new_block(Zone *zone, uint32_t zone_size)
int new_kzone(block_type_t type, uint32_t size)
{
// assert(current_task->pid);
void *heap = alloc_frame();
void *heap = kalloc_pages(size, NULL);
if (heap == NULL) {
kprintf(KERN_ERR "error: alloc_frame failed\n");
return (-1);
}
memset(heap, 0, size);
Zone *zone = (Zone *)heap;
zone->type = type;

View File

@ -47,7 +47,7 @@ static int unmap_zone(Zone *zone)
if (right)
right->prev = left;
unmap:
err = free_pages((void *)zone, zone->size);
err = kfree_pages((void *)zone, zone->size);
if (err)
kprintf(KERN_ERR "error: munmap failed\n");
return (err);

92
src/memory/kern/page.c Normal file
View File

@ -0,0 +1,92 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "assert.h"
#include "kprintf.h"
#include "memory.h"
#include "process.h"
#include "string.h"
#include "utils.h"
static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr,
uint32_t **page_table_ptr)
{
for (*pd_index_ptr = 769; *pd_index_ptr < 1021; (*pd_index_ptr)++) {
if (current_pd[(*pd_index_ptr)] == 0x02) {
if (add_page_table(*pd_index_ptr) < 0)
return -2;
}
*page_table_ptr = (uint32_t *)GET_PAGE_ADDR(769, *pd_index_ptr);
for (uint16_t i = 0; i + nb_pages - 1 < PT_SIZE; i++) {
uint16_t j;
for (j = 0; (*page_table_ptr)[i + j] >> 12 == i + j &&
j < nb_pages;
j++)
;
if (j == nb_pages)
return i;
i += j;
}
}
return -1;
}
void *kalloc_pages(size_t size, void **phys_addr)
{
const uint32_t nb_pages = CEIL(size, PAGE_SIZE);
uint16_t pd_index;
uint32_t *page_table;
const int16_t index = find_next_block(nb_pages, &pd_index, &page_table);
if (index < 0) {
kprintf(KERN_CRIT "%d: Not enough pages (max: %d)\n", index,
PT_SIZE);
return NULL;
}
for (size_t i = index; i - (size_t)index < nb_pages; i++) {
void *frame = alloc_frame();
if (!frame) {
for (size_t j = index; j < i; j++)
free_frame((void *)(page_table[j] & PAGE_MASK));
return NULL;
}
if (phys_addr)
*phys_addr = frame;
page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS;
}
return (void *)GET_PAGE_ADDR(pd_index, index);
}
int kfree_pages(void *page_ptr, size_t size)
{
const uint32_t page_addr = (uint32_t)page_ptr;
const uint32_t nb_pages = CEIL(size, PAGE_SIZE);
const uint32_t page_index = page_addr / PAGE_SIZE;
const uint32_t pd_index = page_index / PD_SIZE;
const uint32_t pt_index = page_index % PD_SIZE;
if ((uint32_t)pd_index > 0x300) {
kprintf(KERN_WARNING "Address out of range\n");
return -1;
} else if (page_addr % PAGE_SIZE) {
kprintf(KERN_WARNING "Invalid address\n");
return -1;
} else if (pt_index + nb_pages > PT_SIZE) {
kprintf(KERN_WARNING "Invalid number of frames\n");
return -1;
}
uint32_t *page_table =
(uint32_t *)GET_PAGE_ADDR(0, PT_START + pd_index);
for (uint16_t i = pt_index; i < pt_index + nb_pages; i++) {
if (page_table[i] >> 12 == i) {
kprintf(KERN_WARNING "Page already free\n");
return -2;
}
free_frame((void *)(page_table[i] & PAGE_MASK));
page_table[i] = i << 12;
}
return 0;
}

View File

@ -1,12 +1,13 @@
.intel_syntax noprefix
.text
.global load_page_directory
.section .text
.global load_page_directory
load_page_directory:
push ebp
mov ebp, esp
mov eax, [esp + 8]
mov cr3, eax
mov esp, ebp
pop ebp
ret
push ebp
mov ebp, esp
mov eax, [esp + 8]
mov cr3, eax
mov esp, ebp
pop ebp
ret

View File

@ -113,7 +113,7 @@ static void init_frame_zones(void)
void init_memory(multiboot_info_t *mbd, uint32_t magic)
{
for (uint16_t i = 0; i < 0x300; i++)
for (uint16_t i = 769; i < 1021; i++)
kernel_pd[i] = 0x02;
init_page_table(page_table_default, 0);
kernel_pd[0] = ((uint32_t)page_table_default - HEAP_END) | 0x03;

View File

@ -4,4 +4,4 @@ void init_page_directory(uint32_t page_directory[1024])
{
for (uint16_t i = 0; i < 0x300; i++)
page_directory[i] = 0x02;
}
}

View File

@ -1,6 +1,5 @@
#include "assert.h"
#include "kprintf.h"
#include "memory.h"
void init_page_table(uint32_t page_table[1024], uint16_t start)
{
for (uint16_t i = start; i < 1024; i++)

View File

@ -1,13 +1,14 @@
.intel_syntax noprefix
.text
.global enable_paging
.section .text
.global enable_paging
enable_paging:
push ebp
mov ebp, esp
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
mov esp, ebp
pop ebp
ret
push ebp
mov ebp, esp
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
mov esp, ebp
pop ebp
ret

View File

@ -3,7 +3,7 @@
#include "kpanic.h"
#include "kprintf.h"
#include "memory.h"
#include "process.h"
#include "string.h"
Zone *vzones[3];
@ -50,11 +50,12 @@ static void new_block(Zone *zone, uint32_t zone_size)
int new_vzone(block_type_t type, uint32_t size)
{
// assert(current_task->pid);
void *heap = alloc_pages(size, NULL);
void *heap = valloc_pages(size, NULL);
if (heap == NULL) {
kprintf(KERN_ERR "error: alloc_pages failed\n");
return (-1);
}
memset(heap, 0, size);
Zone *zone = (Zone *)heap;
zone->type = type;

View File

@ -33,7 +33,7 @@ static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr,
return -1;
}
void *alloc_pages(size_t size, void **phys_addr)
void *valloc_pages(size_t size, void **phys_addr)
{
const uint32_t nb_pages = CEIL(size, PAGE_SIZE);
uint16_t pd_index;
@ -56,11 +56,10 @@ void *alloc_pages(size_t size, void **phys_addr)
*phys_addr = frame;
page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS;
}
memset((void *)GET_PAGE_ADDR(pd_index, index), 0, nb_pages * PAGE_SIZE);
return (void *)GET_PAGE_ADDR(pd_index, index);
}
int free_pages(void *page_ptr, size_t size)
int vfree_pages(void *page_ptr, size_t size)
{
const uint32_t page_addr = (uint32_t)page_ptr;
const uint32_t nb_pages = CEIL(size, PAGE_SIZE);

View File

@ -47,7 +47,7 @@ static int unmap_zone(Zone *zone)
if (right)
right->prev = left;
unmap:
err = free_pages((void *)zone, zone->size);
err = vfree_pages((void *)zone, zone->size);
if (err)
kprintf(KERN_ERR "error: munmap failed\n");
return (err);

View File

@ -38,8 +38,8 @@ static void init_vbe(multiboot_info_t *mbd_virt)
((mbd_virt->framebuffer_addr + i * PAGE_SIZE) & PAGE_MASK) |
INIT_FLAGS;
}
kernel_pd[800] = ((uint32_t)vbe_page_table - HEAP_END) | 0x03;
display.buff = (uint32_t *)GET_PAGE_ADDR(800, 0) +
kernel_pd[1021] = ((uint32_t)vbe_page_table - HEAP_END) | 0x03;
display.buff = (uint32_t *)GET_PAGE_ADDR(1021, 0) +
(mbd_virt->framebuffer_addr % PAGE_SIZE);
display.height = mbd_virt->framebuffer_height;
display.width = mbd_virt->framebuffer_width;

View File

@ -10,7 +10,7 @@ static struct tcb *thread_clone(struct tcb *thread)
if (!new_tcb)
return NULL;
new_tcb->tid = thread->tid;
new_tcb->esp0 = alloc_pages(STACK_SIZE, NULL);
new_tcb->esp0 = kalloc_pages(STACK_SIZE, NULL);
if (!new_tcb->esp0) {
delete_thread(new_tcb);
return NULL;

View File

@ -9,16 +9,16 @@
struct pcb *create_process(uid_t uid)
{
static pid_t pid = 1;
struct pcb *new_pcb = vmalloc(sizeof(struct pcb));
struct pcb *new_pcb = kmalloc(sizeof(struct pcb));
if (!new_pcb)
return NULL;
new_pcb->uid = uid;
new_pcb->pid = pid++;
new_pcb->tid = 1;
new_pcb->heap = alloc_pages(4096, &new_pcb->cr3);
new_pcb->heap = kalloc_pages(4096, &new_pcb->cr3);
if (!new_pcb->heap) {
vfree(new_pcb);
kfree(new_pcb);
return NULL;
}
memcpy(new_pcb->heap, current_pd, 4096);
@ -48,8 +48,8 @@ void remove_process(struct pcb *pcb)
struct pcb *left = pcb->prev;
struct pcb *right = pcb->next;
if (pcb->heap)
free_pages(pcb->heap, 4096);
kfree_pages(pcb->heap, 4096);
left->next = right;
right->prev = left;
vfree(pcb);
kfree(pcb);
}

View File

@ -10,12 +10,12 @@
struct tcb *create_thread(struct pcb *process, void (*entry)(void))
{
struct tcb *new_tcb = vmalloc(sizeof(struct tcb));
struct tcb *new_tcb = kmalloc(sizeof(struct tcb));
if (!new_tcb)
return NULL;
new_tcb->tid = process->tid++;
new_tcb->esp0 = alloc_pages(STACK_SIZE, NULL);
new_tcb->esp0 = kalloc_pages(STACK_SIZE, NULL);
if (!new_tcb->esp0) {
vfree(new_tcb);
return NULL;
@ -46,9 +46,9 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void))
new_tcb->process = process;
new_tcb->state = NEW;
struct list *new_node = vmalloc(sizeof(struct list));
struct list *new_node = kmalloc(sizeof(struct list));
if (!new_node) {
free_pages(new_tcb->esp0, STACK_SIZE);
kfree_pages(new_tcb->esp0, STACK_SIZE);
vfree(new_tcb);
return NULL;
}
@ -68,13 +68,13 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void))
void delete_thread(struct tcb *thread)
{
vfree(thread->esp0);
kfree(thread->esp0);
struct list *it = thread->process->thread_list;
assert(it);
while (it->next && it->next->content != thread)
it = it->next;
struct list *to_free = it;
it->next = it->next->next;
vfree(to_free);
vfree(thread);
kfree(to_free);
kfree(thread);
}