2022-08-21 19:18:53 +00:00
|
|
|
#include "./PhysicalMemoryManager.h"
|
|
|
|
|
|
|
|
PhysicalMemoryManagerInfoBlock* PMMInfoBlock;
|
2022-09-01 18:16:16 +00:00
|
|
|
extern uint32_t* boot_page_directory;
|
|
|
|
extern uint32_t* boot_page_table;
|
2022-08-21 19:18:53 +00:00
|
|
|
|
2022-09-01 14:11:35 +00:00
|
|
|
const uint32_t KERNEL_OFFSET = 0xC0000000;
|
|
|
|
void SetupPhysicalMemoryManager( BootInfoBlock* Bootinfo) {
|
2022-09-01 18:16:16 +00:00
|
|
|
// NOTE: Physical memory map will override the boot info for now!
|
|
|
|
PMMInfoBlock = (PhysicalMemoryManagerInfoBlock*) (&BootInfoBlock_pptr + KERNEL_OFFSET );
|
|
|
|
printf("Setting up physical memory infoblock (0x%x) \n", (uint32_t)&PMMInfoBlock);
|
2022-09-01 14:11:35 +00:00
|
|
|
/*
|
|
|
|
Every byte contains 8 pages
|
|
|
|
A page is 4096 kib
|
|
|
|
Every block (1 bit) represent an page
|
|
|
|
*/
|
2022-08-21 19:18:53 +00:00
|
|
|
|
2022-09-01 18:16:16 +00:00
|
|
|
// Calculate the maximum number of blocks
|
|
|
|
printf("Maxblocks at address(0x%x)\n" , (uint32_t)&(PMMInfoBlock->max_blocks));
|
2022-08-21 19:18:53 +00:00
|
|
|
|
2022-09-01 18:16:16 +00:00
|
|
|
int maximum_blocks = (uint32_t)Bootinfo->MemorySize / BLOCK_SIZE / 8;
|
|
|
|
printf("Set bitmap block maximum: %d\n", maximum_blocks);
|
|
|
|
PMMInfoBlock->max_blocks = maximum_blocks;
|
2022-08-21 19:18:53 +00:00
|
|
|
|
2022-09-01 18:16:16 +00:00
|
|
|
printf("Set used blocks to zero\n");
|
|
|
|
PMMInfoBlock->used_blocks = 0;
|
|
|
|
|
|
|
|
printf("Determine memory bit map address");
|
|
|
|
// put the map after the gdt
|
|
|
|
PMMInfoBlock->memoryBitMap = (uint32_t*) ( 0xC010b100) ;
|
2022-09-01 14:11:35 +00:00
|
|
|
|
|
|
|
printf("Maximum num blocks: %d \n",PMMInfoBlock->max_blocks);
|
|
|
|
//Size of memory map
|
|
|
|
uint32_t memMap_size = PMMInfoBlock->max_blocks / 8;
|
|
|
|
printf("Memory map size: %d\n", memMap_size);
|
|
|
|
printf("Address of memory map 0x%x\n", PMMInfoBlock->memoryBitMap);
|
2022-08-21 19:18:53 +00:00
|
|
|
// Set all places in memory as free
|
2022-09-01 14:11:35 +00:00
|
|
|
memset(PMMInfoBlock->memoryBitMap, 0xFF, memMap_size );
|
|
|
|
|
|
|
|
// Loop over memory map and allocate physical locations
|
|
|
|
// that are already in use
|
|
|
|
MemoryInfoBlock* currentBlock = (MemoryInfoBlock*) ((uint32_t)Bootinfo->MemoryMap + KERNEL_OFFSET) ;
|
|
|
|
printf("Starting address: 0x%x\n", currentBlock);
|
|
|
|
while( (uint32_t) currentBlock->next != 0x0)
|
|
|
|
{
|
|
|
|
if(IS_AVAILABLE_MEM(currentBlock->type)){
|
|
|
|
printf("skip!\n");
|
|
|
|
} else {
|
|
|
|
printf("allocate region 0x%x of size 0x%x\n" , currentBlock->Base_addr, currentBlock->Memory_Size);
|
|
|
|
allocate_region((uint32_t) currentBlock->Base_addr, currentBlock->Memory_Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
currentBlock = (MemoryInfoBlock*) ((uint32_t)currentBlock->next + KERNEL_OFFSET );
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t kernel_size = ((uint32_t)&kernel_end - (uint32_t)&kernel_begin ) - KERNEL_OFFSET;
|
|
|
|
|
|
|
|
printf("kernel size in memory: 0x%x\n", kernel_size);
|
|
|
|
allocate_region((uint32_t)&kernel_begin, kernel_size);
|
2022-09-01 14:42:56 +00:00
|
|
|
|
2022-09-01 18:16:16 +00:00
|
|
|
printf("allocate BIOS region\n");
|
2022-09-01 14:42:56 +00:00
|
|
|
allocate_region (0x0000000, 0x00100000);
|
2022-08-21 19:18:53 +00:00
|
|
|
}
|
|
|
|
|
2022-09-01 14:11:35 +00:00
|
|
|
// NOTE: This can only give blocks of 4kb at a time!
|
|
|
|
// We might at some point want to allocate multiple blocks at once.
|
2022-08-21 19:18:53 +00:00
|
|
|
void* allocate_block() {
|
|
|
|
uint8_t blocks_available = PMMInfoBlock->max_blocks - PMMInfoBlock->used_blocks;
|
|
|
|
// Are there any blocks available?
|
|
|
|
if( blocks_available <= 0)
|
|
|
|
{
|
|
|
|
printf("No blocks available. Blocks Delta: 0x%x\n", blocks_available);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find 1 free block somewhere
|
2022-09-01 14:11:35 +00:00
|
|
|
int free_block_index = bitmap_first_unset(PMMInfoBlock->memoryBitMap, PMMInfoBlock->max_blocks / 8 );
|
2022-08-21 19:18:53 +00:00
|
|
|
|
|
|
|
if(free_block_index == -1)
|
|
|
|
{
|
|
|
|
printf("Could not find a good block!\n");
|
|
|
|
// Could not find a block
|
|
|
|
return (void*)0xFFFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(free_block_index == 0)
|
|
|
|
printf("Somethings wrong!!!\n");
|
|
|
|
|
|
|
|
// Set the block to be used!
|
|
|
|
bitmap_unset(PMMInfoBlock->memoryBitMap, free_block_index);
|
|
|
|
// Increase the used_block count!
|
|
|
|
PMMInfoBlock->used_blocks++;
|
|
|
|
printf("used blocks: 0x%x\n", PMMInfoBlock->used_blocks);
|
|
|
|
// return the pointer to the physical address
|
|
|
|
return (void*) (BLOCK_SIZE * free_block_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void free_block(void* p) {
|
|
|
|
// If it is a null pointer we don't need to do anything.
|
|
|
|
if(p==0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// calculate the index into the bitmap
|
|
|
|
int index = ((uint32_t) p) / BLOCK_SIZE;
|
|
|
|
|
|
|
|
// set the block to be free
|
|
|
|
bitmap_set(PMMInfoBlock->memoryBitMap, index);
|
|
|
|
PMMInfoBlock->used_blocks--;
|
|
|
|
printf("used blocks: 0x%x, after free\n", PMMInfoBlock->used_blocks);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void allocate_region(uint32_t startAddress, uint32_t size) {
|
|
|
|
// every bit should be 4KiB
|
|
|
|
// every byte is 8*4KiB = 32KiB
|
|
|
|
|
|
|
|
int NumberOfBlocksToAllocate = ( size / 1024) / 4 / 8 + 1;
|
|
|
|
int startBlock = (startAddress / 1024) / 4 / 8 ;
|
|
|
|
|
2022-09-01 14:11:35 +00:00
|
|
|
|
2022-08-21 19:18:53 +00:00
|
|
|
for( int i = 0; i < NumberOfBlocksToAllocate; i++)
|
|
|
|
{
|
|
|
|
bitmap_unset(PMMInfoBlock->memoryBitMap, startBlock+ i);
|
|
|
|
PMMInfoBlock->used_blocks++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2022-09-01 14:11:35 +00:00
|
|
|
|
2022-08-21 19:18:53 +00:00
|
|
|
void deallocate_region(uint32_t StartAddress , uint32_t size ) {
|
2022-09-01 14:11:35 +00:00
|
|
|
// reverse of what happened in allocate_region
|
|
|
|
|
|
|
|
int NumberOfBlocks = (size / 1024) / 4 / 8 + 1;
|
|
|
|
int startBlock = (StartAddress / 1024) / 4 / 8;
|
|
|
|
|
|
|
|
for(int i = 0; i < NumberOfBlocks; i++)
|
|
|
|
{
|
|
|
|
bitmap_set(PMMInfoBlock->memoryBitMap, startBlock + i);
|
|
|
|
PMMInfoBlock->used_blocks --;
|
|
|
|
}
|
2022-08-21 19:18:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|