paging: heap_alloc: fix allocation of more than 1 page (not without the help of grok)
This commit is contained in:
+32
-10
@@ -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;
|
||||
}
|
||||
|
||||
// Освобождение памяти
|
||||
|
||||
Reference in New Issue
Block a user