From b4cff3e667be4818a835f1cae28f0b9c65d251ac Mon Sep 17 00:00:00 2001 From: Nigel Date: Sat, 26 Feb 2022 20:44:16 +0100 Subject: [PATCH] Basic block allocation for physical memory allocation. - 1 block = 4096 bytes : because this will make page fault handling possibly somewhat easier - 1 byte in the bitmap = 8 blocks of physical memory unsure if the allocation is perfect ... guess i'll find out some day if this is actually correct. The bitmap needs 16kb to keep track of 2gb of physical memory. Seems a decent percentage to me. --- Makefile | 11 +- README.md | 3 +- features.md | 37 ++-- src/grub.cfg | 7 +- src/kernel/{boot.S => boot.s} | 0 src/kernel/bootinfo.h | 9 + src/kernel/definitions.h | 11 + src/kernel/kernel.cpp | 205 ++++++++++-------- src/kernel/kernel.h | 12 +- src/kernel/kstructures/bitmap.h | 28 +-- src/kernel/memory/PageDirectory.cpp | 58 +++-- src/kernel/memory/PageDirectory.h | 21 +- src/kernel/memory/PageFrameAllocator.cpp | 38 ---- src/kernel/memory/PageFrameAllocator.h | 20 -- src/kernel/memory/PhysicalMemoryManager.cpp | 118 ---------- src/kernel/memory/PhysicalMemoryManager.h | 34 --- src/kernel/memory/SlabAllocator.h | 33 --- src/kernel/memory/memory.cpp | 142 ++++++++++++ src/kernel/memory/memory.h | 48 ++++ src/kernel/memory/memoryinfo.h | 20 ++ src/kernel/sv-terminal/superVisorTerminal.cpp | 13 +- src/kernel/sv-terminal/superVisorTerminal.h | 5 +- src/libc/include/mem.h | 4 +- todo.md | 21 ++ 24 files changed, 472 insertions(+), 426 deletions(-) rename src/kernel/{boot.S => boot.s} (100%) create mode 100644 src/kernel/bootinfo.h create mode 100644 src/kernel/definitions.h delete mode 100644 src/kernel/memory/PageFrameAllocator.cpp delete mode 100644 src/kernel/memory/PageFrameAllocator.h delete mode 100644 src/kernel/memory/PhysicalMemoryManager.cpp delete mode 100644 src/kernel/memory/PhysicalMemoryManager.h delete mode 100644 src/kernel/memory/SlabAllocator.h create mode 100644 src/kernel/memory/memory.cpp create mode 100644 src/kernel/memory/memory.h create mode 100644 src/kernel/memory/memoryinfo.h diff --git a/Makefile b/Makefile index afdeb22..c1b4aa0 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc CPP = ${HOME}/opt/cross/bin/i686-elf-g++ CFLAGS = -ffreestanding -O2 -Wall -Wextra -OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/PageFrameAllocator.o +OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.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 SRC_DIR = src BUILD_DIR = build @@ -54,7 +54,7 @@ $(BUILD_DIR)/kterm.o: $(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti $(BUILD_DIR)/boot.o: - $(AS) $(SRC_DIR)/kernel//boot.S -o $(BUILD_DIR)/boot.o + $(AS) $(SRC_DIR)/kernel/boot.s -o $(BUILD_DIR)/boot.o $(BUILD_DIR)/crti.o: $(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o @@ -65,8 +65,6 @@ $(BUILD_DIR)/crtn.o: $(BUILD_DIR)/io.o: $(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti -$(BUILD_DIR)/PageDirectory.o: - $(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti $(BUILD_DIR)/idt.o: $(CPP) -c $(SRC_DIR)/kernel/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti @@ -81,8 +79,6 @@ $(BUILD_DIR)/pic.o: $(BUILD_DIR)/string.o: $(CC) -c $(SRC_DIR)/libc/include/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99 -$(BUILD_DIR)/PhysicalMemoryManager.o: - $(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti $(BUILD_DIR)/pit.o: $(CPP) -c $(SRC_DIR)/kernel/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti @@ -97,3 +93,6 @@ $(BUILD_DIR)/time.o: $(BUILD_DIR)/sv-terminal.o: $(CPP) -c $(SRC_DIR)/kernel/sv-terminal/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 diff --git a/README.md b/README.md index ee97592..2e5fbb6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Multiboot information can be read by the kernel. ________________________ ### The goal -Writing a hobby operating system to better understand the basic building blocks of any operating system. +Writing a hobby operating system to better understand the basic building blocks of any operating system.Initially I'd like for my +operating system to be able to run bash. ________________________ ### Operating System Technical specs/details diff --git a/features.md b/features.md index 53b1cf0..b704af2 100644 --- a/features.md +++ b/features.md @@ -1,29 +1,30 @@ # TODO list -## Start planning +## Basics Setup Cross-Compiler \ Multiboot to kernel \ Printing string to the screen \ - Printing values/numbers to the screen (a.k.k itoa) \ + Printing values/numbers to the screen \ + Basic Terminal \ Extend Multiboot implementation \ Output to serial port \ Move to protected mode \ Enabel CMOS clock \ - Time measurement (PIC &| PIT) \ + Time measurement (PIC &| PIT) \ Detect CPU speed \ Interrupt / exception system (API) \ - - Plan your memory map (virtual, and physical) : decide where you want the data to be. \ + PCI support \ + ATA PIO Mode support \ + FAT Filesystem \ + Virtual filesystem \ + Keyboard support ( P/S2 Keyboard) \ + Physical memory management \ + Paging \ + Virtual memory management \ The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \ Enable SIMD Extensions (SSE) -## Other features I am thinking of: - PCI support \ - ATA PIO Mode support \ - USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \ - ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \ - ATAPI support \ - Keyboard support ( P/S2 Keyboard) \ - Memory Management (MMU) + Hardware Management system + Preemptive multi tasking \ Processes \ Threads @@ -32,9 +33,11 @@ POSIX compliance (partially) \ RPC - for interprocess communication \ Sync primitives - Semaphores, Mutexes, spinlocks et al. \ - Basic Terminal \ - Extend hardware recognition ( CPU codename, memory, ATA harddisk, RAW diskSpace, CPU speed through SMBIOS et al. ) \ + + ACPI support \ + ATAPI support \ + +## Optional Basic Window server/client \ -## Support for more filesystems if I like the challenge in writing these ... - FAT Filesystem \ EXT2 Filesystem + USTAR Filesystem \ diff --git a/src/grub.cfg b/src/grub.cfg index 40431b9..27391d2 100644 --- a/src/grub.cfg +++ b/src/grub.cfg @@ -1,3 +1,8 @@ -menuentry "BarinkOS"{ +GRUB_DEFAULT=0 +GRUB_TIMEOUT=-1 +GRUB_HIDDEN_TIMEOUT=0 +GRUB_HIDDEN_TIMEOUT_QUITE=true + +menuentry "BarinkOS" { multiboot /boot/myos.bin } diff --git a/src/kernel/boot.S b/src/kernel/boot.s similarity index 100% rename from src/kernel/boot.S rename to src/kernel/boot.s diff --git a/src/kernel/bootinfo.h b/src/kernel/bootinfo.h new file mode 100644 index 0000000..575a048 --- /dev/null +++ b/src/kernel/bootinfo.h @@ -0,0 +1,9 @@ +#pragma once +#include "memory/memoryinfo.h" + + +struct BootInfo{ + const char* BootStructureID = "BarinkOS"; + MemoryInfo* memory; + +}; \ No newline at end of file diff --git a/src/kernel/definitions.h b/src/kernel/definitions.h new file mode 100644 index 0000000..1f99d57 --- /dev/null +++ b/src/kernel/definitions.h @@ -0,0 +1,11 @@ +#pragma once +/** + * Kernel definitions + */ + + + +#define __DEBUG__ false +#define KERNEL_VERSION 0 + +#define ARCHITECTURE "I386" diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 04c2ff1..9e78828 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -1,108 +1,123 @@ #include "kernel.h" -#define GB2 262144 - extern "C" void kernel_main (void); - - extern "C" void early_main(unsigned long magic, unsigned long addr){ - /** - * Initialize terminal interface - * NOTE: This should be done later on , the magic value should be checked first. - */ - kterm_init(); - - /** - * Check Multiboot magic number - * NOTE: Printf call should not be a thing this early on ... - */ - if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ - printf("Invalid magic number: 0x%x\n", magic); - return; - } +extern "C" void kernel_main (BootInfo* bootinfo) { + init_serial(); + pit_initialise(); - /** - * Show a little banner for cuteness - */ - printf("|=== BarinkOS ===|\n"); + startSuperVisorTerminal(bootinfo); +} - /** - * Use the address given as an argument as the pointer - * to a Multiboot information structure. - */ - multiboot_info_t* mbt = (multiboot_info_t*) addr; - - /* - If we got a memory map from our bootloader we - should be parsing it to find out the memory regions available. - */ - if (CHECK_FLAG(mbt->flags, 6)) - { - printf("Preliminary results mmap scan:\n"); - mapMultibootMemoryMap(mbt); - - PhysicalMemoryManager_initialise( mbt->mmap_addr, GB2/* Seriously dangerous hardcoded memory value*/); - PhysicalMemoryManager_initialise_available_regions(mbt->mmap_addr, mbt->mmap_addr + mbt->mmap_length); - PhysicalMemoryManager_deinitialise_kernel(); - } - - initGDT(); - init_idt(); - // Enable interrupts - asm volatile("STI"); - - - CheckMBT( (multiboot_info_t *) addr); - - - kernel_main(); - +extern "C" void early_main(unsigned long magic, unsigned long addr){ + /** + * Initialize terminal interface + * NOTE: This should be done later on , the magic value should be checked first. + */ + kterm_init(); + + /** + * Check Multiboot magic number + * NOTE: Printf call should not be a thing this early on ... + */ + if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ + printf("Invalid magic number: 0x%x\n", magic); + return; } - extern "C" void kernel_main (void) { - init_serial(); - pit_initialise(); - - while (true){ - - printf("SUPERVISOR:>$ " ); - int characterCount = 0; - char command[10] = ""; - - // NOTE: lets just show a kernel prompt - uint8_t ScanCode = getKey(); - while( ScanCode != 0x1C ) - { - char character = getASCIIKey(); - kterm_put(character ); - // wHAT THE HELL - - if( characterCount < 10 ){ - command[characterCount] = character; - characterCount++; - } - - ScanCode = getKey(); - } - printf("\n"); - KeyHandled(); - - - if ( strncmp("TIME", command , characterCount ) == 0 ) { - read_rtc(); - printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d (Ticks: %06d)\n" ,year, month, day, hour, minute, second, pit_tick); - } else if(strncmp("TEST", command, characterCount) == 0){ - // asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0 - } - else{ - printf("Unknown command\n"); - } + /** + * Show a little banner for cuteness + */ + printf("|=== BarinkOS ===|\n"); - delay(1000); - } - + /** + * Use the address given as an argument as the pointer + * to a Multiboot information structure. + */ + multiboot_info_t* mbt = (multiboot_info_t*) addr; + /** + * Construct our own bootInfo structure + */ + BootInfo bootinfo = {}; + + /* + If we got a memory map from our bootloader we + should be parsing it to find out the memory regions available. + */ + if (CHECK_FLAG(mbt->flags, 6)) + { - } + /* + Setup Physical memory managment + */ + MemoryInfo meminfo = {}; + bootinfo.memory = &meminfo; + + mapMultibootMemoryMap(bootinfo.memory , mbt); + printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory ); + + PhysicalMemory memAlloc = PhysicalMemory{}; + memAlloc.setup(bootinfo.memory ); + + /* + Mark already in use sections + */ + + // Mark kernel memory as used + printf("Kernel Begin Pointer: 0x%x, Kernel end pointer: 0x%x\n", kernel_begin , kernel_end ); + + 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){ + + } else{ + printf("allocate region: 0x%x, size : 0x%x bytes\n", (unsigned) mmap->addr,(unsigned) mmap->len ); + memAlloc.allocate_region((unsigned)mmap->addr , (unsigned)mmap->len); + } + + + } + + + printf("allocate region: 0x%x, size : 0x%x bytes\n", kernel_begin, kernel_end - kernel_begin ); + memAlloc.allocate_region(kernel_end, kernel_end - kernel_begin); + + // test alloc_block + + + uint8_t* memory = (uint8_t*) memAlloc.allocate_block(); + printf("Got a new pointer: 0x%x\n", memory); + + uint8_t* memory2 = (uint8_t*) memAlloc.allocate_block(); + printf("Got a new pointer: 0x%x\n", memory2); + + + memAlloc.free_block((void*) memory); + + uint8_t* newBlockPlse = (uint8_t*) memAlloc.allocate_block(); + + + + + // memAlloc.free_block((void*) memory); + + + } + + initGDT(); + init_idt(); + // Enable interrupts + asm volatile("STI"); + + + CheckMBT( (multiboot_info_t *) addr); + + + kernel_main(&bootinfo); + +} diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 63570b5..604c4ff 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -1,14 +1,20 @@ #pragma once -extern "C"{ +extern "C" +{ #include "../libc/include/string.h" } + +#include "definitions.h" + #include "vga/VBE.h" #include "tty/kterm.h" #include "./bootloader/multiboot.h" +#include "bootinfo.h" + +#include "memory/memory.h" +#include "memory/memoryinfo.h" #include "bootcheck.h" -#include "memory/physical/PhysicalMemoryManager.h" -#include "memory/frames/PageFrameAllocator.h" #include "gdt/gdtc.h" #include "idt/idt.h" diff --git a/src/kernel/kstructures/bitmap.h b/src/kernel/kstructures/bitmap.h index e4487fe..165266c 100644 --- a/src/kernel/kstructures/bitmap.h +++ b/src/kernel/kstructures/bitmap.h @@ -13,26 +13,26 @@ inline void bitmap_unset(uint32_t* map , int index) map[index/32] &= ~(1 << (index % 32)); } -inline int bitmap_first_unset( uint32_t* map , int size) +inline uint32_t bitmap_first_unset( uint32_t* map , int map_size) { - uint32_t rem_bits = size % 32; - for(uint32_t i = 0; i < size/32; i++) + for ( int i = 0 ; i < map_size ; i ++ ) { - if(map[i] != 0xFFFFFFFF){ - for(int j = 0; j < 32; j++){ - if(!(map[i] & (1<< j))){ - return (i*32) + j; + // a bit or more is set within this byte! + if( (map[i] & 0xFFFFFFFF) > 0 ){ + + // which bit is set? + for(int j = 0 ; j < 32 ; j++){ + if ( (map[i] & (0x00000001 << j)) > 0) + { + printf("Found bit: byte 0x%x , bit 0x%x\n", i , j); + return (i*32)+j; } } - } - } - if(rem_bits){ - for(uint32_t j = 0; j < rem_bits; j++){ - if(!(map[size/32] & (1 << j ))){ - return size + j; // Original author divided size by 32 and then multiplied it by 32 which is a net zero calculation ?!? - } + } + + } return -1; diff --git a/src/kernel/memory/PageDirectory.cpp b/src/kernel/memory/PageDirectory.cpp index f740680..5e4ab31 100644 --- a/src/kernel/memory/PageDirectory.cpp +++ b/src/kernel/memory/PageDirectory.cpp @@ -1,47 +1,43 @@ #include "PageDirectory.h" -#include + +void PageDirectory::enable() +{ - -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; - } + // 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. + // // 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. - } + // //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; + // // 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 IdentityPaging(uint32_t *first_pte, vaddr from, int size) + +void PageDirectory::MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size ) { - from = from & 0xFFFFF000; // Discard the bits we don't want - for (; size > 0; from += 4096, first_pte++) - { - *first_pte = from | 1; // makr page present. - } + } -*/ diff --git a/src/kernel/memory/PageDirectory.h b/src/kernel/memory/PageDirectory.h index a2863d3..c43c8fa 100644 --- a/src/kernel/memory/PageDirectory.h +++ b/src/kernel/memory/PageDirectory.h @@ -1,17 +1,18 @@ #pragma once #include - -extern "C" void loadPageDirectory (uint32_t* addr ); -extern "C" void enablePaging(); -typedef uintptr_t address_t; - - +#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{}; @@ -21,8 +22,10 @@ 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))); - uint32_t first_page_table[1024] __attribute__((aligned(4096))); + 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 + }; \ No newline at end of file diff --git a/src/kernel/memory/PageFrameAllocator.cpp b/src/kernel/memory/PageFrameAllocator.cpp deleted file mode 100644 index f34c282..0000000 --- a/src/kernel/memory/PageFrameAllocator.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "PageFrameAllocator.h" - - -MemoryInfo memInfo {}; -void mapMultibootMemoryMap( 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.memorySizeInBytes += mmap->len; - } else { - memInfo.reservedMemoryInBytes += mmap->len; - } - - print_Multiboot_memory_Map(mmap); - - } - uint32_t memorySizeInGiB = memInfo.memorySizeInBytes / 1073741824; - - printf("Available Memory: 0x%x bytes, 0x%x GiB\n", memInfo.memorySizeInBytes, memorySizeInGiB ); - printf("Reserved Memory: 0x%x bytes\n", memInfo.reservedMemoryInBytes ); - -} - -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 - ); -} \ No newline at end of file diff --git a/src/kernel/memory/PageFrameAllocator.h b/src/kernel/memory/PageFrameAllocator.h deleted file mode 100644 index 2b19180..0000000 --- a/src/kernel/memory/PageFrameAllocator.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include "../arch/i386/tty/kterm.h" - -#include -#include "../bootloader/multiboot.h" - -struct MemoryInfo{ - uint32_t memorySizeInBytes = 0; - uint32_t reservedMemoryInBytes = 0; -}; - - -extern void *kernel_begin; -extern void *kernel_end; - - - - -void print_Multiboot_memory_Map(multiboot_memory_map_t*); -void mapMultibootMemoryMap(multiboot_info_t*); \ No newline at end of file diff --git a/src/kernel/memory/PhysicalMemoryManager.cpp b/src/kernel/memory/PhysicalMemoryManager.cpp deleted file mode 100644 index 8e894ba..0000000 --- a/src/kernel/memory/PhysicalMemoryManager.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "PhysicalMemoryManager.h" - -size_t mem_size = 0; -int used_blocks = 0; -size_t max_blocks = 0; -uint32_t* pmmap = 0; -size_t pmmap_size = 0; - - -void PhysicalMemoryManager_initialise(uint32_t physicalmemorymap_address, size_t size ) -{ - mem_size = size; - max_blocks = KB_TO_BLOCKS(mem_size); - - used_blocks = max_blocks; - - pmmap = (uint32_t*) physicalmemorymap_address; - - if(max_blocks % BLOCKS_PER_WORD) - pmmap_size++; - - memset(pmmap, 0xFF, pmmap_size); -} - -void PhysicalMemoryManager_region_initialise(uint32_t base, size_t size) -{ - size_t blocks = size /BLOCK_SIZE; - uint32_t align = base / BLOCK_SIZE; - - for(size_t i = 0 ; i < blocks; i ++) - { - bitmap_unset(pmmap, align++); - used_blocks--; - } - - bitmap_set(pmmap, 0); - -} - -void PhysicalMemoryManager_region_deinitialise(uint32_t base, size_t size ) -{ - size_t blocks = size / BLOCK_SIZE; - uint32_t align = base / BLOCK_SIZE; - - for(size_t i = 0 ; i < blocks; i++ ) - { - bitmap_set(pmmap, align++); - used_blocks++; - } - - -} - -void PhysicalMemoryManager_initialise_available_regions(uint32_t mmap_, uint32_t mmap_end_) -{ - multiboot_memory_map_t *mmap = (multiboot_memory_map_t*)mmap_; - multiboot_memory_map_t *mmap_end= (multiboot_memory_map_t*) mmap_end_; - - for(int i = 0; mmap < mmap_end ; mmap++, i++) - { - if(mmap->type == MULTIBOOT_MEMORY_AVAILABLE) - { - PhysicalMemoryManager_region_initialise((uint32_t) mmap->addr, (size_t) mmap->len); - } - } - -} - -void PhysicalMemoryManager_deinitialise_kernel() -{ - extern uint8_t kernel_begin; - extern uint8_t kernel_end; - - size_t kernel_size = (size_t) &kernel_end - (size_t) &kernel_begin; - - uint32_t pmmap_size_aligned = pmmap_size; - if(!IS_ALIGNED(pmmap_size_aligned, BLOCK_SIZE)) - { - pmmap_size_aligned = ALIGN(pmmap_size_aligned, BLOCK_SIZE); - } - - PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_begin, kernel_size); - PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_end, pmmap_size_aligned); - -} - -void* PhysicalMemoryManager_allocate_block() -{ - if(used_blocks - max_blocks <= 0) - { - return 0; - } - - int p_index = bitmap_first_unset(pmmap, p_index ); - - if(p_index == -1){ - return 0; - } - - bitmap_set(pmmap, p_index); - used_blocks++; - - return (void*) (BLOCK_SIZE * p_index); -} - -void PhysicalMemoryManager_free_block(void* p){ - if(p==0){ - return ; - } - - uint32_t p_addr = (uint32_t) p; - - int index = p_addr / BLOCK_SIZE; - bitmap_unset(pmmap, index); - - used_blocks--; - -} \ No newline at end of file diff --git a/src/kernel/memory/PhysicalMemoryManager.h b/src/kernel/memory/PhysicalMemoryManager.h deleted file mode 100644 index 3adc1eb..0000000 --- a/src/kernel/memory/PhysicalMemoryManager.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "../bootloader/multiboot.h" -#include -#include -#include "../../libc/include/mem.h" -#include "../kstructures/bitmap.h" - - -#define BLOCK_SIZE 4092 -#define BLOCKS_PER_WORD 32 - -#define KB_TO_BLOCKS(x) (((x) * 1024 ) / BLOCK_SIZE) -#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1)) -#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align)) - - -extern void PhysicalMemoryManager_initialise(uint32_t, size_t); - -extern void PhysicalMemoryManager_region_initialise(uint32_t, size_t); -extern void PhysicalMemoryManager_region_deinitialise(uint32_t,size_t); - -extern void PhysicalMemoryManager_initialise_available_regions(uint32_t, uint32_t); -extern void PhysicalMemoryManager_deinitialise_kernel(); - -extern void* PhysicalMemoryManager_allocate_block(); -extern void PhysicalMemoryManager_free_block(void* p); - - -extern size_t mem_size; -extern int used_blocks; -extern size_t max_blocks; -extern uint32_t* pmmap; -extern size_t pmmap_size ; \ No newline at end of file diff --git a/src/kernel/memory/SlabAllocator.h b/src/kernel/memory/SlabAllocator.h deleted file mode 100644 index b9f00df..0000000 --- a/src/kernel/memory/SlabAllocator.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -/** - * We'll need something to this effect to allocate memory in the kernel - * this will hopefully someday implement a full slab allocator - **/ -enum SlabState { - empty, - partial, - full -}; - -class CacheSlab { - const int SlabSize = 4000; - void* start = 0x0; -}; - - -class Allocator { - - public: - Allocator(); - ~Allocator(); - - void* kmalloc( int size ); - void kfree (void* address); - - private: - CacheSlab** _cache; - - - - -}; \ No newline at end of file diff --git a/src/kernel/memory/memory.cpp b/src/kernel/memory/memory.cpp new file mode 100644 index 0000000..b72e786 --- /dev/null +++ b/src/kernel/memory/memory.cpp @@ -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 + ); +} + diff --git a/src/kernel/memory/memory.h b/src/kernel/memory/memory.h new file mode 100644 index 0000000..2d0d309 --- /dev/null +++ b/src/kernel/memory/memory.h @@ -0,0 +1,48 @@ +#pragma once +#include +#include + +#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); diff --git a/src/kernel/memory/memoryinfo.h b/src/kernel/memory/memoryinfo.h new file mode 100644 index 0000000..9bbb626 --- /dev/null +++ b/src/kernel/memory/memoryinfo.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include + +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)); + + + diff --git a/src/kernel/sv-terminal/superVisorTerminal.cpp b/src/kernel/sv-terminal/superVisorTerminal.cpp index 436fad2..b568208 100644 --- a/src/kernel/sv-terminal/superVisorTerminal.cpp +++ b/src/kernel/sv-terminal/superVisorTerminal.cpp @@ -1,6 +1,6 @@ #include "superVisorTerminal.h" -void startSuperVisorTerminal(){ +void startSuperVisorTerminal(BootInfo* bootinfo){ while (true){ printf("SUPERVISOR:>$ " ); @@ -40,7 +40,16 @@ void startSuperVisorTerminal(){ printf("========= Memory ==========\n"); printf("Kernel MemoryMap:\n"); printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end); - printf("Frames used: 0x%x blocks of 4 KiB\n", used_blocks); + printf("Frames used: 0x%x blocks of 4 KiB\n", 0); + const int bytesInGiB = 1073741824; + int64_t bytesLeft = (bootinfo->memory->TotalMemory % bytesInGiB) / bytesInGiB; + int64_t effectiveNumberOfGib = bootinfo->memory->TotalMemory / bytesInGiB; + + int64_t GiBs = effectiveNumberOfGib + bytesLeft; + + printf("Available Memory: %d bytes, %d GiB\n", bootinfo->memory->TotalMemory, GiBs ); + printf("Reserved Memory: %d bytes\n", bootinfo->memory->ReservedMemory); + //printf("\n\n"); //PrintPhysicalMemoryAllocation( ); diff --git a/src/kernel/sv-terminal/superVisorTerminal.h b/src/kernel/sv-terminal/superVisorTerminal.h index 8f83a15..5d4519d 100644 --- a/src/kernel/sv-terminal/superVisorTerminal.h +++ b/src/kernel/sv-terminal/superVisorTerminal.h @@ -3,6 +3,7 @@ #include "../time.h" #include "../pit.h" #include "../keyboard/keyboard.h" -#include "../memory/physical/PhysicalMemoryManager.h" +#include "../memory/memory.h" +#include "../bootinfo.h" -void startSuperVisorTerminal(); \ No newline at end of file +void startSuperVisorTerminal(BootInfo * ); \ No newline at end of file diff --git a/src/libc/include/mem.h b/src/libc/include/mem.h index 62c4318..75e7cf8 100644 --- a/src/libc/include/mem.h +++ b/src/libc/include/mem.h @@ -1,8 +1,8 @@ inline void* memset (void* ptr, int value, size_t num){ for( int i = 0; i < num; i++ ) { - int* data = (int*)ptr+ i; - *data = value; + unsigned char* data = (unsigned char*)ptr+ i; + *data = (unsigned char)value; } return ptr; } diff --git a/todo.md b/todo.md index e69de29..d927cb1 100644 --- a/todo.md +++ b/todo.md @@ -0,0 +1,21 @@ +# TODO list + +![Todo image](https://camo.githubusercontent.com/c43d969d9d071c8342e9a69cdd6acb433c541f431127738974ce22290c46f2b8/68747470733a2f2f692e696d6775722e636f6d2f4f764d5a4273392e6a7067) + + +This list keeps me focused and organised so I don't forget what +needs to be done. It is a expansion on the features markdown file which describes the features. Here I put things I need to remember +to do on a more in depth level. + +## -- +[ ] Setup paging \ +[ ] HELP command +[ ] Setup a proper HEAP \ +[ ] Setup a proper Stack \ +[ ] Setup KMalloc and KFree \ +[ ] Merge Functioning Feature branches into sandboxKernelDev \ +[ ] Remove merged feature branches \ +[ ] Merge sandboxKernelDev with dev \ +[ ] Remove sandboxKernelDev branch \ +[ ] Implement proper virtual filesystem +