wip: separate allocators into a kernel one and a user one
This commit is contained in:
@ -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);
|
||||
|
||||
@ -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++;
|
||||
|
||||
@ -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(); */
|
||||
|
||||
@ -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;
|
||||
@ -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
92
src/memory/kern/page.c
Normal 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;
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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++)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user