From 0a8b29b11f56bde9bf21a1e5e65d44dda4b09b3e Mon Sep 17 00:00:00 2001 From: Ruslan Isaev Date: Fri, 11 Apr 2025 14:50:52 +0300 Subject: [PATCH] mm: make page_alloc track all the memory --- src/mm/page_alloc.c | 80 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/src/mm/page_alloc.c b/src/mm/page_alloc.c index e3f557e..7cb790b 100644 --- a/src/mm/page_alloc.c +++ b/src/mm/page_alloc.c @@ -2,39 +2,95 @@ #include #include "../include/stdio.h" -uint8_t page_bitmap[512]; // 1 бит на страницу +#define PAGE_SIZE 0x1000 // 4 КБ +// Общий размер памяти +#define MEMORY_SIZE 0x100000000 // 4 ГБ + +// Количество страниц +#define PAGE_COUNT (MEMORY_SIZE / PAGE_SIZE) // 1 048 576 страниц + +// Размер битмапа в байтах (округлено вверх) +#define BITMAP_SIZE (PAGE_COUNT / 8) // 131 072 байт + +// Битмап для отслеживания страниц +// Каждый бит представляет одну страницу: 0 = свободна, 1 = занята +uint8_t page_bitmap[BITMAP_SIZE]; + +// Инициализация аллокатора страниц void init_allocator() { int i; + // Помечаем все страницы как свободные (0) - for (i = 0; i < 512; i++) { + for (i = 0; i < BITMAP_SIZE; i++) { page_bitmap[i] = 0; } - // Первые 4 МБ уже заняты ядром (0x00000000–0x003FFFFF) - for (i = 0; i < 1024 / 8; i++) { // 1024 страницы = 128 байт + + // Резервируем первые 4 МБ для ядра (0x00000000-0x003FFFFF) + // Это 1024 страницы или 128 байт битмапа + for (i = 0; i < 1024 / 8; i++) { page_bitmap[i] = 0xFF; // Все биты = 1 (занято) } + + // Если вы используете higher-half kernel, то нужно также + // зарезервировать соответствующую область в верхней части памяти + // Например, если ядро отображено начиная с 0xC0000000 (3 ГБ): + uint32_t kernel_higher_start = 0xC0000000 / PAGE_SIZE / 8; // Индекс в битмапе + for (i = kernel_higher_start; i < kernel_higher_start + 1024 / 8; i++) { + page_bitmap[i] = 0xFF; + } } void* alloc_page() { int i, j; - for (i = 0; i < 512; i++) { - if (page_bitmap[i] != 0xFF) { + + // Проходим по всему битмапу + for (i = 0; i < BITMAP_SIZE; i++) { + if (page_bitmap[i] != 0xFF) { // Если в этом байте есть свободная страница for (j = 0; j < 8; j++) { - if (!(page_bitmap[i] & (1 << j))) { - page_bitmap[i] |= (1 << j); - return (void*)(((i * 8) + j) * 0x1000); + if (!(page_bitmap[i] & (1 << j))) { // Если этот бит = 0 (свободен) + page_bitmap[i] |= (1 << j); // Помечаем как занятый + + // Вычисляем физический адрес страницы + uint32_t page_num = i * 8 + j; + return (void*)(page_num * PAGE_SIZE); } } } } + printf("no bitches? no free pages?\n"); - return (void*)0; // Нет свободных страниц + return (void*)0; // Нет свободных страниц } void free_page(void* physaddr) { - uint32_t page_num = (uint32_t)physaddr / 0x1000; + uint32_t addr = (uint32_t)physaddr; + + // Проверка выравнивания адреса + if (addr & 0xFFF) { + printf("free_page: address not page-aligned\n"); + return; + } + + // Вычисляем номер страницы + uint32_t page_num = addr / PAGE_SIZE; + + // Проверка границ + if (page_num >= PAGE_COUNT) { + printf("free_page: address out of range\n"); + return; + } + + // Вычисляем индекс байта и бита в битмапе uint32_t byte_idx = page_num / 8; uint32_t bit_idx = page_num % 8; - page_bitmap[byte_idx] &= ~(1 << bit_idx); // Сбрасываем бит + + // Проверяем, не освобождаем ли уже свободную страницу + if (!(page_bitmap[byte_idx] & (1 << bit_idx))) { + printf("free_page: page already free\n"); + return; + } + + // Освобождаем страницу + page_bitmap[byte_idx] &= ~(1 << bit_idx); }