wip: memory change
This commit is contained in:
parent
9e85807a09
commit
7128f2640a
@ -8,12 +8,10 @@
|
|||||||
|
|
||||||
// Remove this and replace it with <assert.h> header
|
// Remove this and replace it with <assert.h> header
|
||||||
// for debugging purposes
|
// for debugging purposes
|
||||||
/* #include <assert.h> */
|
|
||||||
#define assert(bool)
|
|
||||||
|
|
||||||
// BPZ = Blocks Per Zone, which is the max
|
// BPZ = Blocks Per Zone, which is the max
|
||||||
// number of blocks for a new zone
|
// number of blocks for a new zone
|
||||||
enum { BPZ = 128, PAGES_TINY = 16, PAGES_SMALL = 64, MEM_ALIGN = 8 };
|
enum { BPZ = 128, PAGES_TINY = 16, PAGES_SMALL = 64, MEM_ALIGN = 4 };
|
||||||
|
|
||||||
typedef enum { TINY, SMALL, LARGE } block_type_t;
|
typedef enum { TINY, SMALL, LARGE } block_type_t;
|
||||||
|
|
||||||
@ -34,7 +32,6 @@ typedef enum { TINY, SMALL, LARGE } block_type_t;
|
|||||||
* available blocks (Block *free in struct Zone)
|
* available blocks (Block *free in struct Zone)
|
||||||
*/
|
*/
|
||||||
typedef struct Block {
|
typedef struct Block {
|
||||||
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t sub_size;
|
size_t sub_size;
|
||||||
@ -54,12 +51,12 @@ typedef struct Block {
|
|||||||
* in_use
|
* in_use
|
||||||
*/
|
*/
|
||||||
typedef struct Zone {
|
typedef struct Zone {
|
||||||
|
Block *free;
|
||||||
|
Block *used;
|
||||||
size_t size;
|
size_t size;
|
||||||
struct Zone *prev;
|
struct Zone *prev;
|
||||||
struct Zone *next;
|
struct Zone *next;
|
||||||
block_type_t type;
|
block_type_t type;
|
||||||
Block *free;
|
|
||||||
Block *used;
|
|
||||||
} Zone;
|
} Zone;
|
||||||
|
|
||||||
/* Linked list to store all the zones (pages) mapped.
|
/* Linked list to store all the zones (pages) mapped.
|
||||||
@ -89,5 +86,5 @@ void vfree(void *ptr);
|
|||||||
void *vrealloc(void *ptr, size_t size);
|
void *vrealloc(void *ptr, size_t size);
|
||||||
void show_kalloc_mem(void);
|
void show_kalloc_mem(void);
|
||||||
void show_valloc_mem(void);
|
void show_valloc_mem(void);
|
||||||
size_t ksize(void* virt_addr);
|
size_t ksize(void *virt_addr);
|
||||||
size_t vsize(void* virt_addr);
|
size_t vsize(void *virt_addr);
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "kpanic.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define PRINT_VAR(var) kprintf("%s: %d\n", #var, var)
|
#define PRINT_PTR(X) kprintf("%s: %p\n", #X, X)
|
||||||
|
#define PRINT_INT(X) kprintf("%s: %d\n", #X, X)
|
||||||
|
#define assert(X) \
|
||||||
|
do { \
|
||||||
|
if (!(X)) { \
|
||||||
|
kpanic("ASSERT_FAIL %s:%u %s\n", __FILE__, __LINE__, \
|
||||||
|
#X); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
struct function_entry {
|
struct function_entry {
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void kpanic(const char *format, ...);
|
void kpanic(const char *format, ...);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#define ACCESSED (1 << 4)
|
#define ACCESSED (1 << 4)
|
||||||
#define INIT_FLAGS (PRESENT | RW | SUPERVISOR)
|
#define INIT_FLAGS (PRESENT | RW | SUPERVISOR)
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096
|
||||||
#define KERN_START 0xC0000000
|
#define HEAP_END 0xC0000000
|
||||||
|
|
||||||
void init_memory(void);
|
void init_memory(void);
|
||||||
void *alloc_frames(size_t size);
|
void *alloc_frames(size_t size);
|
||||||
|
@ -31,13 +31,13 @@ void kernel_main(void)
|
|||||||
init_idt();
|
init_idt();
|
||||||
init_memory();
|
init_memory();
|
||||||
load_drivers();
|
load_drivers();
|
||||||
memset((void *)0x10001, 'a', 10);
|
|
||||||
kprintf(KERN_ALERT
|
kprintf(KERN_ALERT
|
||||||
"I see no way to confuse an array of 256 seg:off pairs with a "
|
"I see no way to confuse an array of 256 seg:off pairs with a "
|
||||||
"complex 8*unknown quantity -byte descriptor table. -- Troy "
|
"complex 8*unknown quantity -byte descriptor table. -- Troy "
|
||||||
"Martin 03:50, 22 March 2009 (UTC)\n");
|
"Martin 03:50, 22 March 2009 (UTC)\n");
|
||||||
/* vmalloc(10); */
|
/* kprintf("%p\n", vmalloc(10)); */
|
||||||
/* while (!vmalloc(10)) */
|
int i = 0;
|
||||||
/* ; */
|
while (vmalloc(10))
|
||||||
|
kprintf("%d\n", i++);
|
||||||
shell_init();
|
shell_init();
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
#include "alloc.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
|
#include "memory.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
||||||
|
extern uint32_t page_table1[1024];
|
||||||
|
|
||||||
void kpanic(const char *format, ...)
|
void kpanic(const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
@ -16,6 +20,9 @@ void kpanic(const char *format, ...)
|
|||||||
uint32_t faulting_address;
|
uint32_t faulting_address;
|
||||||
__asm__ __volatile__("mov %%cr2, %0" : "=r"(faulting_address));
|
__asm__ __volatile__("mov %%cr2, %0" : "=r"(faulting_address));
|
||||||
kprintf("fault at address: %p\n", 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"); */
|
/* kprintf("\n\n"); */
|
||||||
/* print_stack(); */
|
/* print_stack(); */
|
||||||
/* kprintf("\n\n"); */
|
/* kprintf("\n\n"); */
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#define MAX_FRAMES (0xC0000000 / PAGE_SIZE)
|
#define MAX_FRAMES (HEAP_END / PAGE_SIZE)
|
||||||
|
|
||||||
static uint8_t frame_table[MAX_FRAMES];
|
static uint8_t frame_table[MAX_FRAMES];
|
||||||
static uint32_t remaining_frames = MAX_FRAMES;
|
static uint32_t remaining_frames = MAX_FRAMES;
|
||||||
@ -37,16 +38,19 @@ void *alloc_frames(size_t size)
|
|||||||
MAX_FRAMES);
|
MAX_FRAMES);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (size_t j = 0; j < nb_frames; j++)
|
for (size_t j = 0; j < nb_frames; j++) {
|
||||||
|
assert(j + i < MAX_FRAMES);
|
||||||
frame_table[j + i] = 1;
|
frame_table[j + i] = 1;
|
||||||
|
}
|
||||||
|
assert(remaining_frames >= nb_frames);
|
||||||
remaining_frames -= nb_frames;
|
remaining_frames -= nb_frames;
|
||||||
return (void *)(i * PAGE_SIZE);
|
return (void *)(i * PAGE_SIZE); // WARNING: address translation cramptés
|
||||||
}
|
}
|
||||||
|
|
||||||
int free_frames(void *frame_ptr, size_t size)
|
int free_frames(void *frame_ptr, size_t size)
|
||||||
{
|
{
|
||||||
const uint32_t nb_frames = CEIL(size, PAGE_SIZE);
|
const uint32_t nb_frames = CEIL(size, PAGE_SIZE);
|
||||||
const uint32_t start = (uint32_t)frame_ptr / PAGE_SIZE;
|
const uint32_t start = (uint32_t)(frame_ptr + HEAP_END) / PAGE_SIZE;
|
||||||
|
|
||||||
if (start > MAX_FRAMES) {
|
if (start > MAX_FRAMES) {
|
||||||
kprintf(KERN_WARNING "Address out of range\n");
|
kprintf(KERN_WARNING "Address out of range\n");
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
@ -7,13 +8,13 @@
|
|||||||
extern uint32_t boot_page_directory;
|
extern uint32_t boot_page_directory;
|
||||||
uint32_t *page_directory = &boot_page_directory;
|
uint32_t *page_directory = &boot_page_directory;
|
||||||
uint32_t page_table1[1024] __attribute__((aligned(4096)));
|
uint32_t page_table1[1024] __attribute__((aligned(4096)));
|
||||||
uint32_t page_table_entries[1024] __attribute__((aligned(4096)));
|
|
||||||
|
|
||||||
void init_memory(void)
|
void init_memory(void)
|
||||||
{
|
{
|
||||||
|
assert(page_directory);
|
||||||
for (int16_t i = 0; i < 0x300; i++)
|
for (int16_t i = 0; i < 0x300; i++)
|
||||||
page_directory[i] = 0x02;
|
page_directory[i] = 0x02;
|
||||||
for (int16_t i = 0; i < 1024; i++)
|
for (int16_t i = 0; i < 1024; i++)
|
||||||
page_table1[i] = i << 12 | 0x03;
|
page_table1[i] = (i << 12) | 0x03;
|
||||||
page_directory[0] = (uint32_t)page_table1 | 0x03;
|
page_directory[0] = ((uint32_t)page_table1 - HEAP_END) | 0x03;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -9,14 +10,13 @@
|
|||||||
#define PT_SIZE 1024
|
#define PT_SIZE 1024
|
||||||
#define MAX_TLB_ENTRIES 32
|
#define MAX_TLB_ENTRIES 32
|
||||||
|
|
||||||
extern uint32_t page_table_entries[PT_SIZE];
|
extern uint32_t page_table1[PT_SIZE];
|
||||||
|
|
||||||
static int16_t find_next_block(size_t nb_pages)
|
static int16_t find_next_block(size_t nb_pages)
|
||||||
{
|
{
|
||||||
for (uint16_t i = 1; i < PT_SIZE; i++) {
|
for (uint16_t i = 1; i < PT_SIZE - 1; i++) {
|
||||||
uint16_t j;
|
uint16_t j;
|
||||||
for (j = 0;
|
for (j = 0; page_table1[i + j] >> 12 == i + j && j < nb_pages;
|
||||||
page_table_entries[i + j] >> 12 == 0 && j < nb_pages;
|
|
||||||
j++)
|
j++)
|
||||||
;
|
;
|
||||||
if (j == nb_pages)
|
if (j == nb_pages)
|
||||||
@ -39,14 +39,15 @@ void *alloc_pages(size_t size)
|
|||||||
void *frame = alloc_frames(PAGE_SIZE);
|
void *frame = alloc_frames(PAGE_SIZE);
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
for (size_t j = index; j < i; j++)
|
for (size_t j = index; j < i; j++)
|
||||||
free_frames(
|
free_frames((void *)(page_table1[j] >> 12),
|
||||||
(void *)(page_table_entries[j] >> 12),
|
PAGE_SIZE);
|
||||||
PAGE_SIZE);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
page_table_entries[i] = (uint32_t)frame << 12 | INIT_FLAGS;
|
assert(page_table1[i] >> 12 == i);
|
||||||
|
page_table1[i] = (uint32_t)frame << 12 | INIT_FLAGS;
|
||||||
}
|
}
|
||||||
return (void *)(index * PAGE_SIZE);
|
PRINT_PTR(page_table1[index]);
|
||||||
|
return (void *)(page_table1[index] >> 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
int free_pages(void *page_ptr, size_t size)
|
int free_pages(void *page_ptr, size_t size)
|
||||||
@ -65,8 +66,8 @@ int free_pages(void *page_ptr, size_t size)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (size_t i = page_index; i < page_index + nb_pages; i++) {
|
for (size_t i = page_index; i < page_index + nb_pages; i++) {
|
||||||
free_frames((void *)(page_table_entries[i] >> 12), PAGE_SIZE);
|
free_frames((void *)(page_table1[i] >> 12), PAGE_SIZE);
|
||||||
page_table_entries[i] = INIT_FLAGS;
|
page_table1[i] = i << 12 | INIT_FLAGS;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
Zone *kzones[3];
|
Zone *kzones[3];
|
||||||
|
|
||||||
@ -14,15 +15,15 @@ static void add_zone(Zone *zone, block_type_t type)
|
|||||||
kzones[type] = zone;
|
kzones[type] = zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void new_block(Zone *zone, size_t zone_size)
|
static void new_block(Zone *zone, uint32_t zone_size)
|
||||||
{
|
{
|
||||||
Block *new_block = (Block *)align_mem((size_t)zone + sizeof(Zone));
|
Block *new_block = (Block *)align_mem((uint32_t)zone + sizeof(Zone));
|
||||||
|
|
||||||
// Metadata
|
// Metadata
|
||||||
new_block->in_use = false;
|
new_block->in_use = false;
|
||||||
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
|
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
|
||||||
new_block->sub_size = new_block->size;
|
new_block->sub_size = new_block->size;
|
||||||
new_block->ptr = (Block *)((size_t)new_block + sizeof(Block));
|
new_block->ptr = (Block *)((uint32_t)new_block + sizeof(Block));
|
||||||
new_block->zone = zone;
|
new_block->zone = zone;
|
||||||
|
|
||||||
// Init future linked lists
|
// Init future linked lists
|
||||||
@ -42,7 +43,7 @@ static void new_block(Zone *zone, size_t zone_size)
|
|||||||
zone->free = new_block;
|
zone->free = new_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_kzone(block_type_t type, size_t size)
|
int new_kzone(block_type_t type, uint32_t size)
|
||||||
{
|
{
|
||||||
void *heap = alloc_frames(size);
|
void *heap = alloc_frames(size);
|
||||||
if (heap == NULL) {
|
if (heap == NULL) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// FULL_INFO is to display (or not) both used and unused blocks
|
// FULL_INFO is to display (or not) both used and unused blocks
|
||||||
#define FULL_INFO 1
|
#define FULL_INFO 1
|
||||||
@ -7,7 +8,7 @@
|
|||||||
void show_kalloc_mem(void)
|
void show_kalloc_mem(void)
|
||||||
{
|
{
|
||||||
char *const kzones_name[3] = {"TINY", "SMALL", "LARGE"};
|
char *const kzones_name[3] = {"TINY", "SMALL", "LARGE"};
|
||||||
size_t total_size = 0;
|
uint32_t total_size = 0;
|
||||||
|
|
||||||
for (block_type_t type = 0; type < 3; ++type) {
|
for (block_type_t type = 0; type < 3; ++type) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -21,7 +22,7 @@ void show_kalloc_mem(void)
|
|||||||
for (Block *block_it = zone_it->free; block_it != NULL;
|
for (Block *block_it = zone_it->free; block_it != NULL;
|
||||||
block_it = block_it->next_free) {
|
block_it = block_it->next_free) {
|
||||||
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
||||||
(size_t)block_it->ptr +
|
(uint32_t)block_it->ptr +
|
||||||
block_it->sub_size + sizeof(Block),
|
block_it->sub_size + sizeof(Block),
|
||||||
block_it->sub_size);
|
block_it->sub_size);
|
||||||
}
|
}
|
||||||
@ -35,7 +36,7 @@ void show_kalloc_mem(void)
|
|||||||
for (Block *block_it = zone_it->used; block_it != NULL;
|
for (Block *block_it = zone_it->used; block_it != NULL;
|
||||||
block_it = block_it->next_used) {
|
block_it = block_it->next_used) {
|
||||||
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
||||||
(size_t)block_it->ptr +
|
(uint32_t)block_it->ptr +
|
||||||
block_it->sub_size + sizeof(Block),
|
block_it->sub_size + sizeof(Block),
|
||||||
block_it->sub_size);
|
block_it->sub_size);
|
||||||
total_size += block_it->sub_size;
|
total_size += block_it->sub_size;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static void remove_used(Block *to_free)
|
static void remove_used(Block *to_free)
|
||||||
{
|
{
|
||||||
@ -97,7 +98,7 @@ void kfree(void *ptr)
|
|||||||
{
|
{
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
return;
|
||||||
Block *to_free = (Block *)((size_t)ptr - sizeof(Block));
|
Block *to_free = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||||
Block *to_merge = NULL;
|
Block *to_merge = NULL;
|
||||||
to_free->in_use = false;
|
to_free->in_use = false;
|
||||||
remove_used(to_free);
|
remove_used(to_free);
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find first available (not in_use) block
|
* Find first available (not in_use) block
|
||||||
* in a zone matching the size we need
|
* in a zone matching the size we need
|
||||||
*/
|
*/
|
||||||
static Block *find_block(Zone *head, size_t size)
|
static Block *find_block(Zone *head, uint32_t size)
|
||||||
{
|
{
|
||||||
for (Zone *zone_it = head; zone_it != NULL; zone_it = zone_it->next) {
|
for (Zone *zone_it = head; zone_it != NULL; zone_it = zone_it->next) {
|
||||||
for (Block *block_it = zone_it->free; block_it != NULL;
|
for (Block *block_it = zone_it->free; block_it != NULL;
|
||||||
@ -42,17 +44,17 @@ static Block *find_block(Zone *head, size_t size)
|
|||||||
* We can see that it now has its own metadata and available
|
* We can see that it now has its own metadata and available
|
||||||
* data and it points towards [6]
|
* data and it points towards [6]
|
||||||
*/
|
*/
|
||||||
static void frag_block(Zone *zone, Block *old_block, size_t size)
|
static void frag_block(Zone *zone, Block *old_block, uint32_t size)
|
||||||
{
|
{
|
||||||
Block *new_block = (Block *)align_mem((size_t)old_block + size);
|
Block *new_block = (Block *)align_mem((uint32_t)old_block + size);
|
||||||
assert(!(new_block >=
|
assert(!(new_block >=
|
||||||
(Block *)((size_t)zone + get_zone_size(zone->type))));
|
(Block *)((uint32_t)zone + get_zone_size(zone->type))));
|
||||||
|
|
||||||
// Newly created block metadata
|
// Newly created block metadata
|
||||||
new_block->size = old_block->size - size;
|
new_block->size = old_block->size - size;
|
||||||
new_block->sub_size = new_block->size;
|
new_block->sub_size = new_block->size;
|
||||||
new_block->in_use = false;
|
new_block->in_use = false;
|
||||||
new_block->ptr = (void *)((size_t)new_block + sizeof(Block));
|
new_block->ptr = (void *)((uint32_t)new_block + sizeof(Block));
|
||||||
new_block->zone = zone;
|
new_block->zone = zone;
|
||||||
|
|
||||||
new_block->prev = old_block;
|
new_block->prev = old_block;
|
||||||
@ -114,7 +116,7 @@ static void save_block(Zone *head, Block *block, Zone *zone)
|
|||||||
*
|
*
|
||||||
* ptr: returns the aligned pointer of the block (after the metadata)
|
* ptr: returns the aligned pointer of the block (after the metadata)
|
||||||
*/
|
*/
|
||||||
void *kmalloc(size_t size)
|
void *kmalloc(uint32_t size)
|
||||||
{
|
{
|
||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
|
|
||||||
@ -130,7 +132,7 @@ void *kmalloc(size_t size)
|
|||||||
// Find an available block in a zone of type "type"
|
// Find an available block in a zone of type "type"
|
||||||
Block *available = find_block(head, size);
|
Block *available = find_block(head, size);
|
||||||
if (available == NULL) {
|
if (available == NULL) {
|
||||||
size_t full_size;
|
uint32_t full_size;
|
||||||
if (type == LARGE)
|
if (type == LARGE)
|
||||||
full_size = size + sizeof(Block) + sizeof(Zone);
|
full_size = size + sizeof(Block) + sizeof(Zone);
|
||||||
else
|
else
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// Prototype for kfree and kmalloc
|
// Prototype for kfree and kmalloc
|
||||||
void kfree(void *ptr);
|
void kfree(void *ptr);
|
||||||
void *kmalloc(size_t size);
|
void *kmalloc(uint32_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ptr: block to resize (undefined behavior if invalid)
|
* ptr: block to resize (undefined behavior if invalid)
|
||||||
@ -17,12 +18,12 @@ void *kmalloc(size_t size);
|
|||||||
*
|
*
|
||||||
* ptr: returns the aligned pointer of the kreallocated block
|
* ptr: returns the aligned pointer of the kreallocated block
|
||||||
*/
|
*/
|
||||||
void *krealloc(void *ptr, size_t size)
|
void *krealloc(void *ptr, uint32_t size)
|
||||||
{
|
{
|
||||||
void *new_ptr = NULL;
|
void *new_ptr = NULL;
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
Block *block = (Block *)((size_t)ptr - sizeof(Block));
|
Block *block = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||||
if (block->size >= size) {
|
if (block->size >= size) {
|
||||||
block->sub_size = size;
|
block->sub_size = size;
|
||||||
return (ptr);
|
return (ptr);
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
size_t ksize(void *ptr)
|
uint32_t ksize(void *ptr)
|
||||||
{
|
{
|
||||||
Block *meta_data = (Block *)((size_t)ptr - sizeof(Block));
|
Block *meta_data = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||||
|
|
||||||
return meta_data->sub_size;
|
return meta_data->sub_size;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "kpanic.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
@ -14,15 +16,15 @@ static void add_zone(Zone *zone, block_type_t type)
|
|||||||
vzones[type] = zone;
|
vzones[type] = zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void new_block(Zone *zone, size_t zone_size)
|
static void new_block(Zone *zone, uint32_t zone_size)
|
||||||
{
|
{
|
||||||
Block *new_block = (Block *)align_mem((size_t)zone + sizeof(Zone));
|
Block *new_block = (Block *)align_mem((uint32_t)zone + sizeof(Zone));
|
||||||
|
|
||||||
// Metadata
|
// Metadata
|
||||||
new_block->in_use = false;
|
new_block->in_use = false;
|
||||||
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
|
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
|
||||||
new_block->sub_size = new_block->size;
|
new_block->sub_size = new_block->size;
|
||||||
new_block->ptr = (Block *)((size_t)new_block + sizeof(Block));
|
new_block->ptr = (Block *)((uint32_t)new_block + sizeof(Block));
|
||||||
new_block->zone = zone;
|
new_block->zone = zone;
|
||||||
|
|
||||||
// Init future linked lists
|
// Init future linked lists
|
||||||
@ -39,16 +41,22 @@ static void new_block(Zone *zone, size_t zone_size)
|
|||||||
new_block->next = zone->free;
|
new_block->next = zone->free;
|
||||||
new_block->next_free = zone->free;
|
new_block->next_free = zone->free;
|
||||||
}
|
}
|
||||||
|
kprintf("before zone: %p zone->free: %p new_block: %p\n", zone,
|
||||||
|
zone->free, new_block);
|
||||||
zone->free = new_block;
|
zone->free = new_block;
|
||||||
|
kprintf("after zone: %p zone->free: %p new_block: %p\n", zone,
|
||||||
|
zone->free, new_block);
|
||||||
|
assert(zone->free == new_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_vzone(block_type_t type, size_t size)
|
int new_vzone(block_type_t type, uint32_t size)
|
||||||
{
|
{
|
||||||
void *heap = alloc_pages(size);
|
void *heap = alloc_pages(size);
|
||||||
if (heap == NULL) {
|
if (heap == NULL) {
|
||||||
kprintf(KERN_ERR "error: alloc_pages failed\n");
|
kprintf(KERN_ERR "error: alloc_pages failed\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
PRINT_PTR(heap);
|
||||||
|
|
||||||
Zone *zone = (Zone *)heap;
|
Zone *zone = (Zone *)heap;
|
||||||
zone->type = type;
|
zone->type = type;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// FULL_INFO is to display (or not) both used and unused blocks
|
// FULL_INFO is to display (or not) both used and unused blocks
|
||||||
#define FULL_INFO 1
|
#define FULL_INFO 1
|
||||||
@ -7,7 +8,7 @@
|
|||||||
void show_valloc_mem(void)
|
void show_valloc_mem(void)
|
||||||
{
|
{
|
||||||
char *const vzones_name[3] = {"TINY", "SMALL", "LARGE"};
|
char *const vzones_name[3] = {"TINY", "SMALL", "LARGE"};
|
||||||
size_t total_size = 0;
|
uint32_t total_size = 0;
|
||||||
|
|
||||||
for (block_type_t type = 0; type < 3; ++type) {
|
for (block_type_t type = 0; type < 3; ++type) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -18,10 +19,11 @@ void show_valloc_mem(void)
|
|||||||
kprintf("---------- AVAILABLE %s [n°%d - %p] "
|
kprintf("---------- AVAILABLE %s [n°%d - %p] "
|
||||||
"----------\n",
|
"----------\n",
|
||||||
vzones_name[type], count, zone_it);
|
vzones_name[type], count, zone_it);
|
||||||
|
int i = 0;
|
||||||
for (Block *block_it = zone_it->free; block_it != NULL;
|
for (Block *block_it = zone_it->free; block_it != NULL;
|
||||||
block_it = block_it->next_free) {
|
block_it = block_it->next_free) {
|
||||||
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
||||||
(size_t)block_it->ptr +
|
(uint32_t)block_it->ptr +
|
||||||
block_it->sub_size + sizeof(Block),
|
block_it->sub_size + sizeof(Block),
|
||||||
block_it->sub_size);
|
block_it->sub_size);
|
||||||
}
|
}
|
||||||
@ -34,8 +36,10 @@ void show_valloc_mem(void)
|
|||||||
vzones_name[type], count, zone_it);
|
vzones_name[type], count, zone_it);
|
||||||
for (Block *block_it = zone_it->used; block_it != NULL;
|
for (Block *block_it = zone_it->used; block_it != NULL;
|
||||||
block_it = block_it->next_used) {
|
block_it = block_it->next_used) {
|
||||||
|
/* i++; */
|
||||||
|
/* if (i < 10) */
|
||||||
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
kprintf("%p - %p : %u bytes\n", block_it->ptr,
|
||||||
(size_t)block_it->ptr +
|
(uint32_t)block_it->ptr +
|
||||||
block_it->sub_size + sizeof(Block),
|
block_it->sub_size + sizeof(Block),
|
||||||
block_it->sub_size);
|
block_it->sub_size);
|
||||||
total_size += block_it->sub_size;
|
total_size += block_it->sub_size;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static void remove_used(Block *to_free)
|
static void remove_used(Block *to_free)
|
||||||
{
|
{
|
||||||
@ -97,7 +98,7 @@ void vfree(void *ptr)
|
|||||||
{
|
{
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
return;
|
||||||
Block *to_free = (Block *)((size_t)ptr - sizeof(Block));
|
Block *to_free = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||||
Block *to_merge = NULL;
|
Block *to_merge = NULL;
|
||||||
to_free->in_use = false;
|
to_free->in_use = false;
|
||||||
remove_used(to_free);
|
remove_used(to_free);
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
int new_zone(block_type_t type, size_t size);
|
int new_zone(block_type_t type, uint32_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find first available (not in_use) block
|
* Find first available (not in_use) block
|
||||||
* in a zone matching the size we need
|
* in a zone matching the size we need
|
||||||
*/
|
*/
|
||||||
static Block *find_block(Zone *head, size_t size)
|
static Block *find_block(Zone *head, uint32_t size)
|
||||||
{
|
{
|
||||||
for (Zone *zone_it = head; zone_it != NULL; zone_it = zone_it->next) {
|
for (Zone *zone_it = head; zone_it != NULL; zone_it = zone_it->next) {
|
||||||
|
assert(zone_it->free);
|
||||||
for (Block *block_it = zone_it->free; block_it != NULL;
|
for (Block *block_it = zone_it->free; block_it != NULL;
|
||||||
block_it = block_it->next_free) {
|
block_it = block_it->next_free) {
|
||||||
|
/* PRINT_PTR(block_it); */
|
||||||
assert(!block_it->in_use);
|
assert(!block_it->in_use);
|
||||||
if (size <= block_it->size) {
|
if (size <= block_it->size) {
|
||||||
assert(block_it->zone == zone_it);
|
assert(block_it->zone == zone_it);
|
||||||
@ -44,17 +48,17 @@ static Block *find_block(Zone *head, size_t size)
|
|||||||
* We can see that it now has its own metadata and available
|
* We can see that it now has its own metadata and available
|
||||||
* data and it points towards [6]
|
* data and it points towards [6]
|
||||||
*/
|
*/
|
||||||
static void frag_block(Zone *zone, Block *old_block, size_t size)
|
static void frag_block(Zone *zone, Block *old_block, uint32_t size)
|
||||||
{
|
{
|
||||||
Block *new_block = (Block *)align_mem((size_t)old_block + size);
|
Block *new_block = (Block *)align_mem((uint32_t)old_block + size);
|
||||||
assert(!(new_block >=
|
assert(!(new_block >=
|
||||||
(Block *)((size_t)zone + get_zone_size(zone->type))));
|
(Block *)((uint32_t)zone + get_zone_size(zone->type))));
|
||||||
|
|
||||||
// Newly created block metadata
|
// Newly created block metadata
|
||||||
new_block->size = old_block->size - size;
|
new_block->size = old_block->size - size;
|
||||||
new_block->sub_size = new_block->size;
|
new_block->sub_size = new_block->size;
|
||||||
new_block->in_use = false;
|
new_block->in_use = false;
|
||||||
new_block->ptr = (void *)((size_t)new_block + sizeof(Block));
|
new_block->ptr = (void *)((uint32_t)new_block + sizeof(Block));
|
||||||
new_block->zone = zone;
|
new_block->zone = zone;
|
||||||
|
|
||||||
new_block->prev = old_block;
|
new_block->prev = old_block;
|
||||||
@ -116,7 +120,7 @@ static void save_block(Zone *head, Block *block, Zone *zone)
|
|||||||
*
|
*
|
||||||
* ptr: returns the aligned pointer of the block (after the metadata)
|
* ptr: returns the aligned pointer of the block (after the metadata)
|
||||||
*/
|
*/
|
||||||
void *vmalloc(size_t size)
|
void *vmalloc(uint32_t size)
|
||||||
{
|
{
|
||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
|
|
||||||
@ -132,7 +136,7 @@ void *vmalloc(size_t size)
|
|||||||
// Find an available block in a zone of type "type"
|
// Find an available block in a zone of type "type"
|
||||||
Block *available = find_block(head, size);
|
Block *available = find_block(head, size);
|
||||||
if (available == NULL) {
|
if (available == NULL) {
|
||||||
size_t full_size;
|
uint32_t full_size;
|
||||||
if (type == LARGE)
|
if (type == LARGE)
|
||||||
full_size = size + sizeof(Block) + sizeof(Zone);
|
full_size = size + sizeof(Block) + sizeof(Zone);
|
||||||
else
|
else
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// Prototype for kfree and vmalloc
|
// Prototype for kfree and vmalloc
|
||||||
void kfree(void *ptr);
|
void kfree(void *ptr);
|
||||||
void *vmalloc(size_t size);
|
void *vmalloc(uint32_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ptr: block to resize (undefined behavior if invalid)
|
* ptr: block to resize (undefined behavior if invalid)
|
||||||
@ -17,12 +18,12 @@ void *vmalloc(size_t size);
|
|||||||
*
|
*
|
||||||
* ptr: returns the aligned pointer of the vreallocated block
|
* ptr: returns the aligned pointer of the vreallocated block
|
||||||
*/
|
*/
|
||||||
void *vrealloc(void *ptr, size_t size)
|
void *vrealloc(void *ptr, uint32_t size)
|
||||||
{
|
{
|
||||||
void *new_ptr = NULL;
|
void *new_ptr = NULL;
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
Block *block = (Block *)((size_t)ptr - sizeof(Block));
|
Block *block = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||||
if (block->size >= size) {
|
if (block->size >= size) {
|
||||||
block->sub_size = size;
|
block->sub_size = size;
|
||||||
return (ptr);
|
return (ptr);
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
size_t vsize(void *ptr)
|
uint32_t vsize(void *ptr)
|
||||||
{
|
{
|
||||||
Block *meta_data = (Block *)((size_t)ptr - sizeof(Block));
|
Block *meta_data = (Block *)((uint32_t)ptr - sizeof(Block));
|
||||||
|
|
||||||
return meta_data->sub_size;
|
return meta_data->sub_size;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user