Я делаю немного OSdev, и я пытался реализовать управление памятью в моем ядре. Я начал с менеджера физической памяти (это 32-битная ОС). Идея состоит в том, чтобы сохранить таблицу битов, в которой мы выделяем бит для блока физической памяти 4K. Если бит равен «1», блок используется, а если «0», это не так. Я думал, что эта таблица должна идти после ядра. Итак, вот мой код ядра (минимальный):
#include<stdint.h>
#define PMMAP 0x1000 //This contains information from int 15h/E820
#define BLOCK_SIZE 4096
#define SECTOR_SIZE 512
#define SECTORS_PER_BLOCK 8
#define BLOCK_SIZE_B 12
#define SECTOR_SIZE_B 9
#define SECTORS_PER_BLOCK_B 3
void pmmngr_init(uint32_t kernelsize,uint32_t mapentrycount);
uint32_t* _physical_memory_table;
void kmain(uint32_t size,uint32_t mmapentrycount) //This size is passed on by the bootloader, where it has a filesystem driver-ish code that determines this. The size unit is 512 bytes
{
pmmngr_init(size,mmapentrycount);
return;
}
struct mmap_entry {
uint32_t startLo;
uint32_t startHi;
uint32_t sizeLo;
uint32_t sizeHi;
uint32_t type;
uint32_t acpi_3_0;
};
void pmmngr_init(uint32_t kernelsize,uint32_t mapentrycount)
{
struct mmap_entry* map_ptr= (struct mmap_entry*)PMMAP;
_physical_memory_table = (uint32_t*)(KERNEL_P + kernelsize*SECTOR_SIZE);
for (uint32_t i=0;i<0x8000;i++) //Why 0x8000? This is the size of the table (* 32 of course)
_physical_memory_table[i] = 0xffffffff;
}
Изначально я делаю все 0xffffffff. Затем я читаю карту памяти (из E820) и выделяю и освобождаю (позже).
Я компилирую с:
i686-elf-gcc kernel.c -c -g -o kernel.o --ffreestanding
i686-elf-ld kernel.o -Ttext 0x100000 -o kernel.elf
objcopy -O binary kernel.elf kernel.bin
Обратите внимание, что ядро предназначено для загрузки в область памяти 1M. Все это было введением в эту проблему. Вот основная проблема ..
Здесь моя _physical_memory_table загружается / создается после ядра, и место его создания зависит от размера файла kernel.bin, полученного из загрузчик.
Предположим, размер файла kernel.bin составляет ~ 1 КБ. Таблица будет размещена в памяти размером 1 МБ + 1 КБ (0x100400). Вот основная проблема ... указатель переменной _physical_memory_table на самом деле не «размещен» в диапазоне 0x100000 - 0x100400 компоновщиком. Он принадлежит разделу .bss и, в моем случае, находится вне этого диапазона! Указатель присутствует в том месте, где создается таблица, он перекрывается и, таким образом, это ошибка.
Итак, как бы я решил эту проблему? Мне нужно раскрыть «диапазон контроля» ядра, т. Е. Диапазон ядра и всех его частей в памяти, и поместить эту таблицу после .
Так что же делать Я делаю? (Я предполагаю что-то с помощью скрипта компоновщика)