src folder -> source folder; makes merging with dev a bit easier.
This commit is contained in:
43
source/kernel/memory/PageDirectory.cpp
Normal file
43
source/kernel/memory/PageDirectory.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "PageDirectory.h"
|
||||
|
||||
void PageDirectory::enable()
|
||||
{
|
||||
|
||||
|
||||
// https://wiki.osdev.org/Setting_Up_Paging
|
||||
//set each entry to not present
|
||||
// int i;
|
||||
// for(i = 0; i < 1024; i++)
|
||||
// {
|
||||
// // This sets the following flags to the pages:
|
||||
// // Supervisor: Only kernel-mode can access them
|
||||
// // Write Enabled: It can be both read from and written to
|
||||
// // Not Present: The page table is not present
|
||||
// this->page_directory[i] = 0x00000002;
|
||||
// }
|
||||
|
||||
// // holds the physical address where we want to start mapping these pages to.
|
||||
// // in this case, we want to map these pages to the very beginning of memory.
|
||||
|
||||
// //we will fill all 1024 entries in the table, mapping 4 megabytes
|
||||
// for(unsigned int i = 0; i < 1024; i++)
|
||||
// {
|
||||
// // As the address is page aligned, it will always leave 12 bits zeroed.
|
||||
// // Those bits are used by the attributes ;)
|
||||
// first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
|
||||
// }
|
||||
|
||||
// // attributes: supervisor level, read/write, present
|
||||
// this->page_directory[0] = ((unsigned int)first_page_table) | 3;
|
||||
|
||||
printf("Enable Paging!\n");
|
||||
|
||||
loadPageDirectory(this->page_directory);
|
||||
enablePaging();
|
||||
}
|
||||
|
||||
|
||||
void PageDirectory::MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size )
|
||||
{
|
||||
|
||||
}
|
31
source/kernel/memory/PageDirectory.h
Normal file
31
source/kernel/memory/PageDirectory.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "./memory.h"
|
||||
#include "./../tty/kterm.h"
|
||||
#define KB 1024
|
||||
|
||||
|
||||
typedef uintptr_t address_t;
|
||||
|
||||
static const int MAX_PAGES = 1024 * KB; // 4GB , 4kB/page
|
||||
static volatile address_t pmem_stack[MAX_PAGES];
|
||||
static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation
|
||||
|
||||
extern "C" void loadPageDirectory (uint32_t* addr );
|
||||
extern "C" void enablePaging();
|
||||
|
||||
struct page_directory_entry {};
|
||||
struct page_table_entry{};
|
||||
|
||||
|
||||
|
||||
class PageDirectory {
|
||||
public:
|
||||
void enable ();
|
||||
void MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size );
|
||||
|
||||
private:
|
||||
uint32_t page_directory[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages
|
||||
uint32_t first_page_table[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages
|
||||
|
||||
};
|
142
source/kernel/memory/memory.cpp
Normal file
142
source/kernel/memory/memory.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "./memory.h"
|
||||
uint32_t* memoryBitMap;
|
||||
/*
|
||||
|
||||
*/
|
||||
void PhysicalMemory::setup( MemoryInfo* memory) {
|
||||
|
||||
// calculate the maximum number of blocks
|
||||
max_blocks = KB_TO_BLOCKS(memory->TotalMemory);
|
||||
|
||||
used_blocks = 0;
|
||||
|
||||
memoryBitMap = (uint32_t*) 0x00a00000;
|
||||
|
||||
|
||||
printf("Maximum Number of blocks: 0x%x, Number of bytes for memMap: 0x%x\n", max_blocks , (max_blocks/8));
|
||||
|
||||
//Size of memory map
|
||||
uint32_t memMap_size = (max_blocks / 8 ) ;
|
||||
|
||||
printf("Memory Map size: 0x%x\n", memMap_size );
|
||||
printf("size of int in bytes: 0x%x \n" , sizeof(int));
|
||||
|
||||
// Set all places in memory as free
|
||||
memset(memoryBitMap, 0xFF, memMap_size );
|
||||
}
|
||||
|
||||
// NOTE: this can only give blocks of 4kb at a time!
|
||||
void* PhysicalMemory::allocate_block() {
|
||||
uint8_t blocks_available = max_blocks - 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
|
||||
int free_block_index = bitmap_first_unset(memoryBitMap, (max_blocks /8) /*memMap Size*/ );
|
||||
|
||||
|
||||
|
||||
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(memoryBitMap, free_block_index);
|
||||
// Increase the used_block count!
|
||||
used_blocks++;
|
||||
printf("used blocks: 0x%x\n", used_blocks);
|
||||
// return the pointer to the physical address
|
||||
return (void*) (BLOCK_SIZE * free_block_index);
|
||||
}
|
||||
|
||||
|
||||
void PhysicalMemory::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(memoryBitMap, index);
|
||||
used_blocks--;
|
||||
printf("used blocks: 0x%x, after free\n", used_blocks);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PhysicalMemory::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 ;
|
||||
|
||||
// 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(memoryBitMap, startBlock+ i);
|
||||
used_blocks++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void PhysicalMemory::deallocate_region(uint32_t StartAddress , uint32_t size ) {
|
||||
// NOT IMPLEMENTED YET
|
||||
}
|
||||
|
||||
|
||||
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt) {
|
||||
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
|
||||
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
|
||||
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
|
||||
|
||||
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
|
||||
|
||||
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
|
||||
|
||||
memInfo->TotalMemory += mmap->len;
|
||||
} else {
|
||||
memInfo->ReservedMemory += mmap->len;
|
||||
}
|
||||
|
||||
print_Multiboot_memory_Map(mmap);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Debug Verbose functions
|
||||
*
|
||||
* @param mmap
|
||||
*/
|
||||
|
||||
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap) {
|
||||
printf(
|
||||
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
|
||||
(unsigned) mmap->size,
|
||||
(unsigned) (mmap->addr >> 32),
|
||||
(unsigned) (mmap->addr & 0xffffffff),
|
||||
(unsigned) (mmap->len >> 32),
|
||||
(unsigned) (mmap->len & 0xffffffff),
|
||||
(unsigned) mmap->type
|
||||
);
|
||||
}
|
||||
|
48
source/kernel/memory/memory.h
Normal file
48
source/kernel/memory/memory.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "memoryinfo.h"
|
||||
#include "../bootloader/multiboot.h"
|
||||
#include "../tty/kterm.h"
|
||||
#include "../../libc/include/mem.h"
|
||||
#include "../kstructures/bitmap.h"
|
||||
|
||||
#define BLOCK_SIZE 4092
|
||||
#define BLOCKS_PER_WORD 32 // A word is 16 bit in x86 machines according to my google search results!
|
||||
|
||||
#define KB_TO_BLOCKS(x) (x / BLOCK_SIZE)
|
||||
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
|
||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
|
||||
|
||||
extern uint32_t kernel_begin;
|
||||
extern uint32_t kernel_end;
|
||||
|
||||
void initialise_available_regions(uint32_t memoryMapAddr, uint32_t memoryMapLastAddr, uint32_t* memoryBitMap, int* used_blocks);
|
||||
|
||||
extern uint32_t* memoryBitMap;
|
||||
|
||||
class PhysicalMemory
|
||||
{
|
||||
public:
|
||||
void setup(MemoryInfo* memory);
|
||||
void destroy();
|
||||
void free_block(void* ptr);
|
||||
void* allocate_block();
|
||||
void allocate_region(uint32_t, uint32_t);
|
||||
void deallocate_region(uint32_t , uint32_t );
|
||||
|
||||
private:
|
||||
size_t pmmap_size;
|
||||
size_t max_blocks;
|
||||
int used_blocks;
|
||||
};
|
||||
|
||||
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt);
|
||||
|
||||
/**
|
||||
* @brief Debug Verbose Functions
|
||||
*
|
||||
* @param mmap
|
||||
*/
|
||||
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap);
|
20
source/kernel/memory/memoryinfo.h
Normal file
20
source/kernel/memory/memoryinfo.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct MemoryArea{
|
||||
void* StartAddress;
|
||||
size_t Size;
|
||||
unsigned int type;
|
||||
MemoryArea* Next;
|
||||
|
||||
}__attribute__((packed));
|
||||
|
||||
struct MemoryInfo {
|
||||
uint32_t TotalMemory;
|
||||
uint32_t ReservedMemory;
|
||||
MemoryArea* MemoryRegionList;
|
||||
}__attribute__((packed));
|
||||
|
||||
|
||||
|
20
source/kernel/memory/paging.s
Normal file
20
source/kernel/memory/paging.s
Normal file
@ -0,0 +1,20 @@
|
||||
.globl enablePaging
|
||||
enablePaging:
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
mov %cr0, %eax
|
||||
or $0x80000000, %eax
|
||||
mov %eax, %cr0
|
||||
mov %ebp, %esp
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
.globl loadPageDirectory
|
||||
loadPageDirectory:
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
mov 8(%esp), %eax
|
||||
mov %eax, %cr3
|
||||
mov %ebp, %esp
|
||||
pop %ebp
|
||||
ret
|
Reference in New Issue
Block a user