mm: make page_alloc track all the memory

This commit is contained in:
2025-04-11 14:50:52 +03:00
parent 35749c097f
commit 0a8b29b11f
+67 -11
View File
@@ -2,39 +2,95 @@
#include <stdint.h> #include <stdint.h>
#include "../include/stdio.h" #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() { void init_allocator() {
int i; int i;
// Помечаем все страницы как свободные (0) // Помечаем все страницы как свободные (0)
for (i = 0; i < 512; i++) { for (i = 0; i < BITMAP_SIZE; i++) {
page_bitmap[i] = 0; page_bitmap[i] = 0;
} }
// Первые 4 МБ уже заняты ядром (0x000000000x003FFFFF)
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 (занято) 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() { void* alloc_page() {
int i, j; 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++) { for (j = 0; j < 8; j++) {
if (!(page_bitmap[i] & (1 << j))) { if (!(page_bitmap[i] & (1 << j))) { // Если этот бит = 0 (свободен)
page_bitmap[i] |= (1 << j); page_bitmap[i] |= (1 << j); // Помечаем как занятый
return (void*)(((i * 8) + j) * 0x1000);
// Вычисляем физический адрес страницы
uint32_t page_num = i * 8 + j;
return (void*)(page_num * PAGE_SIZE);
} }
} }
} }
} }
printf("no bitches? no free pages?\n"); printf("no bitches? no free pages?\n");
return (void*)0; // Нет свободных страниц return (void*)0; // Нет свободных страниц
} }
void free_page(void* physaddr) { 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 byte_idx = page_num / 8;
uint32_t bit_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);
} }