Merge into main the new state of the operating system/kernel #1
@ -38,11 +38,9 @@ extern "C" void kernel_main ()
 | 
			
		||||
extern "C" void early_main()
 | 
			
		||||
{
 | 
			
		||||
    init_serial();
 | 
			
		||||
    print_serial("Hello Higher half kernel!\n");
 | 
			
		||||
 | 
			
		||||
    kterm_init();
 | 
			
		||||
 | 
			
		||||
    printf("Allocated blocks: %d \n", GetUsedBlocks());
 | 
			
		||||
    printf("Allocated blocks: 0x%x \n", GetUsedBlocks());
 | 
			
		||||
 | 
			
		||||
    initGDT();
 | 
			
		||||
    init_idt();
 | 
			
		||||
@ -53,8 +51,12 @@ extern "C" void early_main()
 | 
			
		||||
 | 
			
		||||
    initHeap();
 | 
			
		||||
 | 
			
		||||
    printf("TRY ALLOCATING 4 BYTES\n");
 | 
			
		||||
    uint32_t* MyVariable = (uint32_t*) malloc(4); // allocate 4 bytes using my heap
 | 
			
		||||
    free(MyVariable);
 | 
			
		||||
 | 
			
		||||
    // test heap allocation
 | 
			
		||||
    /*
 | 
			
		||||
    
 | 
			
		||||
    struct KernelInfo {
 | 
			
		||||
        int bar;
 | 
			
		||||
        bool foo;
 | 
			
		||||
@ -64,9 +66,10 @@ extern "C" void early_main()
 | 
			
		||||
 | 
			
		||||
    MyInfo->bar = 6;
 | 
			
		||||
    MyInfo->foo = false;
 | 
			
		||||
 | 
			
		||||
    printf("bar contains %d\n", MyInfo->bar);
 | 
			
		||||
    free(MyInfo);
 | 
			
		||||
    */
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    printf("Enable Protected mode and jump to kernel main\n");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
#include "KernelHeap.h"
 | 
			
		||||
#include "VirtualMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
// Size of heap meta data is 5 bytes 
 | 
			
		||||
struct heap_block{
 | 
			
		||||
@ -11,7 +12,7 @@ heap_block* start ;
 | 
			
		||||
 | 
			
		||||
void* malloc(size_t size)
 | 
			
		||||
{
 | 
			
		||||
    printf("Received request for %d bytes of memory", size);
 | 
			
		||||
    printf("Received request for %d bytes of memory\n", size);
 | 
			
		||||
    heap_block* current = start;
 | 
			
		||||
 | 
			
		||||
    // look for a free block
 | 
			
		||||
@ -20,8 +21,21 @@ void* malloc(size_t size)
 | 
			
		||||
        if(current->Size >= size && current->Used == false )
 | 
			
		||||
        {
 | 
			
		||||
            // We found a spot 
 | 
			
		||||
            printf("Block found!\n");
 | 
			
		||||
 | 
			
		||||
            // Set the spot to in-use 
 | 
			
		||||
            current->Used = false;
 | 
			
		||||
            current->Used = true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // split the block 
 | 
			
		||||
            printf("Split block.\n");
 | 
			
		||||
            uint32_t oldSize = current->Size;
 | 
			
		||||
            current->Size = size;
 | 
			
		||||
 | 
			
		||||
            heap_block* new_block = current + sizeof(heap_block) + current->Size;
 | 
			
		||||
            new_block->Size = oldSize - ( sizeof(heap_block) + size);
 | 
			
		||||
            new_block->Used = false;
 | 
			
		||||
 | 
			
		||||
            // return the free address 
 | 
			
		||||
            // NOTE: added an offset from the initial address to accomodate for 
 | 
			
		||||
            // meta-data.
 | 
			
		||||
@ -36,6 +50,7 @@ void* malloc(size_t size)
 | 
			
		||||
    // probably ask the VMM for more 
 | 
			
		||||
    // TODO: ask for more memory | Extend kernel heap
 | 
			
		||||
    
 | 
			
		||||
    printf("ERROR: OUT OF HEAP MEMORY CONDITION IS NOT IMPLEMENTED. HEAP NEEDS TO BE EXTENDED!\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void free(void* addr)
 | 
			
		||||
@ -48,6 +63,26 @@ void free(void* addr)
 | 
			
		||||
 | 
			
		||||
void initHeap()
 | 
			
		||||
{
 | 
			
		||||
    // NOTE: What to do now??
 | 
			
		||||
    
 | 
			
		||||
    // put the start of our kernel heap 1 page after the kernel_end address
 | 
			
		||||
    // Lets calculate the address 
 | 
			
		||||
    printf("FIND SUITABLE HEAP_ADDRESS\n");
 | 
			
		||||
    uint32_t alligned_k_end = (uint32_t) &kernel_end + ((uint32_t)&kernel_end % BLOCK_SIZE == 0 ? 4096 : 0);
 | 
			
		||||
    uint32_t HEAP_ADDRESS = (uint32_t) alligned_k_end + 4096;
 | 
			
		||||
    printf("HEAP_ADDRESS: 0x%x\n", HEAP_ADDRESS);
 | 
			
		||||
 | 
			
		||||
    // NOTE: we can't check if the mapping has failed or not here!
 | 
			
		||||
    AllocatePage(HEAP_ADDRESS);
 | 
			
		||||
    start = (heap_block*) HEAP_ADDRESS;
 | 
			
		||||
    heap_size = 4096;
 | 
			
		||||
 | 
			
		||||
    printf("Clear heap\n");
 | 
			
		||||
    // Clear the heap 
 | 
			
		||||
    printf("set at 0x%x %d bytes to zero\n", start , heap_size);
 | 
			
		||||
    memset((void*)start, 0x00,  heap_size /4);
 | 
			
		||||
 | 
			
		||||
    printf("Init first heap block\n");
 | 
			
		||||
    // initialzie 
 | 
			
		||||
    start->Size = heap_size - sizeof(heap_block);
 | 
			
		||||
    start->Used = false;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
#include "./PhysicalMemoryManager.h"
 | 
			
		||||
#define BLOCK_SIZE 4092 
 | 
			
		||||
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
 | 
			
		||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
 | 
			
		||||
 | 
			
		||||
@ -28,7 +27,7 @@ void SetupPhysicalMemoryManager(uint32_t mapAddress, uint32_t memorySize )
 | 
			
		||||
    printf("Bitmap size: %d bytes\n",bitmap_size);
 | 
			
		||||
 | 
			
		||||
    // Set blocks used to zero
 | 
			
		||||
    used_blocks = 0;
 | 
			
		||||
    used_blocks = max_blocks;
 | 
			
		||||
    
 | 
			
		||||
    // set the address of the memory bitmap
 | 
			
		||||
    memoryBitMap = (uint32_t*) mapAddress;
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@
 | 
			
		||||
#include "../lib/mem.h"
 | 
			
		||||
#include "../bitmap.h"
 | 
			
		||||
 | 
			
		||||
#define BLOCK_SIZE 4092 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SetupPhysicalMemoryManager(uint32_t mapAddress, uint32_t memorySize);
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,16 @@
 | 
			
		||||
#include "VirtualMemoryManager.h"
 | 
			
		||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
 | 
			
		||||
 | 
			
		||||
extern uint32_t boot_page_directory[1024] ;
 | 
			
		||||
extern uint32_t boot_page_table[1024];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void flush_cr3(){
 | 
			
		||||
    asm volatile("movl %cr3, %ecx;"
 | 
			
		||||
	             "movl %ecx, %cr3");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void AllocatePage(uint32_t vaddr)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
@ -15,23 +22,31 @@ void AllocatePage(uint32_t vaddr)
 | 
			
		||||
    printf("Allocation happening at PDE: %d PTE: %d\n", PageDirectoryEntryIndex, PageTableEntryIndex);
 | 
			
		||||
 | 
			
		||||
    // check if the page directory entry is marked as present 
 | 
			
		||||
    if (boot_page_directory[PageDirectoryEntryIndex] & 0x1 ) {
 | 
			
		||||
 | 
			
		||||
        uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000 + 0xC0000000);
 | 
			
		||||
    if (boot_page_directory[PageDirectoryEntryIndex] & 0x1 ) 
 | 
			
		||||
    {
 | 
			
		||||
        printf("Directory entry is marked as present\n");
 | 
			
		||||
        uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000) ;
 | 
			
		||||
        page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset
 | 
			
		||||
        printf("Page table address: 0x%x\n", (uint32_t)page_table);
 | 
			
		||||
 | 
			
		||||
        // check if the page table entry is marked as present 
 | 
			
		||||
        if ( page_table[PageTableEntryIndex] & 0x1 )
 | 
			
		||||
        {   
 | 
			
		||||
            printf("page already present!\n");
 | 
			
		||||
            return;
 | 
			
		||||
        } else{
 | 
			
		||||
            printf("Mapping a physical page.\n");
 | 
			
		||||
            // Map the entry to a physical page
 | 
			
		||||
            page_table[PageTableEntryIndex] = (uint32_t)(allocate_block() + 0x3);
 | 
			
		||||
        } else{
 | 
			
		||||
            // mark page as present
 | 
			
		||||
            page_table[PageTableEntryIndex] =   0x3;
 | 
			
		||||
            flush_cr3();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        printf("Mapping a new page directory entry with a page table\n");
 | 
			
		||||
        // mark the page table as present and allocate a physical block for it
 | 
			
		||||
        boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)(allocate_block() + 0x3);
 | 
			
		||||
        flush_cr3();
 | 
			
		||||
   
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -56,7 +71,8 @@ void FreePage(uint32_t vaddr )
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Map (  uint32_t vaddr, uint32_t paddr)
 | 
			
		||||
 | 
			
		||||
void Immediate_Map (  uint32_t vaddr, uint32_t paddr)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
@ -66,7 +82,7 @@ void Map (  uint32_t vaddr, uint32_t paddr)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Unmap(uint32_t vaddr)
 | 
			
		||||
void Immediate_Unmap(uint32_t vaddr)
 | 
			
		||||
{
 | 
			
		||||
    // NOTE: I will implement lazy unmapping for now 
 | 
			
		||||
    uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,16 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "PhysicalMemoryManager.h"
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "../cpu.h"
 | 
			
		||||
#include "PhysicalMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SetupVMM();
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
void Immediate_Map(uint32_t p_addr, uint32_t v_addr);
 | 
			
		||||
void Immediate_Unmap (uint32_t v_addr);
 | 
			
		||||
 | 
			
		||||
// void Demand_map(uint32_t p_addr, uint32_t v_addr);
 | 
			
		||||
// void Demand_Unmap (uint32_t v_addr);
 | 
			
		||||
 | 
			
		||||
@ -11,13 +11,7 @@ extern "C" const uint32_t kernel_end;
 | 
			
		||||
#define IS_NVS_MEMORY(MEM_TYPE) MEM_TYPE & 0x8
 | 
			
		||||
#define IS_BADRAM_MEMORY(MEM_TYPE) MEM_TYPE & 0x10
 | 
			
		||||
           
 | 
			
		||||
struct MemoryInfoBlock {
 | 
			
		||||
    uint32_t Base_addr ;
 | 
			
		||||
    uint32_t Memory_Size;
 | 
			
		||||
    MemoryInfoBlock* next;
 | 
			
		||||
    uint8_t  type;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
struct BootInfoBlock {
 | 
			
		||||
    bool MapIsInvalid;
 | 
			
		||||
    uint32_t bootDeviceID ;
 | 
			
		||||
@ -33,9 +27,4 @@ struct BootInfoBlock {
 | 
			
		||||
 | 
			
		||||
    bool EnabledVBE;
 | 
			
		||||
 | 
			
		||||
    bool PhysicalMemoryMapAvailable;
 | 
			
		||||
    MemoryInfoBlock* MemoryMap;
 | 
			
		||||
    uint32_t map_size;
 | 
			
		||||
    uint32_t MemorySize ;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -56,20 +56,3 @@ void print_serial(const char* string ){
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_serial(){
 | 
			
		||||
        /** Serial test **/
 | 
			
		||||
        kterm_writestring("Writing to COM1 serial port:");
 | 
			
		||||
        init_serial();
 | 
			
		||||
        write_serial('A');
 | 
			
		||||
        write_serial('B');
 | 
			
		||||
        write_serial('C');
 | 
			
		||||
        write_serial('D');
 | 
			
		||||
        write_serial('E');
 | 
			
		||||
 | 
			
		||||
        char Character_received = read_serial();
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
        kterm_writestring("received from COM 1: \n");
 | 
			
		||||
        kterm_put(Character_received);
 | 
			
		||||
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user