paging: heap_alloc: fix allocation of more than 1 page (not without the help of grok)

This commit is contained in:
2025-03-29 14:04:57 +03:00
parent 2724595592
commit 6f7cbfedbb
+32 -10
View File
@@ -58,7 +58,7 @@ void init_allocator() {
// Выделяем свободную страницу
void* alloc_page() {
printf("alloc_page called\n");
// printf("alloc_page called\n");
int i, j;
for (i = 0; i < 512; i++) {
if (page_bitmap[i] != 0xFF) {
@@ -354,9 +354,7 @@ void* heap_alloc(uint32_t size) {
// Ищем подходящий свободный блок
while (current) {
if (current->is_free && current->size >= size) {
// Нашли блок
if (current->size >= size + sizeof(Block) + 4) {
// Разделяем блок, если он слишком большой
Block* new_block = (Block*)((uint32_t)current + sizeof(Block) + size);
new_block->size = current->size - size - sizeof(Block);
new_block->is_free = 1;
@@ -366,25 +364,49 @@ void* heap_alloc(uint32_t size) {
current->next = new_block;
}
current->is_free = 0;
return (void*)((uint32_t)current + sizeof(Block)); // Возвращаем адрес после заголовка
return (void*)((uint32_t)current + sizeof(Block));
}
prev = current;
current = current->next;
}
// Нет свободного блока — добавляем новую страницу
// Нет подходящего блока — выделяем нужное количество страниц
uint32_t total_size = size + sizeof(Block); // Размер с заголовком
uint32_t pages_needed = (total_size + 0xFFF) / 0x1000; // Округляем вверх до страниц
uint32_t alloc_size = pages_needed * 0x1000; // Сколько байт выделяем
void* new_page = (void*)((uint32_t)kernel_heap.start + kernel_heap.size);
map_kernel_page(new_page, 0x2);
kernel_heap.size += 0x1000;
for (uint32_t i = 0; i < pages_needed; i++) {
map_kernel_page((void*)((uint32_t)new_page + i * 0x1000), 0x2);
}
kernel_heap.size += alloc_size;
Block* new_block = (Block*)new_page;
new_block->size = 0x1000 - sizeof(Block);
new_block->size = alloc_size - sizeof(Block);
new_block->is_free = 1;
new_block->next = (Block*)0;
if (prev) prev->next = new_block;
if (!kernel_heap.first) kernel_heap.first = new_block;
// Рекурсивно вызываем, чтобы выделить из нового блока
return heap_alloc(size);
// Теперь current указывает на новый блок, продолжаем цикл
current = new_block;
if (current->size >= size) {
if (current->size >= size + sizeof(Block) + 4) {
Block* split_block = (Block*)((uint32_t)current + sizeof(Block) + size);
split_block->size = current->size - size - sizeof(Block);
split_block->is_free = 1;
split_block->next = current->next;
current->size = size;
current->next = split_block;
}
current->is_free = 0;
return (void*)((uint32_t)current + sizeof(Block));
}
// Если что-то пошло не так, возвращаем NULL
return (void*)0;
}
// Освобождение памяти