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 
 | 
			
		||||
 | 
			
		||||
SRC_DIR = src
 | 
			
		||||
SRC_DIR = source
 | 
			
		||||
BUILD_DIR = build
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
$(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:
 | 
			
		||||
	$(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:
 | 
			
		||||
	$(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))
 | 
			
		||||
        {
 | 
			
		||||
#ifdef  __VERBOSE__
 | 
			
		||||
            printf("cmdline = %s\n", (char *) mbi->cmdline);
 | 
			
		||||
            printf("cmdline = %s\n", (char *) (mbi->cmdline + 0xC0000000));
 | 
			
		||||
#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
 | 
			
		||||
                printf("========= Memory ==========\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);  
 | 
			
		||||
                const int bytesInGiB = 1073741824;
 | 
			
		||||
                int64_t bytesLeft = (bootinfo->memory->TotalMemory % bytesInGiB) / bytesInGiB;
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
#include "../time.h"
 | 
			
		||||
#include "../Drivers/PIT/pit.h"
 | 
			
		||||
#include "../Drivers/PS-2/keyboard.h"
 | 
			
		||||
#include "../Memory/memory.h"
 | 
			
		||||
#include "../Memory/PhysicalMemoryManager.h"
 | 
			
		||||
#include "../bootinfo.h"
 | 
			
		||||
 | 
			
		||||
void startSuperVisorTerminal(BootInfo * );
 | 
			
		||||
@ -1,11 +1,5 @@
 | 
			
		||||
#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){
 | 
			
		||||
 | 
			
		||||
    // 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 = {};
 | 
			
		||||
        bootinfo.memory = &meminfo;
 | 
			
		||||
 
 | 
			
		||||
        mapMultibootMemoryMap(bootinfo.memory , mbt);        
 | 
			
		||||
        ///mapMultibootMemoryMap(bootinfo.memory , mbt);        
 | 
			
		||||
        printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory );
 | 
			
		||||
 | 
			
		||||
       /*
 | 
			
		||||
@ -12,9 +12,9 @@ extern "C"
 | 
			
		||||
#include "multiboot.h"
 | 
			
		||||
#include "bootinfo.h"
 | 
			
		||||
 | 
			
		||||
#include "Memory/memory.h"
 | 
			
		||||
#include "Memory/PhysicalMemoryManager.h"
 | 
			
		||||
#include "Memory/memoryinfo.h"
 | 
			
		||||
#include "Memory/paging.h"
 | 
			
		||||
#include "Memory/VirtualMemoryManager.h"
 | 
			
		||||
#include "KernelLauncher/bootcheck.h"
 | 
			
		||||
 | 
			
		||||
#include "Memory/GDT/gdtc.h"
 | 
			
		||||
@ -32,3 +32,15 @@ extern "C"
 | 
			
		||||
#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&);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user