Allocating Pages
This commit is contained in:
parent
5d9a3055b7
commit
582f4b720f
|
@ -7,39 +7,13 @@
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
#include <kernel/heap.h>
|
#include <kernel/heap.h>
|
||||||
|
|
||||||
struct x86_Page_Directory {
|
|
||||||
bool present: 1;
|
|
||||||
bool read_write: 1;
|
|
||||||
bool user_supervisor: 1;
|
|
||||||
bool write_through: 1;
|
|
||||||
bool cache_disable: 1;
|
|
||||||
bool accesed: 1;
|
|
||||||
bool available_2: 1;
|
|
||||||
bool page_size: 1;
|
|
||||||
uint8_t available_1 : 4;
|
|
||||||
uintptr_t address : 20; // Multiply by 0x1000
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct x86_Page_Table {
|
|
||||||
bool present: 1;
|
|
||||||
bool read_write: 1;
|
|
||||||
bool user_supervisor: 1;
|
|
||||||
bool write_through: 1;
|
|
||||||
bool cache_disable: 1;
|
|
||||||
bool accesed: 1;
|
|
||||||
bool dirty: 1;
|
|
||||||
bool page_attribute_table: 1;
|
|
||||||
bool global: 1;
|
|
||||||
uint8_t available_1 : 3;
|
|
||||||
uintptr_t address : 20; // Multiply by 0x1000
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
extern struct x86_Page_Directory boot_page_directory[1024] __attribute__((aligned(4096)));
|
extern struct x86_Page_Directory boot_page_directory[1024] __attribute__((aligned(4096)));
|
||||||
|
|
||||||
static struct x86_Page_Table user_code_table __attribute__((aligned(4096)));
|
static struct x86_Page_Table user_code_table[1024] __attribute__((aligned(4096)));
|
||||||
static uint8_t user_code[4096] __attribute__((aligned(4096)));
|
static uint8_t user_code[4096] __attribute__((aligned(4096)));
|
||||||
|
|
||||||
static struct x86_Page_Table user_data_table __attribute__((aligned(4096)));
|
|
||||||
|
static struct x86_Page_Table user_data_table[1024] __attribute__((aligned(4096)));
|
||||||
static uint8_t user_data[4096] __attribute__((aligned(4096)));
|
static uint8_t user_data[4096] __attribute__((aligned(4096)));
|
||||||
|
|
||||||
static struct x86_Page_Table* get_table(uint16_t index) {
|
static struct x86_Page_Table* get_table(uint16_t index) {
|
||||||
|
@ -54,13 +28,25 @@ movl %ecx, %cr3; \
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_page_directory_entry(uintptr_t address, struct x86_Page_Table* table) {
|
void set_page_directory_entry(uintptr_t address, struct x86_Page_Table* table)
|
||||||
|
{
|
||||||
boot_page_directory[address >> 22].address = ((uintptr_t)(table) - 0xC0000000) >> 12;
|
boot_page_directory[address >> 22].address = ((uintptr_t)(table) - 0xC0000000) >> 12;
|
||||||
boot_page_directory[address >> 22].present = true;
|
boot_page_directory[address >> 22].present = true;
|
||||||
boot_page_directory[address >> 22].read_write = true;
|
boot_page_directory[address >> 22].read_write = true;
|
||||||
boot_page_directory[address >> 22].user_supervisor = true;
|
boot_page_directory[address >> 22].user_supervisor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_page_table_entry(size_t address, void* ptr)
|
||||||
|
{
|
||||||
|
struct x86_Page_Table* table = (struct x86_Page_Table*)((boot_page_directory[address >> 22].address << 12) + 0xC0000000);
|
||||||
|
|
||||||
|
table[(address >> 12) & 0x3FF].address = (size_t)(ptr - 0xC0000000) >> 12;
|
||||||
|
table[(address >> 12) & 0x3FF].present = true;
|
||||||
|
table[(address >> 12) & 0x3FF].read_write = true;
|
||||||
|
table[(address >> 12) & 0x3FF].user_supervisor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct x86_Page_Table create_table;
|
||||||
|
|
||||||
void setup_paging() {
|
void setup_paging() {
|
||||||
struct x86_Page_Table* kernel = get_table(768);
|
struct x86_Page_Table* kernel = get_table(768);
|
||||||
|
@ -81,19 +67,21 @@ void setup_paging() {
|
||||||
|
|
||||||
set_page_directory_entry(0, &user_code_table);
|
set_page_directory_entry(0, &user_code_table);
|
||||||
|
|
||||||
|
/*
|
||||||
user_code_table.address = ((uintptr_t)user_code - 0xC0000000) >> 12;
|
user_code_table.address = ((uintptr_t)user_code - 0xC0000000) >> 12;
|
||||||
user_code_table.present = true;
|
user_code_table.present = true;
|
||||||
user_code_table.read_write = true;
|
user_code_table.read_write = true;
|
||||||
user_code_table.user_supervisor = true;
|
user_code_table.user_supervisor = true;
|
||||||
|
*/
|
||||||
|
|
||||||
set_page_directory_entry(0x00400000, &user_data_table);
|
set_page_directory_entry(0x00400000, &user_data_table);
|
||||||
|
|
||||||
|
/*
|
||||||
user_data_table.address = ((uintptr_t)user_data - 0xC0000000) >> 12;
|
user_data_table.address = ((uintptr_t)user_data - 0xC0000000) >> 12;
|
||||||
user_data_table.present = true;
|
user_data_table.present = true;
|
||||||
user_data_table.read_write = true;
|
user_data_table.read_write = true;
|
||||||
user_data_table.user_supervisor = true;
|
user_data_table.user_supervisor = true;
|
||||||
|
*/
|
||||||
user_data[0] = 'B';
|
|
||||||
|
|
||||||
reload_pages();
|
reload_pages();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,4 +18,6 @@ struct Heap_Block {
|
||||||
|
|
||||||
void heap_init();
|
void heap_init();
|
||||||
void* malloc(size_t size);
|
void* malloc(size_t size);
|
||||||
|
void* alloc_page(size_t num_pages, struct Heap_Block** ptr);
|
||||||
void free(void *ptr);
|
void free(void *ptr);
|
||||||
|
void free_page(struct Heap_Block *ptr);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
struct PageDirectory {
|
struct PageDirectory {
|
||||||
size_t page_table;
|
size_t page_table;
|
||||||
|
@ -8,4 +10,33 @@ struct PageTable {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct x86_Page_Directory {
|
||||||
|
bool present: 1;
|
||||||
|
bool read_write: 1;
|
||||||
|
bool user_supervisor: 1;
|
||||||
|
bool write_through: 1;
|
||||||
|
bool cache_disable: 1;
|
||||||
|
bool accesed: 1;
|
||||||
|
bool available_2: 1;
|
||||||
|
bool page_size: 1;
|
||||||
|
uint8_t available_1 : 4;
|
||||||
|
uintptr_t address : 20; // Multiply by 0x1000
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct x86_Page_Table {
|
||||||
|
bool present: 1;
|
||||||
|
bool read_write: 1;
|
||||||
|
bool user_supervisor: 1;
|
||||||
|
bool write_through: 1;
|
||||||
|
bool cache_disable: 1;
|
||||||
|
bool accesed: 1;
|
||||||
|
bool dirty: 1;
|
||||||
|
bool page_attribute_table: 1;
|
||||||
|
bool global: 1;
|
||||||
|
uint8_t available_1 : 3;
|
||||||
|
uintptr_t address : 20; // Multiply by 0x1000
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
void setup_paging();
|
void setup_paging();
|
||||||
|
void set_page_table_entry(size_t address, void* ptr);
|
||||||
|
void set_page_directory_entry(uintptr_t address, struct x86_Page_Table* table);
|
||||||
|
|
|
@ -16,7 +16,8 @@ static void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t s
|
||||||
|
|
||||||
void run_program(uint8_t* code, size_t code_length, uint8_t* data, size_t data_length)
|
void run_program(uint8_t* code, size_t code_length, uint8_t* data, size_t data_length)
|
||||||
{
|
{
|
||||||
uint8_t* userland_code = (uint8_t*) 0x00000010;
|
// TODO: Replace following lines with malloc calls and paging calls
|
||||||
|
uint8_t* userland_code = (uint8_t*) 0x00000000;
|
||||||
uint8_t* userland_data = (uint8_t*) 0x00400000;
|
uint8_t* userland_data = (uint8_t*) 0x00400000;
|
||||||
|
|
||||||
memcpy(userland_code, code, code_length);
|
memcpy(userland_code, code, code_length);
|
||||||
|
|
129
kernel/heap.c
129
kernel/heap.c
|
@ -1,12 +1,50 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <kernel/heap.h>
|
#include <kernel/heap.h>
|
||||||
|
#include <kernel/tty.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
|
|
||||||
#define HEAP_SIZE (1 << 12)
|
#define HEAP_SIZE (1 << 16)
|
||||||
|
#define NUM_PAGES (128)
|
||||||
|
|
||||||
|
uint8_t global_heap_data[HEAP_SIZE + sizeof(struct Heap_Block)];
|
||||||
|
uint8_t pages_heap_data[NUM_PAGES * 4096 + sizeof(struct Heap_Block)] __attribute__((aligned(4096)));
|
||||||
|
|
||||||
|
struct Heap_Block pages_heap_blocks[NUM_PAGES];
|
||||||
|
|
||||||
uint8_t* global_heap_data[HEAP_SIZE + sizeof(struct Heap_Block)];
|
|
||||||
struct Heap_Metadata global_heap;
|
struct Heap_Metadata global_heap;
|
||||||
|
struct Heap_Metadata pages_heap;
|
||||||
|
|
||||||
|
void* nearest_aligned(void* ptr, size_t alignment)
|
||||||
|
{
|
||||||
|
// TODO: Fix this solution up, it's *extremely* inneficient for numbers that aren't powers of 2
|
||||||
|
|
||||||
|
size_t address = (size_t)ptr;
|
||||||
|
|
||||||
|
if (address % alignment == 0) {
|
||||||
|
return (void*) address;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((alignment & (alignment - 1)) == 0) {
|
||||||
|
address = address & ~(alignment - 1);
|
||||||
|
address += alignment;
|
||||||
|
return (void*) address;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (address % alignment != 0) {
|
||||||
|
address++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void*) address;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sizeof_block(struct Heap_Block* block, size_t alignment)
|
||||||
|
{
|
||||||
|
size_t start = (size_t)nearest_aligned(block->data, alignment);
|
||||||
|
size_t end = (size_t)block->next;
|
||||||
|
|
||||||
|
return end - start;
|
||||||
|
}
|
||||||
|
|
||||||
void heap_init()
|
void heap_init()
|
||||||
{
|
{
|
||||||
|
@ -18,6 +56,16 @@ void heap_init()
|
||||||
start->used = false;
|
start->used = false;
|
||||||
start->data = start + 1;
|
start->data = start + 1;
|
||||||
start->next = 0;
|
start->next = 0;
|
||||||
|
|
||||||
|
struct Heap_Block* page_start = pages_heap_blocks;
|
||||||
|
|
||||||
|
pages_heap.size = NUM_PAGES;
|
||||||
|
pages_heap.start = (struct Heap_Block*) page_start;
|
||||||
|
|
||||||
|
page_start->size = NUM_PAGES;
|
||||||
|
page_start->used = false;
|
||||||
|
page_start->data = pages_heap_data;
|
||||||
|
page_start->next = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* malloc(size_t size)
|
void* malloc(size_t size)
|
||||||
|
@ -31,6 +79,7 @@ void* malloc(size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current == 0) {
|
if (current == 0) {
|
||||||
|
terminal_writestring("WARNING: Heap Full\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +97,43 @@ void* malloc(size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* alloc_page(size_t num_pages, struct Heap_Block** ptr)
|
||||||
|
{
|
||||||
|
struct Heap_Block* current = pages_heap.start;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (current->used || current->size < num_pages) {
|
||||||
|
current = current->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current == 0) {
|
||||||
|
terminal_writestring("WARNING: Heap Full\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size_t)current->data % 4096 != 0) {
|
||||||
|
terminal_writestring("ERROR: Pages are unaligned");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t current_index = ((size_t)current->data - (size_t)pages_heap_data) / 4096;
|
||||||
|
|
||||||
|
struct Heap_Block* next = pages_heap_blocks + (current_index + num_pages);
|
||||||
|
|
||||||
|
next->data = current->data + 4096 * num_pages;
|
||||||
|
next->next = current->next;
|
||||||
|
next->size = current->size - num_pages;
|
||||||
|
|
||||||
|
current->next = next;
|
||||||
|
current->size = num_pages;
|
||||||
|
current->used = true;
|
||||||
|
|
||||||
|
*ptr = current;
|
||||||
|
|
||||||
|
return current->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void free(void *ptr)
|
void free(void *ptr)
|
||||||
{
|
{
|
||||||
struct Heap_Block* current = global_heap.start;
|
struct Heap_Block* current = global_heap.start;
|
||||||
|
@ -83,6 +169,43 @@ void free(void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
start->next = current;
|
start->next = current;
|
||||||
start->size = (uint32_t)start->next - (uint32_t)start->data;
|
start->size = (size_t)start->next - (size_t)start->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_page(struct Heap_Block *ptr)
|
||||||
|
{
|
||||||
|
struct Heap_Block* current = pages_heap.start;
|
||||||
|
|
||||||
|
struct Heap_Block* first_unused;
|
||||||
|
bool found_unused = false;
|
||||||
|
|
||||||
|
while (current != ptr) {
|
||||||
|
if (!current->used && !found_unused) {
|
||||||
|
first_unused = current;
|
||||||
|
found_unused = true;
|
||||||
|
} else {
|
||||||
|
found_unused = false;
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_unused) {
|
||||||
|
first_unused = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
current->used = false;
|
||||||
|
|
||||||
|
if (current->next == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Heap_Block* start = first_unused;
|
||||||
|
current = start;
|
||||||
|
|
||||||
|
while (current->used == false && current->next != 0) {
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
start->next = current;
|
||||||
|
start->size = ((size_t)start->next - (size_t)start->data) / 4096;
|
||||||
|
}
|
||||||
|
|
|
@ -23,8 +23,6 @@ uint8_t data[] = "Hello From Userspace\n";
|
||||||
uint8_t kernel_data[] = "Hello From Kernelspace\n";
|
uint8_t kernel_data[] = "Hello From Kernelspace\n";
|
||||||
// uint8_t data[] = {};
|
// uint8_t data[] = {};
|
||||||
|
|
||||||
void irq0();
|
|
||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
/* Initialize terminal interface */
|
/* Initialize terminal interface */
|
||||||
|
@ -40,7 +38,18 @@ void kernel_main(void)
|
||||||
|
|
||||||
terminal_writestring("Woaw\n");
|
terminal_writestring("Woaw\n");
|
||||||
|
|
||||||
asm("cli");
|
struct Heap_Block* block;
|
||||||
|
void* code_page = alloc_page(1, &block);
|
||||||
|
void* data_page = alloc_page(1, &block);
|
||||||
|
|
||||||
|
set_page_table_entry(0, code_page);
|
||||||
|
set_page_table_entry(0x00400000, data_page);
|
||||||
|
|
||||||
|
*(int*)0 = 1;
|
||||||
|
|
||||||
|
while (true) { }
|
||||||
|
|
||||||
|
/* asm("cli");
|
||||||
|
|
||||||
run_program(program, sizeof(program), data, sizeof(data));
|
run_program(program, sizeof(program), data, sizeof(data));
|
||||||
|
|
||||||
|
@ -56,5 +65,5 @@ void kernel_main(void)
|
||||||
asm("int $0x80");
|
asm("int $0x80");
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue