diff --git a/configure.ac b/configure.ac index 639c8f3..5739739 100644 --- a/configure.ac +++ b/configure.ac @@ -3,8 +3,8 @@ AC_PREREQ([2.69]) AC_INIT([quark-kernel], [pre-alpha]) -AM_INIT_AUTOMAKE([-Wall foreign]) -AC_CONFIG_SRCDIR([src/tty.cpp]) +AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) +AC_CONFIG_SRCDIR([src/allocator.cpp]) AC_CONFIG_HEADERS([src/config.h]) # Checks for programs. diff --git a/src/memorymap.cpp b/src/memorymap.cpp index 2935778..43959df 100644 --- a/src/memorymap.cpp +++ b/src/memorymap.cpp @@ -1,38 +1,229 @@ #include "memorymap.hpp" -kernel::MemoryMap::MemoryMap(kernel::MemoryMap::Region* map, size_t entries) +using namespace kernel; + +MemoryMap::Region::Region() { - this->map = map; - this->entries = entries; + m_location = 0; + m_size = 0; + m_type = (Type) 0; } -kernel::MemoryMap::Region& kernel::MemoryMap::operator[](size_t index) +MemoryMap::Region::Region(Region& copy) { - return map[index]; + m_location = copy.m_location; + m_size = copy.m_size; + m_type = copy.m_type; } -size_t kernel::MemoryMap::size() +MemoryMap::Region::Region(physaddr_t location, size_t size, Type type) { - return entries; + m_location = location; + m_size = size; + m_type = (size_t) type; } -physaddr_t kernel::MemoryMap::Region::getLocation() +const MemoryMap::Region& MemoryMap::Region::operator=(const MemoryMap::Region& rhs) { - return location; + m_location = rhs.m_location; + m_size = rhs.m_size; + m_type = rhs.m_type; + return rhs; } -size_t kernel::MemoryMap::Region::getSize() +const bool MemoryMap::Region::operator==(const MemoryMap::Region& rhs) const { - return size; + return (m_location == rhs.m_location) && (m_size == rhs.m_size); } -kernel::MemoryMap::Type kernel::MemoryMap::Region::getType() +const bool MemoryMap::Region::operator<(const MemoryMap::Region& rhs) const { - return (Type) type; + return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size < rhs.m_size)); } -bool kernel::MemoryMap::Region::contains(physaddr_t location, size_t size) +const bool MemoryMap::Region::operator>(const MemoryMap::Region& rhs) const { - return (location >= this->location) && - (location + size <= this->location + this->size); + return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size > rhs.m_size)); } + +const bool MemoryMap::Region::operator<=(const MemoryMap::Region& rhs) const +{ + return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size <= rhs.m_size)); +} + +const bool MemoryMap::Region::operator>=(const MemoryMap::Region& rhs) const +{ + return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size >= rhs.m_size)); +} + +physaddr_t MemoryMap::Region::getLocation() const +{ + return m_location; +} + +size_t MemoryMap::Region::getSize() const +{ + return m_size; +} + +MemoryMap::Type MemoryMap::Region::getType() const +{ + return (Type) m_type; +} + +physaddr_t MemoryMap::Region::getEnd() const +{ + return m_location + m_size; +} + +bool MemoryMap::Region::contains(const MemoryMap::Region& r) const +{ + return contains(r.m_location, r.m_size); +} + +bool MemoryMap::Region::contains(physaddr_t location, size_t size) const +{ + return (location >= m_location) && + (location + size <= m_location + m_size); +} + +bool MemoryMap::Region::overlaps(const MemoryMap::Region& r) const +{ + if(r.m_location < m_location) + { + return r.m_location + r.m_size < m_location; + } + else + { + return r.m_location >= m_location && r.m_location < m_location + m_size; + } +} + +bool MemoryMap::Region::bordersLeft(const MemoryMap::Region& right) const +{ + return m_location + m_size == right.m_location; +} + +bool MemoryMap::Region::bordersRight(const MemoryMap::Region& left) const +{ + return m_location == left.m_location + left.m_size; +} + +bool MemoryMap::Region::borders(const MemoryMap::Region& r) const +{ + return bordersLeft(r) || bordersRight(r); +} + +void MemoryMap::Region::truncateLeft(physaddr_t left) +{ + m_size = getEnd() - left; + m_location = left; +} + +void MemoryMap::Region::truncateRight(physaddr_t right) +{ + m_size = right - m_location; +} + +MemoryMap::MemoryMap() +{ + this->m_entries = 0; +} + +MemoryMap::MemoryMap(MemoryMap& copy) +{ + for(int i = 0; i < copy.m_entries; i++) + m_map[i] = copy[i]; + this->m_entries = copy.m_entries; +} + +const MemoryMap::Region& MemoryMap::operator[](size_t index) const +{ + return m_map[index]; +} + +size_t MemoryMap::size() const +{ + return m_entries; +} + +void MemoryMap::insertEntry(physaddr_t location, size_t size, Type type) +{ + Region newRegion(location, size, type); + unsigned int i = 0; + while(i < m_entries) + { + if(newRegion < m_map[i]) + { + Region buffer = newRegion; + newRegion = m_map[i]; + m_map[i] = buffer; + } + i++; + } + m_map[i] = newRegion; + m_entries++; + for(i = 0; i < (m_entries - 1); i++) + { + if(m_map[i].overlaps(m_map[i+1])) + { + if(m_map[i].getType() == m_map[i+1].getType()) + { + m_map[i] = Region(m_map[i].getLocation(), + (m_map[i+1].getEnd() > m_map[i].getEnd() ? m_map[i+1].getEnd() : m_map[i].getEnd()) - m_map[i].getLocation(), + m_map[i].getType()); + remove(i + 1); + i--; + } + else if(m_map[i].getType() == AVAILABLE) + { + if(m_map[i+1].contains(m_map[i])) + { + remove(i); + i--; + } + else if(m_map[i].getEnd() <= m_map[i+1].getEnd()) + { + m_map[i].truncateRight(m_map[i+1].getLocation()); + } + else + { + unsigned int end = m_map[i].getEnd(); + m_map[i].truncateRight(m_map[i+1].getLocation()); + insertEntry(m_map[i+1].getEnd(), end - m_map[i+1].getEnd(), AVAILABLE); + } + } + else if(m_map[i+1].getType() == AVAILABLE) + { + if(m_map[i].contains(m_map[i + 1])) + { + remove(i + 1); + i--; + } + else + { + m_map[i+1].truncateLeft(m_map[i].getEnd()); + } + } + else + { + // two overlapping unavailable regions + } + } + else if(m_map[i].bordersLeft(m_map[i+1]) && m_map[i].getType() == m_map[i+1].getType()) + { + m_map[i] = Region(m_map[i].getLocation(), m_map[i+1].getEnd() - m_map[i].getLocation(), m_map[i].getType()); + remove(i + 1); + i--; + } + } +} + +void MemoryMap::remove(unsigned int index) +{ + for(unsigned int i = index; i < (m_entries - 1); i++) + { + m_map[i] = m_map[i+1]; + } + m_entries--; +} \ No newline at end of file diff --git a/src/memorymap.hpp b/src/memorymap.hpp index 853927a..ddc2b7a 100644 --- a/src/memorymap.hpp +++ b/src/memorymap.hpp @@ -1,9 +1,6 @@ #ifndef MEMORYMAP_H #define MEMORYMAP_H -#include -#include - #include "systypes.hpp" namespace kernel @@ -16,6 +13,7 @@ public: enum Type { AVAILABLE = 1, + UNAVAILABLE = 2, ACPI = 3, DEFECTIVE = 5 }; @@ -24,38 +22,82 @@ public: { public: - physaddr_t getLocation(); + Region(); - size_t getSize(); + Region(Region& copy); - Type getType(); + Region(physaddr_t location, size_t size, Type type); - bool contains(physaddr_t location, size_t size); - + const Region& operator=(const Region& rhs); + + const bool operator==(const Region& rhs) const; + + const bool operator<(const Region& rhs) const; + + const bool operator>(const Region& rhs) const; + + const bool operator<=(const Region& rhs) const; + + const bool operator>=(const Region& rhs) const; + + physaddr_t getLocation() const; + + size_t getSize() const; + + Type getType() const; + + physaddr_t getEnd() const; + + bool contains(const Region& r) const; + + bool contains(physaddr_t location, size_t size) const; + + bool overlaps(const Region& r) const; + + bool bordersLeft(const Region& right) const; + + bool bordersRight(const Region& left) const; + + bool borders(const Region& r) const; + + void truncateLeft(physaddr_t left); + + void truncateRight(physaddr_t right); + private: - physaddr_t location; - - size_t size; - - uint32_t type; - + physaddr_t m_location; + + size_t m_size; + + size_t m_type; + }; - - MemoryMap(Region* map, size_t entries); + + MemoryMap(); - Region& operator[](size_t index); + MemoryMap(MemoryMap& copy); - size_t size(); + const Region& operator[](size_t index) const; + + size_t size() const; + + size_t totalMemory() const; + + void insertEntry(physaddr_t location, size_t size, Type type); private: - Region* map; + void remove(unsigned int index); - size_t entries; - + static const unsigned int maxEntries = 16; + + Region m_map[maxEntries]; + + size_t m_entries; + }; - + } -#endif +#endif \ No newline at end of file diff --git a/src/module.cpp b/src/module.cpp index c0a1eee..7aae391 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -1,44 +1,39 @@ #include "module.hpp" #include "util.hpp" -kernel::ELF::ELF() +using namespace kernel; + +Module::Module() { - this->m_fileLocation = (void*) NULL; + m_start = 0; + m_end = 0; + m_command = NULL; } -kernel::ELF::ELF(void* location) +Module::Module(physaddr_t start, physaddr_t end, const char* command) { - this->m_fileLocation = location; + m_start = start; + m_end = end; + m_command = new char[strlen(command) + 1]; + strcpy(m_command, command); } -void* kernel::ELF::entry() +Module::~Module() { - Header* fileHeader = (Header*) m_fileLocation; - return fileHeader->entry; + delete[] m_command; } -int kernel::ELF::validate() +physaddr_t Module::getStart() const { - Header* fileHeader = (Header*) m_fileLocation; - if(fileHeader->magic != 0x464c457f) - return -1; - else if((ISA) fileHeader->machine != HOST_ISA) - return -1; - else if((Endianness) fileHeader->endianness != Little) - return -1; - return 0; + return m_start; } -int kernel::ELF::load() +physaddr_t Module::getEnd() const { - Header* fileHeader = (Header*) m_fileLocation; - ProgramHeader* programHeader = (ProgramHeader*) ((size_t) m_fileLocation + fileHeader->phoffset); - int count = (int) fileHeader->phcount; - for(int i = 0; i < count; i++) - { - if((SegmentType) programHeader->type != Load) - continue; - memcpy(programHeader->vaddr, m_fileLocation + programHeader->offset, programHeader->filesize); - } - return 0; + return m_end; +} + +const char* Module::getCommand() const +{ + return m_command; } \ No newline at end of file diff --git a/src/module.hpp b/src/module.hpp index 9f7748d..2c4b586 100644 --- a/src/module.hpp +++ b/src/module.hpp @@ -8,144 +8,21 @@ namespace kernel { -class ELF -{ -public: - - enum Endianness - { - Little = 1, - Big = 2 - }; - - enum ISA - { - NA = 0x00, - x86 = 0x03, - MIPS = 0x08, - PPC = 0x14, - PPC64 = 0x15, - ARM = 0x28, - x86_64 = 0x3E, - aarch64 = 0xB7 - }; - - enum SegmentType - { - Unused = 0, - Load = 1, - Dynamic = 2 - }; - - struct Header - { - uint32_t magic; - char size; - char endianness; - char version; - char abi; - char abiVersion; - char reserved[7]; - uint16_t type; - uint16_t machine; - uint32_t _version; - void* entry; -#if defined __i386__ || defined __arm__ - uint32_t phoffset; - uint32_t shoffset; -#elif defined __x86_64__ || defined __aarch64__ - uint64_t phoffset; - uint64_t shoffset; -#endif - uint32_t flags; - uint16_t headerSize; - uint16_t phsize; - uint16_t phcount; - uint16_t shsize; - uint16_t shcount; - uint16_t shstrndx; - }; - - struct ProgramHeader - { - uint32_t type; -#if defined __i386__ || defined __arm__ - uint32_t offset; - void* vaddr; - physaddr_t paddr; - uint32_t filesize; - uint32_t memsize; - uint32_t flags; - uint32_t align; -#elif defined __x86_64__ || defined __aarch64__ - uint32_t flags; - uint64_t offset; - void* vaddr; - physaddr_t paddr; - uint64_t filesize; - uint64_t memsize; - uint64_t align; -#endif - }; - - struct SectionHeader - { - uint32_t name; - uint32_t type; -#if defined __i386__ || defined __arm__ - uint32_t flags; - void* addr; - uint32_t offset; - uint32_t size; - uint32_t link; - uint32_t info; - uint32_t align; - uint32_t entrysize; -#elif defined __x86_64__ || defined __aarch64__ - uint64_t flags; - void* addr; - uint64_t offset; - uint64_t size; - uint32_t link; - uint32_t info; - uint64_t align; - uint64_t entrysize; -#endif - }; - -#if defined __i386__ - static const ISA HOST_ISA = x86; -#elif defined __x86_64__ - static const ISA HOST_ISA = x86_64; -#elif defined __arm__ - static const ISA HOST_ISA = ARM; -#elif defined __aarch64__ - static const ISA HOST_ISA = aarch64; -#endif - - ELF(); - - ELF(void* location); - - void* entry(); - - int validate(); - - int load(); - -private: - - void* m_fileLocation; - -}; - class Module { public: Module(); - Module(physaddr_t start, physaddr_t end); + Module(physaddr_t start, physaddr_t end, const char* command); + + ~Module(); + + physaddr_t getStart() const; + + physaddr_t getEnd() const; + + const char* getCommand() const; private: @@ -153,7 +30,7 @@ private: physaddr_t m_end; - ELF binary; + char* m_command; }; diff --git a/src/util.cpp b/src/util.cpp index 2dfa310..284251b 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,6 +1,7 @@ #include #include "util.hpp" +#include "kernelstate.hpp" void* memcpy(void* destination, const void* source, size_t num) { @@ -120,7 +121,42 @@ char* strcpy(char* destination, const char* source) return destination; } +void* malloc(size_t size) +{ + return kernel::State::allocator.allocate(size); +} + +void* calloc(size_t count, size_t size) +{ + return memset(malloc(count * size), 0, count * size); +} + +void free(void* p) +{ + kernel::State::allocator.free(p); +} + void __cxa_pure_virtual() { // do nothing +} + +void* operator new(size_t size) +{ + return malloc(size); +} + +void* operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void* p) +{ + free(p); +} + +void operator delete[](void* p) +{ + free(p); } \ No newline at end of file diff --git a/src/util.hpp b/src/util.hpp index a16c112..608f8e0 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -3,8 +3,6 @@ #include -extern "C" void __cxa_pure_virtual(); - extern "C" void* memcpy(void* destination, const void* source, size_t num); extern "C" void* memmove(void* destination, const void* source, size_t num); @@ -17,4 +15,40 @@ extern "C" int strlen(const char* str); extern "C" char* strcpy(char* destination, const char* source); +extern "C" void* malloc(size_t size); + +extern "C" void* calloc(size_t count, size_t size); + +extern "C" void free(void* p); + +extern "C" void __cxa_pure_virtual(); + +void* operator new(size_t size); + +void* operator new[](size_t size); + +void operator delete(void* p); + +void operator delete[](void* p); + +inline void* operator new(size_t, void *p) +{ + return p; +} + +inline void* operator new[](size_t, void *p) +{ + return p; +} + +inline void operator delete(void *, void *) +{ + +} + +inline void operator delete[](void *, void *) +{ + +} + #endif \ No newline at end of file diff --git a/src/x86/multiboot2.cpp b/src/x86/multiboot2.cpp new file mode 100644 index 0000000..a191382 --- /dev/null +++ b/src/x86/multiboot2.cpp @@ -0,0 +1,78 @@ +#include "multiboot2.hpp" + +using namespace kernel; + +Multiboot2Info::Multiboot2Info(void* tableLocation) +{ + m_commandLine = NULL; + m_bootloader = NULL; + m_moduleCount = 0; + uint32_t* ptr = (uint32_t*) tableLocation; + ptr += 2; + while(*ptr != 0) + { + if(*ptr == T_BootCommand) + { + m_commandLine = &reinterpret_cast(ptr)->str; + } + else if(*ptr == T_Bootloader) + { + m_bootloader = &reinterpret_cast(ptr)->str; + } + else if(*ptr == T_MemoryMap) + { + unsigned int tagSize = reinterpret_cast(ptr)->size - 16; + unsigned int entrySize = reinterpret_cast(ptr)->entrySize; + MemoryMapEntry* entry = &reinterpret_cast(ptr)->entries; + while(tagSize > 0) + { + m_memmap.insertEntry(entry->base, entry->length, (MemoryMap::Type) entry->type); + entry = (MemoryMapEntry*) (reinterpret_cast(entry) + entrySize); + tagSize -= entrySize; + } + } + else if(*ptr == T_Module) + { + TagModule* moduleTag = reinterpret_cast(ptr); + m_modules[m_moduleCount] = Module(moduleTag->start, moduleTag->end, &moduleTag->str); + m_memmap.insertEntry(moduleTag->start, moduleTag->end - moduleTag->start, MemoryMap::UNAVAILABLE); + } + unsigned int size = (ptr[1] + 7) - ((ptr[1] + 7) % 8); + ptr += size / sizeof(uint32_t); + } +} + +Multiboot2Info::~Multiboot2Info() +{ + +} + +bool Multiboot2Info::isValid() const +{ + return true; +} + +MemoryMap& Multiboot2Info::getMemoryMap() +{ + return m_memmap; +} + +const Module* Multiboot2Info::getModules() const +{ + return m_modules; +} + +unsigned int Multiboot2Info::getModuleCount() const +{ + return m_moduleCount; +} + +const char* Multiboot2Info::getCommandLine() const +{ + return m_commandLine; +} + +const char* Multiboot2Info::getBootloaderName() const +{ + return m_bootloader; +} \ No newline at end of file diff --git a/src/x86/multiboot2.hpp b/src/x86/multiboot2.hpp new file mode 100644 index 0000000..9f9e944 --- /dev/null +++ b/src/x86/multiboot2.hpp @@ -0,0 +1,105 @@ +#ifndef MULTIBOOT2_H +#define MULTIBOOT2_H + +#include "../memorymap.hpp" +#include "../module.hpp" + +namespace kernel +{ + +class Multiboot2Info +{ +public: + + enum TagType + { + T_BootCommand = 1, + T_Bootloader = 2, + T_Module = 3, + T_MemoryInfo = 4, + T_BIOSBootDevice = 5, + T_MemoryMap = 6, + T_VBE = 7, + T_Framebuffer = 8, + T_ELFSymbols = 9, + T_APM = 10, + T_EFI32SystemTable = 11, + T_EFI64SystemTable = 12, + T_SMBIOS = 13, + T_ACPI10RSDP = 14, + T_ACPT20RSDP = 15, + T_Network = 16, + T_EFIMemoryMap = 17, + T_EFIBootServices = 18, + T_EFI32Image = 19, + T_EFI64Image = 20, + T_LoadAddress = 21 + }; + + struct TagString + { + uint32_t type; + uint32_t size; + char str; + }; + + struct TagModule + { + uint32_t type; + uint32_t size; + uint32_t start; + uint32_t end; + char str; + }; + + struct MemoryMapEntry + { + uint64_t base; + uint64_t length; + uint32_t type; + }; + + struct TagMemoryMap + { + uint32_t type; + uint32_t size; + uint32_t entrySize; + uint32_t entryVersion; + MemoryMapEntry entries; + }; + + Multiboot2Info(void* tableLocation); + + ~Multiboot2Info(); + + bool isValid() const; + + MemoryMap& getMemoryMap(); + + const Module* getModules() const; + + unsigned int getModuleCount() const; + + const char* getCommandLine() const; + + const char* getBootloaderName() const; + +private: + + Module m_modules[16]; + + unsigned int m_moduleCount; + + MemoryMap m_memmap; + + char* m_commandLine; + + char* m_bootloader; + + void* m_tableLocation; + +}; + +} + +#endif \ No newline at end of file