KERNEL: Physical Page Frame allocation
Rewriting the setup to allow for physical memory allocation again to work.
This commit is contained in:
@ -51,7 +51,7 @@ void initGDT(){
|
||||
gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
|
||||
gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
|
||||
|
||||
|
||||
printf("GDT at address 0x%x, with an size of 0x%x bytes\n" , (unsigned int)GlobalDescriptorTable, sizeof(GlobalDescriptorTable));
|
||||
|
||||
LoadGlobalDescriptorTable();
|
||||
|
||||
|
@ -2,32 +2,61 @@
|
||||
|
||||
PhysicalMemoryManagerInfoBlock* PMMInfoBlock;
|
||||
|
||||
const uint32_t KERNEL_OFFSET = 0xC0000000;
|
||||
void SetupPhysicalMemoryManager( BootInfoBlock* Bootinfo) {
|
||||
|
||||
void initPMM( MemoryInfo* memory) {
|
||||
|
||||
// NOTE: Lets for now puts the Physical memoryManagerBlock at a random address
|
||||
// We'll think of a more proper solution a bit later
|
||||
PMMInfoBlock = (PhysicalMemoryManagerInfoBlock*) 0xCC900000;
|
||||
|
||||
PMMInfoBlock = (PhysicalMemoryManagerInfoBlock*) ((uint32_t)MemoryMapHeap_pptr + Bootinfo->map_size + 0xC0000000);
|
||||
|
||||
/*
|
||||
Every byte contains 8 pages
|
||||
A page is 4096 kib
|
||||
Every block (1 bit) represent an page
|
||||
*/
|
||||
// calculate the maximum number of blocks
|
||||
PMMInfoBlock->max_blocks = KB_TO_BLOCKS(memory->TotalMemory);
|
||||
PMMInfoBlock->max_blocks =Bootinfo->MemorySize / BLOCK_SIZE / 8;
|
||||
PMMInfoBlock->used_blocks = 0;
|
||||
PMMInfoBlock->memoryBitMap = (uint32_t*) 0xCCA00000;
|
||||
|
||||
printf("Maximum Number of blocks: 0x%x, Number of bytes for memMap: 0x%x\n", PMMInfoBlock->max_blocks , (PMMInfoBlock->max_blocks/8));
|
||||
// put the map after the gdt
|
||||
PMMInfoBlock->memoryBitMap = (uint32_t*) ( 0xC010b100) ;
|
||||
|
||||
// // Page in the address space please
|
||||
// uint32_t PDEI = 0xC020a000 >> 22;
|
||||
// uint32_t PTEI = (0xC020a000 >> 12) & 0x1FFF;
|
||||
// printf("PDEI: %d, PTEI: %d\n", PDEI, PTEI);
|
||||
|
||||
//Size of memory map
|
||||
uint32_t memMap_size = (PMMInfoBlock->max_blocks / 8 ) ;
|
||||
|
||||
printf("Memory Map size: 0x%x\n", memMap_size );
|
||||
printf("size of int in bytes: 0x%x \n" , sizeof(int));
|
||||
|
||||
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);
|
||||
// Set all places in memory as free
|
||||
memset(PMMInfoBlock->memoryBitMap, 0xFF, memMap_size );
|
||||
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);
|
||||
}
|
||||
|
||||
// NOTE: this can only give blocks of 4kb at a time!
|
||||
// NOTE: This can only give blocks of 4kb at a time!
|
||||
// We might at some point want to allocate multiple blocks at once.
|
||||
void* allocate_block() {
|
||||
uint8_t blocks_available = PMMInfoBlock->max_blocks - PMMInfoBlock->used_blocks;
|
||||
// Are there any blocks available?
|
||||
@ -38,10 +67,8 @@ void* allocate_block() {
|
||||
}
|
||||
|
||||
// Find 1 free block somewhere
|
||||
int free_block_index = bitmap_first_unset(PMMInfoBlock->memoryBitMap, (PMMInfoBlock->max_blocks /8) /*memMap Size*/ );
|
||||
int free_block_index = bitmap_first_unset(PMMInfoBlock->memoryBitMap, PMMInfoBlock->max_blocks / 8 );
|
||||
|
||||
|
||||
|
||||
if(free_block_index == -1)
|
||||
{
|
||||
printf("Could not find a good block!\n");
|
||||
@ -83,20 +110,27 @@ void allocate_region(uint32_t startAddress, uint32_t size) {
|
||||
int NumberOfBlocksToAllocate = ( size / 1024) / 4 / 8 + 1;
|
||||
int startBlock = (startAddress / 1024) / 4 / 8 ;
|
||||
|
||||
// printf("NumberOfBlocksToAllocate: 0x%x\n", NumberOfBlocksToAllocate);
|
||||
//printf( "start block: 0x%x\n" , startBlock);
|
||||
|
||||
for( int i = 0; i < NumberOfBlocksToAllocate; i++)
|
||||
{
|
||||
|
||||
//printf("ALLOCATE BLOCK: 0x%x\n" , startBlock + i );
|
||||
bitmap_unset(PMMInfoBlock->memoryBitMap, startBlock+ i);
|
||||
PMMInfoBlock->used_blocks++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void deallocate_region(uint32_t StartAddress , uint32_t size ) {
|
||||
// NOT IMPLEMENTED YET
|
||||
// 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 --;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,17 +1,13 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include "memoryinfo.h"
|
||||
|
||||
#include "../PreKernel/bootstructure.h"
|
||||
#include "../Terminal/kterm.h"
|
||||
#include "../Lib/mem.h"
|
||||
#include "../bitmap.h"
|
||||
|
||||
// Asumming 32 bit x86 for now!
|
||||
#define BLOCK_SIZE 4092
|
||||
#define WORD_SIZE 2
|
||||
#define BLOCKS_PER_WORD 32
|
||||
// Asumming i386 for now!
|
||||
#define BLOCK_SIZE 4092
|
||||
|
||||
#define KB_TO_BLOCKS(x) (x / BLOCK_SIZE)
|
||||
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
|
||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
|
||||
|
||||
@ -23,7 +19,7 @@ struct PhysicalMemoryManagerInfoBlock
|
||||
int used_blocks;
|
||||
};
|
||||
|
||||
void initPMM(MemoryInfo* memory);
|
||||
void SetupPhysicalMemoryManager(BootInfoBlock* memory);
|
||||
void free_block(void* ptr);
|
||||
void* allocate_block();
|
||||
void allocate_region(uint32_t, uint32_t);
|
||||
|
Reference in New Issue
Block a user