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 +