Merge into main the new state of the operating system/kernel #1
6
Makefile
6
Makefile
@ -7,7 +7,7 @@ CFLAGS = -ffreestanding -Og -ggdb -Wall -Wextra
|
|||||||
|
|
||||||
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/launcher.o
|
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/launcher.o
|
||||||
|
|
||||||
SRC_DIR = src
|
SRC_DIR = source
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
|
|
||||||
CRTBEGIN_OBJ = $(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
|
CRTBEGIN_OBJ = $(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
|
||||||
@ -99,10 +99,10 @@ $(BUILD_DIR)/sv-terminal.o:
|
|||||||
$(CPP) -c $(SRC_DIR)/kernel/SuperVisorTerminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CPP) -c $(SRC_DIR)/kernel/SuperVisorTerminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
$(BUILD_DIR)/memory.o:
|
$(BUILD_DIR)/memory.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/Memory/memory.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CPP) -c $(SRC_DIR)/kernel/Memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
$(BUILD_DIR)/paging.o:
|
$(BUILD_DIR)/paging.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/Memory/paging.cpp -o $(BUILD_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CPP) -c $(SRC_DIR)/kernel/Memory/VirtualMemoryManager.cpp -o $(BUILD_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
$(BUILD_DIR)/launcher.o:
|
$(BUILD_DIR)/launcher.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/KernelLauncher/launcher.cpp -o $(BUILD_DIR)/launcher.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CPP) -c $(SRC_DIR)/kernel/KernelLauncher/launcher.cpp -o $(BUILD_DIR)/launcher.o $(CFLAGS) -fno-exceptions -fno-rtti
|
@ -31,7 +31,7 @@ void CheckMBT ( multiboot_info_t* mbt ){
|
|||||||
if (CHECK_FLAG ( mbi->flags,2))
|
if (CHECK_FLAG ( mbi->flags,2))
|
||||||
{
|
{
|
||||||
#ifdef __VERBOSE__
|
#ifdef __VERBOSE__
|
||||||
printf("cmdline = %s\n", (char *) mbi->cmdline);
|
printf("cmdline = %s\n", (char *) (mbi->cmdline + 0xC0000000));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
51
source/kernel/Memory/KernelHeap.cpp
Normal file
51
source/kernel/Memory/KernelHeap.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "KernelHeap.h"
|
||||||
|
|
||||||
|
// Size of heap meta data is 5 bytes
|
||||||
|
struct heap_block{
|
||||||
|
uint8_t Used;
|
||||||
|
uint32_t Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t heap_size;
|
||||||
|
heap_block* start ;
|
||||||
|
|
||||||
|
void* malloc(size_t size)
|
||||||
|
{
|
||||||
|
printf("Received request for %d bytes of memory", size);
|
||||||
|
heap_block* current = start;
|
||||||
|
|
||||||
|
while(current < start + heap_size)
|
||||||
|
{
|
||||||
|
if(current->size >= size && current->Used == false )
|
||||||
|
{
|
||||||
|
// We found a spot
|
||||||
|
// Set the spot to in-use
|
||||||
|
current->Used = false;
|
||||||
|
// return the free address
|
||||||
|
// NOTE: added an offset from the initial address to accomodate for
|
||||||
|
// meta-data.
|
||||||
|
return current + sizeof(heap_block);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
current += current->Size + sizeof(heap_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are here we need more memory so we should
|
||||||
|
// probably ask the VMM for more
|
||||||
|
// TODO: ask for more memory
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void* addr)
|
||||||
|
{
|
||||||
|
// clear the free boolean that corresponds to this adddress
|
||||||
|
// This should be fairly simple
|
||||||
|
heap_block* allocatedBlock = addr - sizeof(heap_block);
|
||||||
|
allocate_block->Used = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initHeap()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
9
source/kernel/Memory/KernelHeap.h
Normal file
9
source/kernel/Memory/KernelHeap.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
void initHeap();
|
||||||
|
|
||||||
|
void* malloc (size_t size );
|
||||||
|
void free(void* addr);
|
||||||
|
|
43
source/kernel/Memory/MBIMMap/MBI_MMap.cpp
Normal file
43
source/kernel/Memory/MBIMMap/MBI_MMap.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include "MBI_MMap.h"
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
16
source/kernel/Memory/MBIMMap/MBI_MMap.h
Normal file
16
source/kernel/Memory/MBIMMap/MBI_MMap.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "../../multiboot.h"
|
||||||
|
#include "../memoryinfo.h"
|
||||||
|
|
||||||
|
void initialise_available_regions(uint32_t memoryMapAddr, uint32_t memoryMapLastAddr, uint32_t* memoryBitMap, 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);
|
102
source/kernel/Memory/PhysicalMemoryManager.cpp
Normal file
102
source/kernel/Memory/PhysicalMemoryManager.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include "./PhysicalMemoryManager.h"
|
||||||
|
|
||||||
|
PhysicalMemoryManagerInfoBlock* PMMInfoBlock;
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
// calculate the maximum number of blocks
|
||||||
|
PMMInfoBlock->max_blocks = KB_TO_BLOCKS(memory->TotalMemory);
|
||||||
|
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));
|
||||||
|
|
||||||
|
//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));
|
||||||
|
|
||||||
|
// Set all places in memory as free
|
||||||
|
memset(PMMInfoBlock->memoryBitMap, 0xFF, memMap_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: this can only give blocks of 4kb at a time!
|
||||||
|
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
|
||||||
|
int free_block_index = bitmap_first_unset(PMMInfoBlock->memoryBitMap, (PMMInfoBlock->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(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 ;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
30
source/kernel/Memory/PhysicalMemoryManager.h
Normal file
30
source/kernel/Memory/PhysicalMemoryManager.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "memoryinfo.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
|
||||||
|
|
||||||
|
#define KB_TO_BLOCKS(x) (x / BLOCK_SIZE)
|
||||||
|
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
|
||||||
|
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
|
||||||
|
|
||||||
|
struct PhysicalMemoryManagerInfoBlock
|
||||||
|
{
|
||||||
|
uint32_t* memoryBitMap;
|
||||||
|
size_t pmmap_size;
|
||||||
|
size_t max_blocks;
|
||||||
|
int used_blocks;
|
||||||
|
};
|
||||||
|
|
||||||
|
void initPMM(MemoryInfo* memory);
|
||||||
|
void free_block(void* ptr);
|
||||||
|
void* allocate_block();
|
||||||
|
void allocate_region(uint32_t, uint32_t);
|
||||||
|
void deallocate_region(uint32_t , uint32_t );
|
24
source/kernel/Memory/VirtualMemoryManager.cpp
Normal file
24
source/kernel/Memory/VirtualMemoryManager.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "VirtualMemoryManager.h"
|
||||||
|
|
||||||
|
extern "C" void loadPageDirectory (uint32_t* addr );
|
||||||
|
extern "C" void enablePaging();
|
||||||
|
|
||||||
|
void AllocatePage(uint32_t vaddr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreePage(uint32_t vaddr )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map ( uint32_t vaddr, uint32_t paddr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unmap(uint32_t vaddr)
|
||||||
|
{
|
||||||
|
// NOTE: I will implement lazy unmapping for now
|
||||||
|
}
|
12
source/kernel/Memory/VirtualMemoryManager.h
Normal file
12
source/kernel/Memory/VirtualMemoryManager.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "PhysicalMemoryManager.h"
|
||||||
|
#include "../Terminal/kterm.h"
|
||||||
|
#include "../cpu.h"
|
||||||
|
|
||||||
|
void AllocatePage(uint32_t v_addr );
|
||||||
|
void FreePage(uint32_t v_addr);
|
||||||
|
|
||||||
|
void Map(uint32_t p_addr, uint32_t v_addr);
|
||||||
|
void Unmap (uint32_t v_addr);
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ void startSuperVisorTerminal(BootInfo* bootinfo){
|
|||||||
// Show memory layout
|
// Show memory layout
|
||||||
printf("========= Memory ==========\n");
|
printf("========= Memory ==========\n");
|
||||||
printf("Kernel MemoryMap:\n");
|
printf("Kernel MemoryMap:\n");
|
||||||
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
|
//printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
|
||||||
printf("Frames used: 0x%x blocks of 4 KiB\n", 0);
|
printf("Frames used: 0x%x blocks of 4 KiB\n", 0);
|
||||||
const int bytesInGiB = 1073741824;
|
const int bytesInGiB = 1073741824;
|
||||||
int64_t bytesLeft = (bootinfo->memory->TotalMemory % bytesInGiB) / bytesInGiB;
|
int64_t bytesLeft = (bootinfo->memory->TotalMemory % bytesInGiB) / bytesInGiB;
|
@ -3,7 +3,7 @@
|
|||||||
#include "../time.h"
|
#include "../time.h"
|
||||||
#include "../Drivers/PIT/pit.h"
|
#include "../Drivers/PIT/pit.h"
|
||||||
#include "../Drivers/PS-2/keyboard.h"
|
#include "../Drivers/PS-2/keyboard.h"
|
||||||
#include "../Memory/memory.h"
|
#include "../Memory/PhysicalMemoryManager.h"
|
||||||
#include "../bootinfo.h"
|
#include "../bootinfo.h"
|
||||||
|
|
||||||
void startSuperVisorTerminal(BootInfo * );
|
void startSuperVisorTerminal(BootInfo * );
|
@ -1,11 +1,5 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
|
||||||
void map_multiboot_info_structure(unsigned long addr);
|
|
||||||
extern "C" void kernel_main (BootInfo* bootinfo);
|
|
||||||
extern "C" uint32_t boot_page_directory;
|
|
||||||
extern "C" uint32_t multiboot_page_table;
|
|
||||||
|
|
||||||
const uint32_t KERNEL_BASE_ADDR = 0xC0000000;
|
|
||||||
extern "C" void early_main(unsigned long magic, unsigned long addr){
|
extern "C" void early_main(unsigned long magic, unsigned long addr){
|
||||||
|
|
||||||
// Convert MBI address to higher quarter kernel space
|
// Convert MBI address to higher quarter kernel space
|
||||||
@ -63,7 +57,7 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){
|
|||||||
MemoryInfo meminfo = {};
|
MemoryInfo meminfo = {};
|
||||||
bootinfo.memory = &meminfo;
|
bootinfo.memory = &meminfo;
|
||||||
|
|
||||||
mapMultibootMemoryMap(bootinfo.memory , mbt);
|
///mapMultibootMemoryMap(bootinfo.memory , mbt);
|
||||||
printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory );
|
printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory );
|
||||||
|
|
||||||
/*
|
/*
|
@ -12,9 +12,9 @@ extern "C"
|
|||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
#include "bootinfo.h"
|
#include "bootinfo.h"
|
||||||
|
|
||||||
#include "Memory/memory.h"
|
#include "Memory/PhysicalMemoryManager.h"
|
||||||
#include "Memory/memoryinfo.h"
|
#include "Memory/memoryinfo.h"
|
||||||
#include "Memory/paging.h"
|
#include "Memory/VirtualMemoryManager.h"
|
||||||
#include "KernelLauncher/bootcheck.h"
|
#include "KernelLauncher/bootcheck.h"
|
||||||
|
|
||||||
#include "Memory/GDT/gdtc.h"
|
#include "Memory/GDT/gdtc.h"
|
||||||
@ -32,3 +32,15 @@ extern "C"
|
|||||||
#define PANIC(message) {return;}
|
#define PANIC(message) {return;}
|
||||||
|
|
||||||
|
|
||||||
|
void map_multiboot_info_structure(unsigned long addr);
|
||||||
|
|
||||||
|
extern "C" void kernel_main (BootInfo* bootinfo);
|
||||||
|
|
||||||
|
extern "C" const void* kernel_begin;
|
||||||
|
extern "C" const void* kernel_end;
|
||||||
|
|
||||||
|
extern "C" uint32_t boot_page_directory;
|
||||||
|
extern "C" uint32_t multiboot_page_table;
|
||||||
|
|
||||||
|
|
||||||
|
const uint32_t KERNEL_BASE_ADDR = 0xC0000000;
|
@ -1,2 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
|||||||
#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*) 0xCCA00000;
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "memoryinfo.h"
|
|
||||||
#include "../multiboot.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
|
|
||||||
|
|
||||||
#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);
|
|
@ -1,171 +0,0 @@
|
|||||||
#include "paging.h"
|
|
||||||
// PageDirectoryEntry kernel_directory[MAX_DIRECTORY_ENTRIES]__attribute__((aligned(4096)));
|
|
||||||
// PageTableEntry first_page_table[MAX_PAGE_TABLE_ENTRIES]__attribute__((aligned(4096)));
|
|
||||||
|
|
||||||
void IdentityMap (){
|
|
||||||
printf("\nInit paging\n");
|
|
||||||
// The basics as explained by wiki.osdev.org
|
|
||||||
|
|
||||||
// Set all page_directories to not present
|
|
||||||
int i = 0;
|
|
||||||
while ( i < 1024)
|
|
||||||
{
|
|
||||||
// kernel_directory[i] = 0x2;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// map 4 megabytes
|
|
||||||
unsigned int j ;
|
|
||||||
for( j = 0; j < 1024; j++ )
|
|
||||||
{
|
|
||||||
// first_page_table[j] = (j * 0x1000) | 3 ;
|
|
||||||
|
|
||||||
//Attributes:
|
|
||||||
//Supervisor Level ,
|
|
||||||
//read/write,
|
|
||||||
//present,
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put the page table in the page directory
|
|
||||||
// attributes: supervisor level, read/write, present;
|
|
||||||
// kernel_directory[0] = ((unsigned int)first_page_table) | 3;
|
|
||||||
|
|
||||||
printf("Init paging DONE\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializePaging()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Initial kernel page directory
|
|
||||||
set all page tables to not present
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_DIRECTORY_ENTRIES; i++)
|
|
||||||
{
|
|
||||||
// kernel_directory[i] = 0x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BIOS Address Identity mapping
|
|
||||||
// Identity map the first 8MiB ... Physical addresses 0x00000000 to 0x007A1200
|
|
||||||
PHYSICAL_ADDRESS BIOSAddr = 0x00000000;
|
|
||||||
PHYSICAL_ADDRESS BIOSAddr_Max = 0x800000;
|
|
||||||
|
|
||||||
// How many PDE's do we need
|
|
||||||
uint8_t NUM_PDE = BIOSAddr_Max / (4 * 1024 * 1024);
|
|
||||||
|
|
||||||
printf("The first 8MiB require %d Page Directory Entries\n", NUM_PDE);
|
|
||||||
|
|
||||||
|
|
||||||
for( int i = 0; i < NUM_PDE; i++)
|
|
||||||
{
|
|
||||||
// setup a page table
|
|
||||||
// PageTableEntry pagetable[MAX_PAGE_TABLE_ENTRIES] = PhysicalMemory::allocate_block(); // TODO :: Physical memory manager functions should be available here.
|
|
||||||
|
|
||||||
for(int j = 0; j < MAX_PAGE_TABLE_ENTRIES; j++)
|
|
||||||
{
|
|
||||||
// pagetable[j] = ( j * 4096 ) | 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add page table as page directory entry
|
|
||||||
// kernel_directory[i] = ( (unsigned int) pagetable ) | 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// map the kernel space
|
|
||||||
VIRTUAL_ADDRESS Vaddr = KERNEL_VRT_MEMORY_BEGIN;
|
|
||||||
PHYSICAL_ADDRESS KernelAddr = kernel_begin;
|
|
||||||
PHYSICAL_ADDRESS KernelEndAddr = kernel_end;
|
|
||||||
|
|
||||||
uint32_t KernelSizeInBytes = (KernelEndAddr - KernelAddr);
|
|
||||||
printf("Kernel is 0x%x bytes\n", KernelSizeInBytes);
|
|
||||||
NUM_PDE = KernelSizeInBytes / (4 * 1024* 1024);
|
|
||||||
printf("Kernel requires %d Page Directory Entries\n", NUM_PDE);
|
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < NUM_PDE; i++)
|
|
||||||
{
|
|
||||||
// PageTableEntry pageTable [MAX_PAGE_TABLE_ENTRIES] = PhysicalMemory::allocate_block();
|
|
||||||
|
|
||||||
for(int j = 0; j < MAX_PAGE_TABLE_ENTRIES; j++)
|
|
||||||
{
|
|
||||||
// pageTable[j] = ( j * 4096) | 3; // NOTE: Check if page is actually supposed to be present
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Calculate Page Directory index
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Identity map VGA memory
|
|
||||||
// Calc which PDE adn
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AllocatePage(VIRTUAL_ADDRESS vaddr, PageDirectoryEntry& page_directory)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreePage(VIRTUAL_ADDRESS vaddr , PageDirectoryEntry& page_directory)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Map ( PHYSICAL_ADDRESS paddr, VIRTUAL_ADDRESS vaddr, PageDirectoryEntry& page_directory)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unmap(VIRTUAL_ADDRESS vaddr, PageDirectoryEntry& page_directory)
|
|
||||||
{
|
|
||||||
// NOTE: I will implement lazy unmapping for now
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Enable()
|
|
||||||
{
|
|
||||||
|
|
||||||
//TODO: Write protect will not be turned on
|
|
||||||
// for the moment altough according to the intel
|
|
||||||
// developer manual this should happen.
|
|
||||||
|
|
||||||
uint32_t CR0;
|
|
||||||
|
|
||||||
CR0 = GetCR0();
|
|
||||||
printf("PG bit = %d \n" , GET_PG_BIT(CR0));
|
|
||||||
|
|
||||||
// printf("Load into CR3 address: 0x%x\n", (uint32_t)(&kernel_directory[0]));
|
|
||||||
// loadPageDirectory(&kernel_directory[0]);
|
|
||||||
// enablePaging();
|
|
||||||
|
|
||||||
printf("Paging enabled!\n");
|
|
||||||
|
|
||||||
|
|
||||||
CR0 = GetCR0();
|
|
||||||
uint32_t CR4 = GetCR4();
|
|
||||||
printf("PG bit = %d\n" , GET_PG_BIT(CR0) );
|
|
||||||
printf("PAE bit = %d\n", GET_PAE_BIT(CR4));
|
|
||||||
|
|
||||||
if(GET_PAE_BIT(CR4) == 0){
|
|
||||||
printf("Using 32bit paging\n");
|
|
||||||
|
|
||||||
if(GET_PSE_BIT(CR4) == 0 ){
|
|
||||||
printf("Page size is 4KiB\n");
|
|
||||||
} else {
|
|
||||||
printf("Page size is 4MiB\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("Using some extended version for paging\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "memory.h"
|
|
||||||
#include "paging.definitions.h"
|
|
||||||
#include "../Terminal/kterm.h"
|
|
||||||
#include "../cpu.h"
|
|
||||||
|
|
||||||
extern "C" void loadPageDirectory (uint32_t* addr );
|
|
||||||
extern "C" void enablePaging();
|
|
||||||
|
|
||||||
|
|
||||||
void IdentityMap();
|
|
||||||
void InitializePaging();
|
|
||||||
|
|
||||||
void Enable();
|
|
||||||
|
|
||||||
void AllocatePage(VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
|
||||||
void FreePage(VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
|
||||||
|
|
||||||
void Map(PHYSICAL_ADDRESS, VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
|
||||||
void Unmap (VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user