From 09edf0cedc644dc69fbcd035c28ee6d6a21aa129 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sat, 1 Aug 2020 18:10:43 -0500 Subject: [PATCH 001/109] Moved PageAllocator implementation to pageallocator.cpp --- src/Makefile.am | 2 +- src/buddyallocator.hpp | 94 ------------------- src/mmap.hpp | 4 +- src/mmgr.hpp | 2 +- src/{buddyallocator.cpp => pageallocator.cpp} | 2 +- src/pageallocator.hpp | 85 ++++++++++++++++- src/x86/mmap.cpp | 4 +- 7 files changed, 91 insertions(+), 102 deletions(-) delete mode 100755 src/buddyallocator.hpp rename src/{buddyallocator.cpp => pageallocator.cpp} (99%) diff --git a/src/Makefile.am b/src/Makefile.am index 4062180..a5b0db4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = quarkkernel.cpp elf.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp buddyallocator.cpp +quark_kernel_SOURCES = quarkkernel.cpp elf.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp quark_kernel_LDADD = -lgcc quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -nostdlib diff --git a/src/buddyallocator.hpp b/src/buddyallocator.hpp deleted file mode 100755 index d30351f..0000000 --- a/src/buddyallocator.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef BUDDYALLOCATOR_H_ -#define BUDDYALLOCATOR_H_ - -#include "pageallocator.hpp" -#include "memorymap.hpp" - -namespace kernel -{ - -class BuddyAllocator : public MemoryAllocator -{ -public: - - BuddyAllocator(); - - BuddyAllocator(MemoryMap& memmap, char* bitmap, size_t blockCount, - size_t treeHeight); - - BuddyAllocator(char* bitmap, size_t blockSize, size_t blockCount, - size_t treeHeight); - - /** - * Allocate a block of memory containing at least 'size' bytes. - * Rounds up to the nearest power of 2 times the size of a block. - */ - virtual physaddr_t allocate(size_t size); - - /** - * Free the region of memory starting at 'location' and containing - * 'size' bytes. - */ - virtual void free(physaddr_t location, size_t size); - - /** - * @returns the total number of free blocks of memory. - */ - virtual size_t freeBlocks() const; - - /** - * @returns the size in blocks of the largest possible allocation that - * will not fail due to lack of memory. - */ - virtual size_t maxAllocationSize() const; - - /** - * @returns the size in bytes of a single block. - */ - virtual size_t getBlockSize() const; - - /** - * @returns the total number of blocks managed by this memory - * allocator. - */ - virtual size_t getMemorySize() const; - -private: - - static const size_t INVALID = (size_t) -1; - - char* bitmap; - - size_t blockSize; - - size_t blockCount; - - size_t treeHeight; - - size_t findFreeBlock(size_t height); - - size_t split(size_t height, size_t index); - - size_t merge(size_t height, size_t index); - - size_t getBuddy(size_t index); - - size_t getParent(size_t index); - - size_t getChild(size_t index); - - physaddr_t nodeToAddress(size_t height, size_t index) const; - - size_t addressToNode(size_t height, physaddr_t location) const; - - void reserveNode(size_t height, size_t index); - - void freeNode(size_t height, size_t index); - - bool isFree(size_t height, size_t index) const; - -}; - -} - -#endif diff --git a/src/mmap.hpp b/src/mmap.hpp index 8f354d3..3169629 100644 --- a/src/mmap.hpp +++ b/src/mmap.hpp @@ -10,9 +10,9 @@ namespace kernel { -int mmap(MemoryAllocator& allocator, void* start, size_t length, int flags); +int mmap(PageAllocator& allocator, void* start, size_t length, int flags); -int munmap(MemoryAllocator& allocator, void* start, size_t length); +int munmap(PageAllocator& allocator, void* start, size_t length); bool isMapped(void* addr); diff --git a/src/mmgr.hpp b/src/mmgr.hpp index b34b018..e39cb6e 100644 --- a/src/mmgr.hpp +++ b/src/mmgr.hpp @@ -2,6 +2,6 @@ #define MMGR_H #include "mmap.hpp" -#include "buddyallocator.hpp" +#include "pageallocator.hpp" #endif \ No newline at end of file diff --git a/src/buddyallocator.cpp b/src/pageallocator.cpp similarity index 99% rename from src/buddyallocator.cpp rename to src/pageallocator.cpp index 93a33c9..761a52d 100755 --- a/src/buddyallocator.cpp +++ b/src/pageallocator.cpp @@ -1,4 +1,4 @@ -#include "buddyallocator.hpp" +#include "pageallocator.hpp" #include "systypes.hpp" #include "memorymap.hpp" diff --git a/src/pageallocator.hpp b/src/pageallocator.hpp index 48ea87c..d3034ec 100755 --- a/src/pageallocator.hpp +++ b/src/pageallocator.hpp @@ -3,6 +3,7 @@ #include #include "systypes.hpp" +#include "memorymap.hpp" namespace kernel { @@ -10,7 +11,7 @@ namespace kernel /** * Interface for a dymanic memory allocator. */ -class MemoryAllocator +class PageAllocator { public: @@ -49,6 +50,88 @@ public: virtual size_t getMemorySize() const = 0; }; + +class BuddyAllocator : public PageAllocator +{ +public: + + BuddyAllocator(); + + BuddyAllocator(MemoryMap& memmap, char* bitmap, size_t blockCount, + size_t treeHeight); + + BuddyAllocator(char* bitmap, size_t blockSize, size_t blockCount, + size_t treeHeight); + + /** + * Allocate a block of memory containing at least 'size' bytes. + * Rounds up to the nearest power of 2 times the size of a block. + */ + virtual physaddr_t allocate(size_t size); + + /** + * Free the region of memory starting at 'location' and containing + * 'size' bytes. + */ + virtual void free(physaddr_t location, size_t size); + + /** + * @returns the total number of free blocks of memory. + */ + virtual size_t freeBlocks() const; + + /** + * @returns the size in blocks of the largest possible allocation that + * will not fail due to lack of memory. + */ + virtual size_t maxAllocationSize() const; + + /** + * @returns the size in bytes of a single block. + */ + virtual size_t getBlockSize() const; + + /** + * @returns the total number of blocks managed by this memory + * allocator. + */ + virtual size_t getMemorySize() const; + +private: + + static const size_t INVALID = (size_t) -1; + + char* bitmap; + + size_t blockSize; + + size_t blockCount; + + size_t treeHeight; + + size_t findFreeBlock(size_t height); + + size_t split(size_t height, size_t index); + + size_t merge(size_t height, size_t index); + + size_t getBuddy(size_t index); + + size_t getParent(size_t index); + + size_t getChild(size_t index); + + physaddr_t nodeToAddress(size_t height, size_t index) const; + + size_t addressToNode(size_t height, physaddr_t location) const; + + void reserveNode(size_t height, size_t index); + + void freeNode(size_t height, size_t index); + + bool isFree(size_t height, size_t index) const; + +}; } diff --git a/src/x86/mmap.cpp b/src/x86/mmap.cpp index 9bb61a1..4638203 100644 --- a/src/x86/mmap.cpp +++ b/src/x86/mmap.cpp @@ -1,7 +1,7 @@ #include "../mmap.hpp" #include "pagetableentry.hpp" -int kernel::mmap(MemoryAllocator& allocator, void* start, size_t length, int flags) +int kernel::mmap(PageAllocator& allocator, void* start, size_t length, int flags) { if((size_t) start % 4096 != 0) return -1; @@ -36,7 +36,7 @@ int kernel::mmap(MemoryAllocator& allocator, void* start, size_t length, int fla return 0; } -int kernel::munmap(MemoryAllocator& allocator, void* start, size_t length) +int kernel::munmap(PageAllocator& allocator, void* start, size_t length) { if((size_t) start % 4096 != 0) return -1; From 39710685fbb9adfb35507ee32161aff0cd92eefe Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sat, 1 Aug 2020 19:03:51 -0500 Subject: [PATCH 002/109] Merged several files together --- src/Makefile.am | 6 +- src/x86/entry.S | 95 ++++++++++++++++++- src/x86/idt.S | 21 ----- src/x86/idt.hpp | 10 -- src/x86/interruptdescriptor.cpp | 63 ------------- src/x86/interruptdescriptor.hpp | 55 ----------- src/x86/interrupts.cpp | 162 +++++++++++++++++++++++++++++++- src/x86/inthandlers.cpp | 39 -------- src/x86/inthandlers.hpp | 19 ---- src/x86/multiboot2header.S | 94 ------------------ 10 files changed, 252 insertions(+), 312 deletions(-) delete mode 100644 src/x86/idt.S delete mode 100644 src/x86/idt.hpp delete mode 100644 src/x86/interruptdescriptor.cpp delete mode 100644 src/x86/interruptdescriptor.hpp delete mode 100644 src/x86/inthandlers.cpp delete mode 100644 src/x86/inthandlers.hpp delete mode 100755 src/x86/multiboot2header.S diff --git a/src/Makefile.am b/src/Makefile.am index a5b0db4..5ff9807 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,12 +8,8 @@ if x86 quark_kernel_SOURCES += x86/pagetableentry.cpp \ x86/mmap.cpp \ x86/interrupts.cpp \ - x86/inthandlers.cpp \ - x86/interruptdescriptor.cpp \ - x86/idt.S \ x86/entry.S \ - x86/pio.S \ - x86/multiboot2header.S + x86/pio.S quark_kernel_LDFLAGS += -T x86/linker.ld quark_kernel_DEPENDENCIES = x86/linker.ld endif diff --git a/src/x86/entry.S b/src/x86/entry.S index 55dc9d0..7a68f9d 100755 --- a/src/x86/entry.S +++ b/src/x86/entry.S @@ -1,5 +1,98 @@ .section .multiboot -.include "x86/multiboot2header.S" + +/* + * Define constants for the multiboot header. See Multiboot 2 Specifications for details. + */ +.set align, 1<<0 +.set meminfo, 1<<1 +.set magic, 0xE85250D6 +.set arch, 0 +.set headerLength, _multibootHeaderEnd - _multibootHeaderStart +.set checksum, -(magic + arch + headerLength) + +.set tagNotOptional, 0 + +.set tagInfoRequestType, 1 +.set tagInfoRequestSize, _multibootInfoTagEnd - _multibootInfoTagStart +.set requestBootCommand, 1 +.set requestBootLoaderName, 2 +.set requestBootModules, 3 +.set requestMemoryInfo, 4 +.set requestBootDevice, 5 +.set requestMemoryMap, 6 + +.set tagAddressType, 2 +.set tagAddressSize, 24 +.set tagAddressHeaderLocation, LOAD_START +.set tagAddressLoadStart, LOAD_START +.set tagAddressLoadEnd, LOAD_END +.set tagAddressBSSEnd, BSS_END + +.set tagEntryType, 3 +.set tagEntrySize, 12 +.set tagEntryAddress, _start - (0xFF900000 - 0x100000) + +.set tagModuleAlignType, 6 +.set tagModuleAlignSize, 8 + +/* + * Each multiboot tag must be 8-byte aligned, or GRUB will not be able to read the header. + */ +.align 8 +_multibootHeaderStart: + +.long magic +.long arch +.long headerLength +.long checksum + +.align 8 + +_multibootInfoTagStart: +.short tagInfoRequestType +.short tagNotOptional +.long tagInfoRequestSize +.long requestBootCommand +.long requestBootLoaderName +.long requestBootModules +.long requestMemoryInfo +.long requestBootDevice +.long requestMemoryMap +_multibootInfoTagEnd: + +.align 8 + +.short tagAddressType +.short tagNotOptional +.long tagAddressSize +.long tagAddressHeaderLocation +.long tagAddressLoadStart +.long tagAddressLoadEnd +.long tagAddressBSSEnd + +.align 8 + +.short tagEntryType +.short tagNotOptional +.long tagEntrySize +.long tagEntryAddress + +.align 8 + +.short tagModuleAlignType +.short tagNotOptional +.long tagModuleAlignSize + +.align 8 + +/* + * Terminate list of multiboot header tags. + * Ending tag has type = 0, flags = 0, size = 8 + */ +.long 0 +.long 8 + +_multibootHeaderEnd: .section .rodata diff --git a/src/x86/idt.S b/src/x86/idt.S deleted file mode 100644 index a76f770..0000000 --- a/src/x86/idt.S +++ /dev/null @@ -1,21 +0,0 @@ -.section .bss - -.align 8 -.global idt -idt: -.skip 8 * 256 -idt_end: - -.section .rodata - -.idt_info: -.short idt_end - idt - 1 -.long idt - -.section .text - -.global _lidt -.type _lidt, @function -_lidt: - - ret \ No newline at end of file diff --git a/src/x86/idt.hpp b/src/x86/idt.hpp deleted file mode 100644 index 2c1cf0f..0000000 --- a/src/x86/idt.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef IDT_H -#define IDT_H - -#include "interruptdescriptor.hpp" - -extern kernel::InterruptDescriptor idt[256]; - -extern "C" void _lidt(); - -#endif \ No newline at end of file diff --git a/src/x86/interruptdescriptor.cpp b/src/x86/interruptdescriptor.cpp deleted file mode 100644 index 63803e6..0000000 --- a/src/x86/interruptdescriptor.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "interruptdescriptor.hpp" - -kernel::InterruptDescriptor::InterruptDescriptor() -{ - this->m_offset1 = 0; - this->m_selector = 0; - this->m_zero = 0; - this->m_type = 0; - this->m_storage = 0; - this->m_dpl = 0; - this->m_present = 0; - this->m_offset2 = 0; -} - -kernel::InterruptDescriptor::InterruptDescriptor(void* handler, Type type, unsigned int dpl) -{ - uint32_t offset = (uint32_t) handler; - this->m_offset1 = (uint16_t) offset; - this->m_selector = 8; - this->m_zero = 0; - this->m_type = (uint16_t) type; - this->m_storage = 0; - this->m_dpl = dpl; - this->m_present = 1; - this->m_offset2 = offset >> 16; -} - -bool kernel::InterruptDescriptor::present() -{ - return m_present == 1; -} -void kernel::InterruptDescriptor::present(bool present) -{ - m_present = present ? 1 : 0; -} - -kernel::InterruptDescriptor::Type kernel::InterruptDescriptor::type() -{ - return (Type) m_type; -} - -void kernel::InterruptDescriptor::type(kernel::InterruptDescriptor::Type type) -{ - m_type = (unsigned int) type; -} - -unsigned int kernel::InterruptDescriptor::dpl() -{ - return m_dpl; -} - -void kernel::InterruptDescriptor::dpl(unsigned int dpl) -{ - m_dpl = dpl; -} - -void* kernel::InterruptDescriptor::operator=(void* rhs) -{ - uint32_t offset = (uint32_t) rhs; - m_offset1 = (uint16_t) offset; - m_offset2 = (offset >> 16); - return rhs; -} diff --git a/src/x86/interruptdescriptor.hpp b/src/x86/interruptdescriptor.hpp deleted file mode 100644 index c4365fe..0000000 --- a/src/x86/interruptdescriptor.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef INTERRUPTDESCRIPTOR_H -#define INTERRUPTDESCRIPTOR_H - -#include - -namespace kernel -{ - -class InterruptDescriptor -{ -public: - - enum Type - { - TASK32 = 5, - TRAP32 = 15, - INT32 = 14, - TRAP16 = 7, - INT16 = 6 - }; - - InterruptDescriptor(); - - InterruptDescriptor(void* handler, Type type, unsigned int dpl); - - bool present(); - - void present(bool present); - - Type type(); - - void type(Type type); - - unsigned int dpl(); - - void dpl(unsigned int dpl); - - void* operator=(void* rhs); - -private: - - uint16_t m_offset1; - uint16_t m_selector; - uint16_t m_zero : 8; - uint16_t m_type : 4; - uint16_t m_storage : 1; - uint16_t m_dpl : 2; - uint16_t m_present : 1; - uint16_t m_offset2; - -}; - -} - -#endif diff --git a/src/x86/interrupts.cpp b/src/x86/interrupts.cpp index 9e5c964..2b22417 100644 --- a/src/x86/interrupts.cpp +++ b/src/x86/interrupts.cpp @@ -1,6 +1,158 @@ #include "../interrupts.hpp" -#include "idt.hpp" -#include "inthandlers.hpp" + +#include + +class InterruptDescriptor +{ +public: + + enum Type + { + TASK32 = 5, + TRAP32 = 15, + INT32 = 14, + TRAP16 = 7, + INT16 = 6 + }; + + InterruptDescriptor(); + + InterruptDescriptor(void* handler, Type type, unsigned int dpl); + + bool present(); + + void present(bool present); + + Type type(); + + void type(Type type); + + unsigned int dpl(); + + void dpl(unsigned int dpl); + + void* operator=(void* rhs); + +private: + + uint16_t m_offset1; + uint16_t m_selector; + uint16_t m_zero : 8; + uint16_t m_type : 4; + uint16_t m_storage : 1; + uint16_t m_dpl : 2; + uint16_t m_present : 1; + uint16_t m_offset2; + +}; + +struct IDTInfo +{ + uint16_t size; + void* location; +}; + +InterruptDescriptor idt[256]; + +void lidt() +{ + IDTInfo idtInfo; + idtInfo.size = sizeof(idt) - 1; + idtInfo.location = (void*) &idt; + asm("lidt idt"); +} + +__attribute__ ((interrupt)) +void divisionByZero(void* frame) +{ + +} + +__attribute__ ((interrupt)) +void gpFaultHandler(void* frame, unsigned int error) +{ + +} + +__attribute__ ((interrupt)) +void pageFaultHandler(void* frame, unsigned int error) +{ + +} + +__attribute__ ((interrupt)) +void doubleFaultHandler(void* frame, unsigned int error) +{ + asm("hlt"); +} + +__attribute__ ((interrupt)) +void syscallHandler(void* frame) +{ + +} + +InterruptDescriptor::InterruptDescriptor() +{ + this->m_offset1 = 0; + this->m_selector = 0; + this->m_zero = 0; + this->m_type = 0; + this->m_storage = 0; + this->m_dpl = 0; + this->m_present = 0; + this->m_offset2 = 0; +} + +InterruptDescriptor::InterruptDescriptor(void* handler, Type type, unsigned int dpl) +{ + uint32_t offset = (uint32_t) handler; + this->m_offset1 = (uint16_t) offset; + this->m_selector = 8; + this->m_zero = 0; + this->m_type = (uint16_t) type; + this->m_storage = 0; + this->m_dpl = dpl; + this->m_present = 1; + this->m_offset2 = offset >> 16; +} + +bool InterruptDescriptor::present() +{ + return m_present == 1; +} +void InterruptDescriptor::present(bool present) +{ + m_present = present ? 1 : 0; +} + +InterruptDescriptor::Type InterruptDescriptor::type() +{ + return (Type) m_type; +} + +void InterruptDescriptor::type(InterruptDescriptor::Type type) +{ + m_type = (unsigned int) type; +} + +unsigned int InterruptDescriptor::dpl() +{ + return m_dpl; +} + +void InterruptDescriptor::dpl(unsigned int dpl) +{ + m_dpl = dpl; +} + +void* InterruptDescriptor::operator=(void* rhs) +{ + uint32_t offset = (uint32_t) rhs; + m_offset1 = (uint16_t) offset; + m_offset2 = (offset >> 16); + return rhs; +} kernel::Interrupts::Interrupts() { @@ -9,15 +161,15 @@ kernel::Interrupts::Interrupts() idt[0x80] = InterruptDescriptor((void*) &syscallHandler, InterruptDescriptor::INT32, 0); // Load interrupt handlers // Configure PIC - _lidt(); + lidt(); } -inline void kernel::Interrupts::enable() +void kernel::Interrupts::enable() { asm("sti"); } -inline void kernel::Interrupts::disable() +void kernel::Interrupts::disable() { asm("cli"); } \ No newline at end of file diff --git a/src/x86/inthandlers.cpp b/src/x86/inthandlers.cpp deleted file mode 100644 index 6519620..0000000 --- a/src/x86/inthandlers.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "inthandlers.hpp" - -char* display = (char*) 0xC00B8000; - -__attribute__ ((interrupt)) -void divisionByZero(void* frame) -{ - *display = 'z'; - display += 2; -} - -__attribute__ ((interrupt)) -void gpFaultHandler(void* frame, unsigned int error) -{ - *display = 'a'; - display += 2; -} - -__attribute__ ((interrupt)) -void pageFaultHandler(void* frame, unsigned int error) -{ - *display = '0'; - display += 2; -} - -__attribute__ ((interrupt)) -void doubleFaultHandler(void* frame, unsigned int error) -{ - *display = '#'; - asm("hlt"); -} - -__attribute__ ((interrupt)) -void syscallHandler(void* frame) -{ - *display = 'z'; - display += 2; -} - diff --git a/src/x86/inthandlers.hpp b/src/x86/inthandlers.hpp deleted file mode 100644 index bf92c56..0000000 --- a/src/x86/inthandlers.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef INTHANDLERS_H -#define INTHANDLERS_H - -__attribute__ ((interrupt)) -void divisionByZero(void* frame); - -__attribute__ ((interrupt)) -void gpFaultHandler(void* frame, unsigned int error); - -__attribute__ ((interrupt)) -void pageFaultHandler(void* frame, unsigned int error); - -__attribute__ ((interrupt)) -void doubleFaultHandler(void* frame, unsigned int error); - -__attribute__ ((interrupt)) -void syscallHandler(void* frame); - -#endif diff --git a/src/x86/multiboot2header.S b/src/x86/multiboot2header.S deleted file mode 100755 index 050df1c..0000000 --- a/src/x86/multiboot2header.S +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Define constants for the multiboot header. See Multuboot 2 Specifications for details. - */ -.set align, 1<<0 -.set meminfo, 1<<1 -.set magic, 0xE85250D6 -.set arch, 0 -.set headerLength, _multibootHeaderEnd - _multibootHeaderStart -.set checksum, -(magic + arch + headerLength) - -.set tagNotOptional, 0 - -.set tagInfoRequestType, 1 -.set tagInfoRequestSize, _multibootInfoTagEnd - _multibootInfoTagStart -.set requestBootCommand, 1 -.set requestBootLoaderName, 2 -.set requestBootModules, 3 -.set requestMemoryInfo, 4 -.set requestBootDevice, 5 -.set requestMemoryMap, 6 - -.set tagAddressType, 2 -.set tagAddressSize, 24 -.set tagAddressHeaderLocation, LOAD_START -.set tagAddressLoadStart, LOAD_START -.set tagAddressLoadEnd, LOAD_END -.set tagAddressBSSEnd, BSS_END - -.set tagEntryType, 3 -.set tagEntrySize, 12 -.set tagEntryAddress, _start - (0xFF900000 - 0x100000) - -.set tagModuleAlignType, 6 -.set tagModuleAlignSize, 8 - -/* - * Each multiboot tag must be 8-byte aligned, or GRUB will not be able to read the header. - */ -.align 8 -_multibootHeaderStart: - -.long magic -.long arch -.long headerLength -.long checksum - -.align 8 - -_multibootInfoTagStart: -.short tagInfoRequestType -.short tagNotOptional -.long tagInfoRequestSize -.long requestBootCommand -.long requestBootLoaderName -.long requestBootModules -.long requestMemoryInfo -.long requestBootDevice -.long requestMemoryMap -_multibootInfoTagEnd: - -.align 8 - -.short tagAddressType -.short tagNotOptional -.long tagAddressSize -.long tagAddressHeaderLocation -.long tagAddressLoadStart -.long tagAddressLoadEnd -.long tagAddressBSSEnd - -.align 8 - -.short tagEntryType -.short tagNotOptional -.long tagEntrySize -.long tagEntryAddress - -.align 8 - -.short tagModuleAlignType -.short tagNotOptional -.long tagModuleAlignSize - -.align 8 - -/* - * Terminate list of multiboot header tags. - * Ending tag has type = 0, flags = 0, size = 8 - */ -.long 0 -.long 8 - -_multibootHeaderEnd: - From 6dc610c9aa5c231a0be3a8c64de314025736731b Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sat, 1 Aug 2020 19:05:37 -0500 Subject: [PATCH 003/109] Deleted inb and outb functions. --- src/Makefile.am | 3 +-- src/quarkkernel.cpp | 3 --- src/x86/pio.S | 13 ------------- src/x86/pio.hpp | 8 -------- 4 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 src/x86/pio.S delete mode 100644 src/x86/pio.hpp diff --git a/src/Makefile.am b/src/Makefile.am index 5ff9807..9094671 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,8 +8,7 @@ if x86 quark_kernel_SOURCES += x86/pagetableentry.cpp \ x86/mmap.cpp \ x86/interrupts.cpp \ - x86/entry.S \ - x86/pio.S + x86/entry.S quark_kernel_LDFLAGS += -T x86/linker.ld quark_kernel_DEPENDENCIES = x86/linker.ld endif diff --git a/src/quarkkernel.cpp b/src/quarkkernel.cpp index 069742f..abefa11 100755 --- a/src/quarkkernel.cpp +++ b/src/quarkkernel.cpp @@ -4,7 +4,6 @@ #include "systypes.hpp" #include "systeminfo.hpp" #include "mmgr.hpp" -#include "x86/pio.hpp" #include "tty.hpp" #include "util.hpp" #include "config.h" @@ -30,7 +29,5 @@ void main(char* cmdline) } BuddyAllocator alloc(memmap, (char*) 0xFF800000, system_info.getHighMemory() / 4 + 256, 6); mmap(alloc, (void*) 0, 4096, MMAP_RW); - outb(0xa1, 0xff); - outb(0x21, 0xff); tty << "Nothing left to do. Hanging.\n"; } diff --git a/src/x86/pio.S b/src/x86/pio.S deleted file mode 100644 index 7681ee0..0000000 --- a/src/x86/pio.S +++ /dev/null @@ -1,13 +0,0 @@ -.global outb -outb: - mov 4(%esp), %dx - mov 8(%esp), %al - out %al, %dx - ret - -.global inb -inb: - mov 4(%esp), %dx - xor %eax, %eax - in %dx, %al - ret \ No newline at end of file diff --git a/src/x86/pio.hpp b/src/x86/pio.hpp deleted file mode 100644 index 68aed33..0000000 --- a/src/x86/pio.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PIO_H -#define PIO_H - -extern "C" void outb(short port, char data); - -extern "C" char inb(short port); - -#endif \ No newline at end of file From a40ca13279e63c95dc974748863f8667fc5c22c2 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sat, 1 Aug 2020 19:07:27 -0500 Subject: [PATCH 004/109] Renamed quarkkernel.cpp to better reflect what it does --- src/Makefile.am | 2 +- src/{quarkkernel.cpp => startup.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{quarkkernel.cpp => startup.cpp} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 9094671..dabe9c7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = quarkkernel.cpp elf.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp +quark_kernel_SOURCES = startup.cpp elf.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp quark_kernel_LDADD = -lgcc quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -nostdlib diff --git a/src/quarkkernel.cpp b/src/startup.cpp similarity index 100% rename from src/quarkkernel.cpp rename to src/startup.cpp From 74dae83c85d778bfaaca9b0bb227ac4ef0e6cc20 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sat, 1 Aug 2020 19:45:19 -0500 Subject: [PATCH 005/109] Merged i386 PTE class into mmap.cpp --- src/Makefile.am | 3 +- src/x86/mmap.cpp | 150 ++++++++++++++++++++++++++++++++++++- src/x86/pagetableentry.cpp | 141 ---------------------------------- src/x86/pagetableentry.hpp | 52 ------------- 4 files changed, 150 insertions(+), 196 deletions(-) delete mode 100755 src/x86/pagetableentry.cpp delete mode 100755 src/x86/pagetableentry.hpp diff --git a/src/Makefile.am b/src/Makefile.am index dabe9c7..e044453 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,8 +5,7 @@ quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-except quark_kernel_LDFLAGS = -nostdlib if x86 -quark_kernel_SOURCES += x86/pagetableentry.cpp \ - x86/mmap.cpp \ +quark_kernel_SOURCES += x86/mmap.cpp \ x86/interrupts.cpp \ x86/entry.S quark_kernel_LDFLAGS += -T x86/linker.ld diff --git a/src/x86/mmap.cpp b/src/x86/mmap.cpp index 4638203..1a8f530 100644 --- a/src/x86/mmap.cpp +++ b/src/x86/mmap.cpp @@ -1,5 +1,153 @@ #include "../mmap.hpp" -#include "pagetableentry.hpp" + +class PageTableEntry { +public: + + PageTableEntry() + { + this->present = 0; + this->rw = 0; + this->usermode = 0; + this->writeThrough = 0; + this->cacheDisable = 0; + this->accessed = 0; + this->dirty = 0; + this->pat = 0; + this->global = 0; + this->shared = 0; + this->ignored = 0; + this->physicalAddress = 0; + } + + bool getAccessed() const + { + return accessed == 1; + } + + bool getCacheDisable() const + { + return cacheDisable == 1; + } + + void setCacheDisable(bool cacheDisable) + { + this->cacheDisable = cacheDisable ? 1 : 0; + } + + bool getDirty() const + { + return dirty == 1; + } + + bool getGlobal() const + { + return global == 1; + } + + void setGlobal(bool global) + { + this->global = global ? 1 : 0; + } + + bool getPat() const + { + return pat == 1; + } + + void setPat(bool pat) + { + this->pat = pat ? 1 : 0; + } + + physaddr_t getPhysicalAddress() const + { + physaddr_t physicalAddress = this->physicalAddress; + return physicalAddress << 12; + } + + physaddr_t setPhysicalAddress(physaddr_t physicalAddress) + { + this->physicalAddress = physicalAddress >> 12; + return this->physicalAddress << 12; + } + + bool getPresent() const + { + return present == 1; + } + + void setPresent(bool present) + { + this->present = present ? 1 : 0; + } + + bool getRw() const + { + return rw == 1; + } + + void setRw(bool rw) + { + this->rw = rw ? 1 : 0; + } + + bool getShared() const + { + return shared == 1; + } + + void setShared(bool shared) + { + this->shared = shared ? 1 : 0; + } + + bool getUsermode() const + { + return usermode == 1; + } + + void setUsermode(bool usermode) + { + this->usermode = usermode ? 1 : 0; + } + + bool getWriteThrough() const + { + return writeThrough == 1; + } + + void setWriteThrough(bool writeThrough) + { + this->writeThrough = writeThrough ? 1 : 0; + } + + physaddr_t operator=(physaddr_t rhs) + { + return setPhysicalAddress(rhs); + } + + PageTableEntry operator=(PageTableEntry rhs) + { + uint32_t* iThis = (uint32_t*) this; + uint32_t* iThat = (uint32_t*) &rhs; + *iThis = *iThat; + return rhs; + } + +private: + uint32_t present : 1; + uint32_t rw : 1; + uint32_t usermode : 1; + uint32_t writeThrough : 1; + uint32_t cacheDisable : 1; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t pat : 1; + uint32_t global : 1; + uint32_t shared : 1; + uint32_t ignored : 2; + uint32_t physicalAddress : 20; +}; int kernel::mmap(PageAllocator& allocator, void* start, size_t length, int flags) { diff --git a/src/x86/pagetableentry.cpp b/src/x86/pagetableentry.cpp deleted file mode 100755 index b07241f..0000000 --- a/src/x86/pagetableentry.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * PageTableEntry.cpp - * - * Created on: May 22, 2019 - * Author: nathan - */ - -#include "pagetableentry.hpp" - -namespace kernel { - -static_assert(sizeof(PageTableEntry) == 4, "PTE structure is the wrong size!"); - -PageTableEntry::PageTableEntry() { - this->present = 0; - this->rw = 0; - this->usermode = 0; - this->writeThrough = 0; - this->cacheDisable = 0; - this->accessed = 0; - this->dirty = 0; - this->pat = 0; - this->global = 0; - this->shared = 0; - this->ignored = 0; - this->physicalAddress = 0; -} - -bool PageTableEntry::getAccessed() const { - return accessed == 1; -} - -bool PageTableEntry::getCacheDisable() const -{ - return cacheDisable == 1; -} - -void PageTableEntry::setCacheDisable(bool cacheDisable) -{ - this->cacheDisable = cacheDisable ? 1 : 0; -} - -bool PageTableEntry::getDirty() const -{ - return dirty == 1; -} - -bool PageTableEntry::getGlobal() const -{ - return global == 1; -} - -void PageTableEntry::setGlobal(bool global) -{ - this->global = global ? 1 : 0; -} - -bool PageTableEntry::getPat() const -{ - return pat == 1; -} - -void PageTableEntry::setPat(bool pat) -{ - this->pat = pat ? 1 : 0; -} - -physaddr_t PageTableEntry::getPhysicalAddress() const { - physaddr_t physicalAddress = this->physicalAddress; - return physicalAddress << 12; -} - -physaddr_t PageTableEntry::setPhysicalAddress(physaddr_t physicalAddress) -{ - this->physicalAddress = physicalAddress >> 12; - return this->physicalAddress << 12; -} - -bool PageTableEntry::getPresent() const -{ - return present == 1; -} - -void PageTableEntry::setPresent(bool present) -{ - this->present = present ? 1 : 0; -} - -bool PageTableEntry::getRw() const -{ - return rw == 1; -} - -void PageTableEntry::setRw(bool rw) -{ - this->rw = rw ? 1 : 0; -} - -bool PageTableEntry::getUsermode() const -{ - return usermode == 1; -} - -void PageTableEntry::setUsermode(bool usermode) -{ - this->usermode = usermode ? 1 : 0; -} - -bool PageTableEntry::getWriteThrough() const { - return writeThrough == 1; -} - -bool PageTableEntry::getShared() const -{ - return shared == 1; -} - -void PageTableEntry::setShared(bool shared) -{ - this->shared = shared ? 1 : 0; -} - -void PageTableEntry::setWriteThrough(bool writeThrough) -{ - this->writeThrough = writeThrough ? 1 : 0; -} - -physaddr_t PageTableEntry::operator=(physaddr_t rhs) -{ - return setPhysicalAddress(rhs); -} - -PageTableEntry PageTableEntry::operator=(PageTableEntry rhs) -{ - uint32_t* iThis = (uint32_t*) this; - uint32_t* iThat = (uint32_t*) &rhs; - *iThis = *iThat; - return rhs; -} - -} diff --git a/src/x86/pagetableentry.hpp b/src/x86/pagetableentry.hpp deleted file mode 100755 index aa9fb8d..0000000 --- a/src/x86/pagetableentry.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef SRC_PAGETABLEENTRY_H_ -#define SRC_PAGETABLEENTRY_H_ - -#include -#include "../systypes.hpp" - -namespace kernel { - -class PageTableEntry { -public: - PageTableEntry(); - bool getAccessed() const; - bool getCacheDisable() const; - void setCacheDisable(bool cacheDisable); - bool getDirty() const; - bool getGlobal() const; - void setGlobal(bool global); - bool getPat() const; - void setPat(bool pat); - physaddr_t getPhysicalAddress() const; - physaddr_t setPhysicalAddress(physaddr_t physicalAddress); - bool getPresent() const; - void setPresent(bool present); - bool getRw() const; - void setRw(bool rw); - bool getShared() const; - void setShared(bool shared); - bool getUsermode() const; - void setUsermode(bool usermode); - bool getWriteThrough() const; - void setWriteThrough(bool writeThrough); - physaddr_t operator=(physaddr_t rhs); - PageTableEntry operator=(PageTableEntry rhs); - -private: - uint32_t present : 1; - uint32_t rw : 1; - uint32_t usermode : 1; - uint32_t writeThrough : 1; - uint32_t cacheDisable : 1; - uint32_t accessed : 1; - uint32_t dirty : 1; - uint32_t pat : 1; - uint32_t global : 1; - uint32_t shared : 1; - uint32_t ignored : 2; - uint32_t physicalAddress : 20; -}; - -} - -#endif From 4ceebe15d8f261d864d2bc88e2f922228bdc445d Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sat, 1 Aug 2020 19:45:35 -0500 Subject: [PATCH 006/109] Started work on a memory allocator --- src/allocator.cpp | 97 +++++++++++++++++++++++++++++++++++++++++++++++ src/allocator.hpp | 40 +++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 src/allocator.cpp create mode 100644 src/allocator.hpp diff --git a/src/allocator.cpp b/src/allocator.cpp new file mode 100644 index 0000000..cc24587 --- /dev/null +++ b/src/allocator.cpp @@ -0,0 +1,97 @@ +#include "allocator.hpp" + +#define AVAIL 0 +#define UNAVAIL -1 + +inline size_t ilog2(size_t n) +{ + size_t m = n; + size_t count = 0; + bool isPowerOfTwo = true; + while(m) + { + if((m & 1) == 1 && m > 1) + { + isPowerOfTwo = false; + } + count++; + m >>= 1; + } + return count - (isPowerOfTwo ? 1 : 0); +} + +kernel::Allocator::Allocator(void* base, size_t heapSize, size_t blockSize) +{ + this->base = (char*) base; + this->heapSize = heapSize; + this->blockSize = blockSize; + this->treeHeight = ilog2(heapSize / blockSize); + size_t headerSize = (heapSize / blockSize) << 1; + for(size_t i = 1; i < (heapSize / blockSize) * 2; i++) + this->base[i] = UNAVAIL; + for(size_t i = 0; i < heapSize / blockSize; i++) + { + if(blockSize * i >= headerSize) + { + size_t index = i + (1 << treeHeight); + this->base[index] = AVAIL; + for(; index > 1 && this->base[index ^ 1] == 0; index >>= 1) + { + this->base[index] = UNAVAIL; + this->base[index ^ 1] = UNAVAIL; + this->base[index >> 1] = AVAIL; + } + } + else + { + this->base[i + (1 << treeHeight)] = 1; + } + } +} + +void* kernel::Allocator::allocate(size_t size) +{ + size += blockSize - 1; + size -= size % blockSize; + size_t height = ilog2(size / blockSize); + size_t index = findFreeBlock(height); + if(index) + { + base[index] = height + 1; + return (void*) ((size_t) base + (blockSize << height) * (index - (1 << (treeHeight - height)))); + } + return NULL; +} + +void kernel::Allocator::free(void* location) +{ + size_t offset = (size_t) location - (size_t) base; + size_t index = (offset / blockSize) + (1 << treeHeight); + for(; index > 0 && base[index] == UNAVAIL; index >>= 1); + base[index] = AVAIL; + for(; index > 1 && base[index ^ 1] == AVAIL; index >>= 1) + { + base[index] = UNAVAIL; + base[index ^ 1] = UNAVAIL; + base[index >> 1] = AVAIL; + } +} + +size_t kernel::Allocator::findFreeBlock(size_t height) +{ + if(height > treeHeight) + return 0; + for(size_t index = 1 << (treeHeight - height); index < 1 << (treeHeight - height + 1); index++) + { + if(base[index] == AVAIL) + return index; + } + size_t index = findFreeBlock(height + 1); + if(index) + { + base[index] = UNAVAIL; + base[index << 1] = AVAIL; + base[(index << 1) ^ 1] = AVAIL; + } + return index << 1; +} \ No newline at end of file diff --git a/src/allocator.hpp b/src/allocator.hpp new file mode 100644 index 0000000..5e99c11 --- /dev/null +++ b/src/allocator.hpp @@ -0,0 +1,40 @@ +#ifndef ALLOCATOR_H +#define ALLOCATOR_H + +#include + +namespace kernel +{ + +class Allocator +{ +public: + + /** + * @param base A pointer to the start of the heap. + * @param heapSize The size of the heap, in bytes. Must be a power of two. + * @param blockSize The smallest unit of allocation, in bytes. Must be a power of two less than or equal to heapSize. + */ + Allocator(void* base, size_t heapSize, size_t blockSize); + + void* allocate(size_t size); + + void free(void* location); + +private: + + size_t findFreeBlock(size_t height); + + char* base; + + size_t heapSize; + + size_t blockSize; + + size_t treeHeight; + +}; + +} + +#endif \ No newline at end of file From 66cf91d3a5ed4b8c1a4b53c75a42568347f9856f Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sat, 1 Aug 2020 23:01:55 -0500 Subject: [PATCH 007/109] Started a DEVELOPERS file --- DEVELOPERS.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 DEVELOPERS.md diff --git a/DEVELOPERS.md b/DEVELOPERS.md new file mode 100644 index 0000000..14db3e1 --- /dev/null +++ b/DEVELOPERS.md @@ -0,0 +1,26 @@ +Notice: The kernel is still in early development. Some information in this file +may be inaccurate. Please create an issue if this is the case. + +# Porting + +The kernel should be portable to most systems, provided they support paging +and have sufficient memory. All platform-specific code belongs in an appropriately-named +subdirectory inside src/. It must provide a linker script, startup code, and +implement a set of functions required by the kernel. + +The linker script must define the following symbols: +- _pageMapLocation The location of the bitmap to be used by the page allocator. +- _heapLocation The location of the kernel's heap. +- _heapSize The size in bytes of the kernel's heap. +- _kernelStart The linear address of the start of the kernel image. +- _kernelEnd The first linear address after the end of the kernel image. + +The startup code is required to enable paging and relocate the kernel if necessary. It also +needs to provide a memory map to the kernel in the form of an array of MemoryMap::Region +structures. It should then call main() with a pointer to the kernel command line as an argument. + +In addition, the contents of mmap.hpp and interrupts.hpp must be implemented. + +# Files + +[TODO] \ No newline at end of file From 0b32783a2c8fd4c59a63dafa8d5867633e4aa646 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 2 Aug 2020 15:01:18 -0500 Subject: [PATCH 008/109] Added missing return value and default constructor --- src/scheduler.cpp | 6 ++++++ src/scheduler.hpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 718d8ca..c1c00c7 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -1,5 +1,10 @@ #include "scheduler.hpp" +kernel::ProcessQueue::ProcessQueue() +{ + +} + kernel::ProcessQueue::ProcessQueue(Process** array) { m_array = array; @@ -14,6 +19,7 @@ kernel::Process* kernel::ProcessQueue::extractMin() Process* p = m_array[0]; m_array[0] = m_array[m_size]; heapify(0); + return p; } void kernel::ProcessQueue::insert(Process* n) diff --git a/src/scheduler.hpp b/src/scheduler.hpp index 982795e..73a69db 100644 --- a/src/scheduler.hpp +++ b/src/scheduler.hpp @@ -22,6 +22,8 @@ class ProcessQueue { public: + ProcessQueue(); + ProcessQueue(Process** array); Process* extractMin(); From 50816a3b6d25930e086a2850a5d3de879a3e7d56 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 2 Aug 2020 15:03:35 -0500 Subject: [PATCH 009/109] Added key systems to kernel state --- src/kernelstate.hpp | 17 +++++++++++++---- src/mmap.hpp | 4 ++-- src/startup.cpp | 19 ++++++++++++++++--- src/x86/linker.ld | 9 ++++++++- src/x86/mmap.cpp | 9 +++++---- 5 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/kernelstate.hpp b/src/kernelstate.hpp index 7133f9c..b7ea052 100644 --- a/src/kernelstate.hpp +++ b/src/kernelstate.hpp @@ -1,9 +1,10 @@ #ifndef KERNELSTATE_H #define KERNELSTATE_H -#include - -#include "process.hpp" +#include "pageallocator.hpp" +#include "allocator.hpp" +#include "interrupts.hpp" +#include "scheduler.hpp" namespace kernel { @@ -12,7 +13,15 @@ class State { public: - static const size_t MAX_PROCESSES = 2048; + static const unsigned int MAX_PROCESSES = 2048; + + static BuddyAllocator pageAllocator; + + static Allocator allocator; + + static Interrupts interrupts; + + static ProcessQueue processQueue; }; diff --git a/src/mmap.hpp b/src/mmap.hpp index 3169629..8550153 100644 --- a/src/mmap.hpp +++ b/src/mmap.hpp @@ -10,9 +10,9 @@ namespace kernel { -int mmap(PageAllocator& allocator, void* start, size_t length, int flags); +int mmap(void* start, size_t length, int flags); -int munmap(PageAllocator& allocator, void* start, size_t length); +int munmap(void* start, size_t length); bool isMapped(void* addr); diff --git a/src/startup.cpp b/src/startup.cpp index abefa11..fa6da1c 100755 --- a/src/startup.cpp +++ b/src/startup.cpp @@ -6,28 +6,41 @@ #include "mmgr.hpp" #include "tty.hpp" #include "util.hpp" +#include "kernelstate.hpp" #include "config.h" using namespace kernel; +BuddyAllocator State::pageAllocator; +Allocator State::allocator; +Interrupts State::interrupts; +ProcessQueue State::processQueue; + +extern int _pageMapLocation; +extern int _heapLocation; +extern int _heapSize; + extern SystemInfo system_info; extern MemoryMap::Region memory_map; void main(char* cmdline) { + MemoryMap memmap(&memory_map, 16); + State::pageAllocator = BuddyAllocator(memmap, (char*) &_pageMapLocation, system_info.getHighMemory() / 4 + 256, 6); + mmap((void*) &_heapLocation, 0x100000, MMAP_RW); + State::allocator = Allocator((void*) 0xFFB00000, 0x100000, 256); + TTY tty((char*) 0xFF8B8000); tty << PACKAGE_STRING << "\n\n"; tty << "Low memory: \t" << (int) system_info.getLowMemory() << " KiB\n"; tty << "High memory:\t" << (int) system_info.getHighMemory() << " KiB\n"; tty << "Type\t\tLocation\t\tSize\n"; - MemoryMap memmap(&memory_map, 16); for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++) { tty << (int) memmap[i].getType() << "\t\t\t"; tty << (void*) memmap[i].getLocation() << "\t\t"; tty << (int) memmap[i].getSize() << "\n"; } - BuddyAllocator alloc(memmap, (char*) 0xFF800000, system_info.getHighMemory() / 4 + 256, 6); - mmap(alloc, (void*) 0, 4096, MMAP_RW); + mmap((void*) 0, 4096, MMAP_RW); tty << "Nothing left to do. Hanging.\n"; } diff --git a/src/x86/linker.ld b/src/x86/linker.ld index cfe1db2..55d5651 100755 --- a/src/x86/linker.ld +++ b/src/x86/linker.ld @@ -1,7 +1,8 @@ ENTRY(_start) - + SECTIONS { + . = 0xFF900000; VIRTUAL_BASE = .; PHYSICAL_BASE = 0x100000; @@ -33,4 +34,10 @@ SECTIONS LOAD_END = ADDR(.data) + SIZEOF(.data) - (VIRTUAL_BASE - PHYSICAL_BASE); BSS_END = ADDR(.bss) + SIZEOF(.bss) - (VIRTUAL_BASE - PHYSICAL_BASE); IMAGE_SIZE = ((BSS_END - LOAD_START) + (4096 - ((BSS_END - LOAD_START) % 4096))) / 4096; + + _pageMapLocation = 0xFF800000; + _heapLocation = 0xFFB00000; + _heapSize = 0x100000; + _kernelStart = VIRTUAL_BASE; + _kernelEnd = VIRTUAL_BASE + (4096 * IMAGE_SIZE); } diff --git a/src/x86/mmap.cpp b/src/x86/mmap.cpp index 1a8f530..87c7907 100644 --- a/src/x86/mmap.cpp +++ b/src/x86/mmap.cpp @@ -1,4 +1,5 @@ #include "../mmap.hpp" +#include "../kernelstate.hpp" class PageTableEntry { public: @@ -149,7 +150,7 @@ private: uint32_t physicalAddress : 20; }; -int kernel::mmap(PageAllocator& allocator, void* start, size_t length, int flags) +int kernel::mmap(void* start, size_t length, int flags) { if((size_t) start % 4096 != 0) return -1; @@ -161,7 +162,7 @@ int kernel::mmap(PageAllocator& allocator, void* start, size_t length, int flags size_t directoryIndex = tableIndex / 1024; if(!pageDirectory[directoryIndex].getPresent()) { - physaddr_t newPT = allocator.allocate(4096); + physaddr_t newPT = State::pageAllocator.allocate(4096); if(newPT == 0) return -1; pageDirectory[directoryIndex] = newPT; @@ -171,7 +172,7 @@ int kernel::mmap(PageAllocator& allocator, void* start, size_t length, int flags } if(!pageTables[tableIndex].getPresent()) { - physaddr_t page = allocator.allocate(4096); + physaddr_t page = State::pageAllocator.allocate(4096); pageTables[tableIndex] = page; pageTables[tableIndex].setPresent(true); pageTables[tableIndex].setUsermode(false); @@ -184,7 +185,7 @@ int kernel::mmap(PageAllocator& allocator, void* start, size_t length, int flags return 0; } -int kernel::munmap(PageAllocator& allocator, void* start, size_t length) +int kernel::munmap(void* start, size_t length) { if((size_t) start % 4096 != 0) return -1; From 436aa012b1c8a06351e87e81448a5bf55190bf59 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 2 Aug 2020 15:06:08 -0500 Subject: [PATCH 010/109] Added Allocator.cpp to sources list --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index e044453..52e771e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = startup.cpp elf.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp +quark_kernel_SOURCES = startup.cpp elf.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp quark_kernel_LDADD = -lgcc quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -nostdlib From f220514e7262f7df3b4d2f5c6b9ca1b26c05ac88 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 2 Aug 2020 15:06:23 -0500 Subject: [PATCH 011/109] Added default constructor to Allocator --- src/allocator.cpp | 5 +++++ src/allocator.hpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/allocator.cpp b/src/allocator.cpp index cc24587..6ecef06 100644 --- a/src/allocator.cpp +++ b/src/allocator.cpp @@ -20,6 +20,11 @@ inline size_t ilog2(size_t n) return count - (isPowerOfTwo ? 1 : 0); } +kernel::Allocator::Allocator() +{ + +} + kernel::Allocator::Allocator(void* base, size_t heapSize, size_t blockSize) { this->base = (char*) base; diff --git a/src/allocator.hpp b/src/allocator.hpp index 5e99c11..bd9dfbf 100644 --- a/src/allocator.hpp +++ b/src/allocator.hpp @@ -10,6 +10,8 @@ class Allocator { public: + Allocator(); + /** * @param base A pointer to the start of the heap. * @param heapSize The size of the heap, in bytes. Must be a power of two. From b924e632cf80bb23fcaccf36c6371bb997ef1fb2 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 2 Aug 2020 15:07:23 -0500 Subject: [PATCH 012/109] Fixed x86 lidt function, added addSyscall() method --- src/interrupts.hpp | 8 ++++++++ src/x86/interrupts.cpp | 13 ++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/interrupts.hpp b/src/interrupts.hpp index 173a002..d51d864 100644 --- a/src/interrupts.hpp +++ b/src/interrupts.hpp @@ -7,12 +7,20 @@ namespace kernel { public: + static const unsigned int MAX_SYSCALL_ID = 31; + Interrupts(); void enable(); void disable(); + void addSyscall(unsigned int id, void* function); + + private: + + void* syscalls[MAX_SYSCALL_ID + 1]; + }; } diff --git a/src/x86/interrupts.cpp b/src/x86/interrupts.cpp index 2b22417..c825113 100644 --- a/src/x86/interrupts.cpp +++ b/src/x86/interrupts.cpp @@ -1,6 +1,7 @@ #include "../interrupts.hpp" #include +#include class InterruptDescriptor { @@ -59,7 +60,9 @@ void lidt() IDTInfo idtInfo; idtInfo.size = sizeof(idt) - 1; idtInfo.location = (void*) &idt; - asm("lidt idt"); + asm("lidt (%0)" + : + : "r" (&idtInfo)); } __attribute__ ((interrupt)) @@ -156,6 +159,8 @@ void* InterruptDescriptor::operator=(void* rhs) kernel::Interrupts::Interrupts() { + for(unsigned int i = 0; i <= MAX_SYSCALL_ID; i++) + syscalls[i] = (void*) NULL; idt[0] = InterruptDescriptor((void*) &divisionByZero, InterruptDescriptor::INT32, 0); idt[8] = InterruptDescriptor((void*) &doubleFaultHandler, InterruptDescriptor::INT32, 0); idt[0x80] = InterruptDescriptor((void*) &syscallHandler, InterruptDescriptor::INT32, 0); @@ -172,4 +177,10 @@ void kernel::Interrupts::enable() void kernel::Interrupts::disable() { asm("cli"); +} + +void kernel::Interrupts::addSyscall(unsigned int id, void* function) +{ + if(id <= MAX_SYSCALL_ID) + syscalls[id] = function; } \ No newline at end of file From b8d694e182b0ab5c2030f796d4502de3ef0a03de Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 2 Aug 2020 15:12:01 -0500 Subject: [PATCH 013/109] Moved x86 InterruptDescriptor methods into class definition --- src/x86/interrupts.cpp | 125 ++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 71 deletions(-) diff --git a/src/x86/interrupts.cpp b/src/x86/interrupts.cpp index c825113..7845ef5 100644 --- a/src/x86/interrupts.cpp +++ b/src/x86/interrupts.cpp @@ -16,23 +16,68 @@ public: INT16 = 6 }; - InterruptDescriptor(); + InterruptDescriptor() + { + this->m_offset1 = 0; + this->m_selector = 0; + this->m_zero = 0; + this->m_type = 0; + this->m_storage = 0; + this->m_dpl = 0; + this->m_present = 0; + this->m_offset2 = 0; + } - InterruptDescriptor(void* handler, Type type, unsigned int dpl); + InterruptDescriptor(void* handler, Type type, unsigned int dpl) + { + uint32_t offset = (uint32_t) handler; + this->m_offset1 = (uint16_t) offset; + this->m_selector = 8; + this->m_zero = 0; + this->m_type = (uint16_t) type; + this->m_storage = 0; + this->m_dpl = dpl; + this->m_present = 1; + this->m_offset2 = offset >> 16; + } - bool present(); + bool present() + { + return m_present == 1; + } - void present(bool present); + void present(bool present) + { + m_present = present ? 1 : 0; + } - Type type(); + Type type() + { + return (Type) m_type; + } - void type(Type type); + void type(Type type) + { + m_type = (unsigned int) type; + } - unsigned int dpl(); + unsigned int dpl() + { + return m_dpl; + } - void dpl(unsigned int dpl); + void dpl(unsigned int dpl) + { + m_dpl = dpl; + } - void* operator=(void* rhs); + void* operator=(void* rhs) + { + uint32_t offset = (uint32_t) rhs; + m_offset1 = (uint16_t) offset; + m_offset2 = (offset >> 16); + return rhs; + } private: @@ -95,68 +140,6 @@ void syscallHandler(void* frame) } -InterruptDescriptor::InterruptDescriptor() -{ - this->m_offset1 = 0; - this->m_selector = 0; - this->m_zero = 0; - this->m_type = 0; - this->m_storage = 0; - this->m_dpl = 0; - this->m_present = 0; - this->m_offset2 = 0; -} - -InterruptDescriptor::InterruptDescriptor(void* handler, Type type, unsigned int dpl) -{ - uint32_t offset = (uint32_t) handler; - this->m_offset1 = (uint16_t) offset; - this->m_selector = 8; - this->m_zero = 0; - this->m_type = (uint16_t) type; - this->m_storage = 0; - this->m_dpl = dpl; - this->m_present = 1; - this->m_offset2 = offset >> 16; -} - -bool InterruptDescriptor::present() -{ - return m_present == 1; -} -void InterruptDescriptor::present(bool present) -{ - m_present = present ? 1 : 0; -} - -InterruptDescriptor::Type InterruptDescriptor::type() -{ - return (Type) m_type; -} - -void InterruptDescriptor::type(InterruptDescriptor::Type type) -{ - m_type = (unsigned int) type; -} - -unsigned int InterruptDescriptor::dpl() -{ - return m_dpl; -} - -void InterruptDescriptor::dpl(unsigned int dpl) -{ - m_dpl = dpl; -} - -void* InterruptDescriptor::operator=(void* rhs) -{ - uint32_t offset = (uint32_t) rhs; - m_offset1 = (uint16_t) offset; - m_offset2 = (offset >> 16); - return rhs; -} - kernel::Interrupts::Interrupts() { for(unsigned int i = 0; i <= MAX_SYSCALL_ID; i++) From 98197ec8eaae3dc781c6c98beb33d17894929629 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 2 Aug 2020 18:30:54 -0500 Subject: [PATCH 014/109] Renamed elf.cpp to module.cpp, started Module class --- src/{elf.cpp => module.cpp} | 17 +++++++++++------ src/{elf.hpp => module.hpp} | 22 +++++++++++++++++++++- 2 files changed, 32 insertions(+), 7 deletions(-) rename src/{elf.cpp => module.cpp} (56%) rename src/{elf.hpp => module.hpp} (92%) diff --git a/src/elf.cpp b/src/module.cpp similarity index 56% rename from src/elf.cpp rename to src/module.cpp index ff503ab..e327acf 100644 --- a/src/elf.cpp +++ b/src/module.cpp @@ -1,20 +1,25 @@ #include "elf.hpp" #include "util.hpp" +kernel::ELF::ELF() +{ + this->m_fileLocation = (void*) NULL; +} + kernel::ELF::ELF(void* location) { - this->location = location; + this->m_fileLocation = location; } void* kernel::ELF::entry() { - Header* fileHeader = (Header*) location; + Header* fileHeader = (Header*) m_fileLocation; return fileHeader->entry; } int kernel::ELF::validate() { - Header* fileHeader = (Header*) location; + Header* fileHeader = (Header*) m_fileLocation; if(fileHeader->magic != 0x464c457f) return -1; else if((ISA) fileHeader->machine != HOST_ISA) @@ -26,14 +31,14 @@ int kernel::ELF::validate() int kernel::ELF::load() { - Header* fileHeader = (Header*) location; - ProgramHeader* programHeader = (ProgramHeader*) ((size_t) location + fileHeader->phoffset); + 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, location + programHeader->offset, programHeader->filesize); + memcpy(programHeader->vaddr, m_fileLocation + programHeader->offset, programHeader->filesize); } return 0; } \ No newline at end of file diff --git a/src/elf.hpp b/src/module.hpp similarity index 92% rename from src/elf.hpp rename to src/module.hpp index bf62255..9f7748d 100644 --- a/src/elf.hpp +++ b/src/module.hpp @@ -123,6 +123,8 @@ public: static const ISA HOST_ISA = aarch64; #endif + ELF(); + ELF(void* location); void* entry(); @@ -133,7 +135,25 @@ public: private: - void* location; + void* m_fileLocation; + +}; + +class Module +{ +public: + + Module(); + + Module(physaddr_t start, physaddr_t end); + +private: + + physaddr_t m_start; + + physaddr_t m_end; + + ELF binary; }; From 29677e0391da0fea098af9407c2347a4e5e66033 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 2 Aug 2020 18:46:09 -0500 Subject: [PATCH 015/109] Added kernel end field to systeminfo --- src/systeminfo.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/systeminfo.hpp b/src/systeminfo.hpp index 33ef728..9632f65 100644 --- a/src/systeminfo.hpp +++ b/src/systeminfo.hpp @@ -25,6 +25,8 @@ private: size_t highMemory; physaddr_t kernelBase; + + physaddr_t kernelEnd; }; From c601aed9f21540add494e31d631da701574cc312 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 18 Nov 2020 13:36:09 -0600 Subject: [PATCH 016/109] Wrote strlen() and strcpy() --- src/Makefile.am | 2 +- src/module.cpp | 2 +- src/util.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++- src/util.hpp | 4 ++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 52e771e..718ad10 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = startup.cpp elf.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp +quark_kernel_SOURCES = startup.cpp module.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp quark_kernel_LDADD = -lgcc quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -nostdlib diff --git a/src/module.cpp b/src/module.cpp index e327acf..c0a1eee 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -1,4 +1,4 @@ -#include "elf.hpp" +#include "module.hpp" #include "util.hpp" kernel::ELF::ELF() diff --git a/src/util.cpp b/src/util.cpp index fe13afc..2dfa310 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -64,7 +64,7 @@ int memcmp(const void* ptr1, const void* ptr2, size_t num) return 0; } -void* memset (void* ptr, int value, size_t num) +void* memset(void* ptr, int value, size_t num) { uint8_t* dest = (uint8_t*) ptr; uint8_t v = (uint8_t) value; @@ -75,6 +75,51 @@ void* memset (void* ptr, int value, size_t num) return ptr; } +int strlen(const char* str) +{ + int i = 0; + while(str[i] != '\0') + { + i++; + } + return i; +} + +char* strcpy(char* destination, const char* source) +{ + int sourceLen = strlen(source); + if((destination <= source) || (destination > (source + sourceLen))) + { + char* d = destination; + const char* s = source; + while(true) + { + *d = *s; + if(*s == '\0') + { + break; + } + else + { + s++; + d++; + } + } + } + else + { + char* d = destination + sourceLen; + const char* s = source + sourceLen; + do + { + *d = *s; + d--; + s--; + } while(d > destination); + } + return destination; +} + void __cxa_pure_virtual() { // do nothing diff --git a/src/util.hpp b/src/util.hpp index acf21d0..a16c112 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -13,4 +13,8 @@ extern "C" int memcmp(const void* ptr1, const void* ptr2, size_t num); extern "C" void* memset(void* ptr, int value, size_t num); +extern "C" int strlen(const char* str); + +extern "C" char* strcpy(char* destination, const char* source); + #endif \ No newline at end of file From d3eab67473c2ad3bf9caf77f7b83e6eb0eb72d6b Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Thu, 19 Nov 2020 10:05:27 -0600 Subject: [PATCH 017/109] Wrote mmap overload with physical address argument --- src/mmap.hpp | 2 ++ src/x86/mmap.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/mmap.hpp b/src/mmap.hpp index 8550153..54b905d 100644 --- a/src/mmap.hpp +++ b/src/mmap.hpp @@ -12,6 +12,8 @@ namespace kernel int mmap(void* start, size_t length, int flags); +int mmap(void* start, physaddr_t p_start, size_t length, int flags); + int munmap(void* start, size_t length); bool isMapped(void* addr); diff --git a/src/x86/mmap.cpp b/src/x86/mmap.cpp index 87c7907..0aa9e2a 100644 --- a/src/x86/mmap.cpp +++ b/src/x86/mmap.cpp @@ -185,6 +185,42 @@ int kernel::mmap(void* start, size_t length, int flags) return 0; } +int kernel::mmap(void* start, physaddr_t p_start, size_t length, int flags) +{ + if((size_t) start % 4096 != 0 || p_start % 4096 != 0) + return -1; + PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; + PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; + size_t tableIndex = (size_t) start / 4096; + physaddr_t page = p_start; + for(int i = (int) length; i > 0; i -= 4096) + { + size_t directoryIndex = tableIndex / 1024; + if(!pageDirectory[directoryIndex].getPresent()) + { + physaddr_t newPT = State::pageAllocator.allocate(4096); + if(newPT == 0) + return -1; + pageDirectory[directoryIndex] = newPT; + pageDirectory[directoryIndex].setPresent(true); + pageDirectory[directoryIndex].setUsermode(false); + pageDirectory[directoryIndex].setRw(true); + } + if(!pageTables[tableIndex].getPresent()) + { + pageTables[tableIndex] = page; + pageTables[tableIndex].setPresent(true); + pageTables[tableIndex].setUsermode(false); + if(flags & MMAP_RW) + pageTables[tableIndex].setRw(true); + + } + tableIndex++; + page += 4096; + } + return 0; +} + int kernel::munmap(void* start, size_t length) { if((size_t) start % 4096 != 0) From c1ec6a962bc431d23ea1c8b807bd2eb3961b4fff Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 05:06:16 -0600 Subject: [PATCH 018/109] Wrote new Multiboot2 table reader --- configure.ac | 4 +- src/memorymap.cpp | 223 ++++++++++++++++++++++++++++++++++++++--- src/memorymap.hpp | 88 +++++++++++----- src/module.cpp | 49 ++++----- src/module.hpp | 143 ++------------------------ src/util.cpp | 36 +++++++ src/util.hpp | 38 ++++++- src/x86/multiboot2.cpp | 78 ++++++++++++++ src/x86/multiboot2.hpp | 105 +++++++++++++++++++ 9 files changed, 561 insertions(+), 203 deletions(-) create mode 100644 src/x86/multiboot2.cpp create mode 100644 src/x86/multiboot2.hpp 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 From 44946c8d9dbb181df8e5484b8f3c9154b3de5d0f Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 05:06:26 -0600 Subject: [PATCH 019/109] Removed module from grub.cfg --- rootfs/boot/grub/grub.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 1910960..a731acc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -1,4 +1,3 @@ menuentry "Quark OS" { multiboot2 /apps/quark-kernel - module2 /apps/test } \ No newline at end of file From 11813469f7d19927e0f2f1d6ad6629ca9c551e29 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 05:07:12 -0600 Subject: [PATCH 020/109] Re-added (bare bones) ELF program loader --- src/elf.cpp | 44 ++++++++++++++++ src/elf.hpp | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 src/elf.cpp create mode 100644 src/elf.hpp diff --git a/src/elf.cpp b/src/elf.cpp new file mode 100644 index 0000000..e327acf --- /dev/null +++ b/src/elf.cpp @@ -0,0 +1,44 @@ +#include "elf.hpp" +#include "util.hpp" + +kernel::ELF::ELF() +{ + this->m_fileLocation = (void*) NULL; +} + +kernel::ELF::ELF(void* location) +{ + this->m_fileLocation = location; +} + +void* kernel::ELF::entry() +{ + Header* fileHeader = (Header*) m_fileLocation; + return fileHeader->entry; +} + +int kernel::ELF::validate() +{ + 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; +} + +int kernel::ELF::load() +{ + 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; +} \ No newline at end of file diff --git a/src/elf.hpp b/src/elf.hpp new file mode 100644 index 0000000..341296c --- /dev/null +++ b/src/elf.hpp @@ -0,0 +1,142 @@ +#ifndef ELF_H +#define ELF_H + +#include "systypes.hpp" + +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; + +}; + +} + +#endif \ No newline at end of file From 231d6c4464d62828aa87733962faa5bb135709ba Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 05:07:58 -0600 Subject: [PATCH 021/109] Added const specifier to memory map argument --- src/pageallocator.cpp | 2 +- src/pageallocator.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pageallocator.cpp b/src/pageallocator.cpp index 761a52d..d31617c 100755 --- a/src/pageallocator.cpp +++ b/src/pageallocator.cpp @@ -26,7 +26,7 @@ kernel::BuddyAllocator::BuddyAllocator() } -kernel::BuddyAllocator::BuddyAllocator(kernel::MemoryMap& memmap, +kernel::BuddyAllocator::BuddyAllocator(const kernel::MemoryMap& memmap, char* bitmap, size_t blockCount, size_t treeHeight) { diff --git a/src/pageallocator.hpp b/src/pageallocator.hpp index d3034ec..27e2acd 100755 --- a/src/pageallocator.hpp +++ b/src/pageallocator.hpp @@ -57,7 +57,7 @@ public: BuddyAllocator(); - BuddyAllocator(MemoryMap& memmap, char* bitmap, size_t blockCount, + BuddyAllocator(const MemoryMap& memmap, char* bitmap, size_t blockCount, size_t treeHeight); BuddyAllocator(char* bitmap, size_t blockSize, size_t blockCount, From d2eecf95e5bf9b1909811a02f8033521cd8147c4 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 05:08:55 -0600 Subject: [PATCH 022/109] Re-wrote boot code, moved to x86 folder --- src/Makefile.am | 5 +- src/kernelstate.cpp | 9 ++ src/kernelstate.hpp | 3 + src/startup.cpp | 46 ---------- src/systeminfo.cpp | 21 +++-- src/systeminfo.hpp | 17 ++-- src/x86/entry.S | 203 +++++++++-------------------------------- src/x86/initialize.cpp | 77 ++++++++++++++++ src/x86/linker.ld | 1 - src/{ => x86}/tty.cpp | 0 src/{ => x86}/tty.hpp | 0 11 files changed, 160 insertions(+), 222 deletions(-) create mode 100644 src/kernelstate.cpp delete mode 100755 src/startup.cpp create mode 100644 src/x86/initialize.cpp rename src/{ => x86}/tty.cpp (100%) rename src/{ => x86}/tty.hpp (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 718ad10..aad19a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,15 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = startup.cpp module.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp +quark_kernel_SOURCES = kernelstate.cpp module.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp quark_kernel_LDADD = -lgcc quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -nostdlib if x86 quark_kernel_SOURCES += x86/mmap.cpp \ + x86/tty.cpp \ x86/interrupts.cpp \ + x86/multiboot2.cpp \ + x86/initialize.cpp \ x86/entry.S quark_kernel_LDFLAGS += -T x86/linker.ld quark_kernel_DEPENDENCIES = x86/linker.ld diff --git a/src/kernelstate.cpp b/src/kernelstate.cpp new file mode 100644 index 0000000..561ba16 --- /dev/null +++ b/src/kernelstate.cpp @@ -0,0 +1,9 @@ +#include "kernelstate.hpp" + +using namespace kernel; + +BuddyAllocator State::pageAllocator; +Allocator State::allocator; +Interrupts State::interrupts; +ProcessQueue State::processQueue; +SystemInfo State::config; \ No newline at end of file diff --git a/src/kernelstate.hpp b/src/kernelstate.hpp index b7ea052..77a3cb8 100644 --- a/src/kernelstate.hpp +++ b/src/kernelstate.hpp @@ -5,6 +5,7 @@ #include "allocator.hpp" #include "interrupts.hpp" #include "scheduler.hpp" +#include "systeminfo.hpp" namespace kernel { @@ -23,6 +24,8 @@ public: static ProcessQueue processQueue; + static SystemInfo config; + }; } diff --git a/src/startup.cpp b/src/startup.cpp deleted file mode 100755 index fa6da1c..0000000 --- a/src/startup.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include - -#include "systypes.hpp" -#include "systeminfo.hpp" -#include "mmgr.hpp" -#include "tty.hpp" -#include "util.hpp" -#include "kernelstate.hpp" -#include "config.h" - -using namespace kernel; - -BuddyAllocator State::pageAllocator; -Allocator State::allocator; -Interrupts State::interrupts; -ProcessQueue State::processQueue; - -extern int _pageMapLocation; -extern int _heapLocation; -extern int _heapSize; - -extern SystemInfo system_info; -extern MemoryMap::Region memory_map; - -void main(char* cmdline) -{ - MemoryMap memmap(&memory_map, 16); - State::pageAllocator = BuddyAllocator(memmap, (char*) &_pageMapLocation, system_info.getHighMemory() / 4 + 256, 6); - mmap((void*) &_heapLocation, 0x100000, MMAP_RW); - State::allocator = Allocator((void*) 0xFFB00000, 0x100000, 256); - - TTY tty((char*) 0xFF8B8000); - tty << PACKAGE_STRING << "\n\n"; - tty << "Low memory: \t" << (int) system_info.getLowMemory() << " KiB\n"; - tty << "High memory:\t" << (int) system_info.getHighMemory() << " KiB\n"; - tty << "Type\t\tLocation\t\tSize\n"; - for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++) - { - tty << (int) memmap[i].getType() << "\t\t\t"; - tty << (void*) memmap[i].getLocation() << "\t\t"; - tty << (int) memmap[i].getSize() << "\n"; - } - mmap((void*) 0, 4096, MMAP_RW); - tty << "Nothing left to do. Hanging.\n"; -} diff --git a/src/systeminfo.cpp b/src/systeminfo.cpp index 0ed92e4..1151de1 100644 --- a/src/systeminfo.cpp +++ b/src/systeminfo.cpp @@ -1,16 +1,25 @@ #include "systeminfo.hpp" +#include "util.hpp" -size_t kernel::SystemInfo::getLowMemory() +using namespace kernel; + +SystemInfo::SystemInfo() { - return lowMemory; + } -size_t kernel::SystemInfo::getHighMemory() +SystemInfo::SystemInfo(MemoryMap& memoryMap, const char* commandLine) + : m_memmap(memoryMap) { - return highMemory; + strcpy(this->commandLine, commandLine); } -physaddr_t kernel::SystemInfo::getKernelBase() +const MemoryMap& SystemInfo::getMemoryMap() const { - return kernelBase; + return m_memmap; +} + +const char* SystemInfo::getCommandLine() const +{ + return commandLine; } diff --git a/src/systeminfo.hpp b/src/systeminfo.hpp index 9632f65..81727cd 100644 --- a/src/systeminfo.hpp +++ b/src/systeminfo.hpp @@ -4,6 +4,7 @@ #include #include "systypes.hpp" +#include "memorymap.hpp" namespace kernel { @@ -12,21 +13,19 @@ class SystemInfo { public: - size_t getLowMemory(); + SystemInfo(); - size_t getHighMemory(); + SystemInfo(MemoryMap& memoryMap, const char* commandLine); - physaddr_t getKernelBase(); + const MemoryMap& getMemoryMap() const; + + const char* getCommandLine() const; private: - - size_t lowMemory; - size_t highMemory; + MemoryMap m_memmap; - physaddr_t kernelBase; - - physaddr_t kernelEnd; + char commandLine[128]; }; diff --git a/src/x86/entry.S b/src/x86/entry.S index 7a68f9d..fd6c079 100755 --- a/src/x86/entry.S +++ b/src/x86/entry.S @@ -143,181 +143,54 @@ memory_map: .global _start .type _start, @function _start: + # This platform reqires a Multiboot2 bootloader. cmp $0x36d76289, %eax - jne _err + jne .err - movb $64, 0xB8000 + # Initialize stack in physical address space + mov $stackTop, %esp + sub $BASE_DIFF, %esp - mov $system_info, %edi - sub $BASE_DIFF, %edi - add $8, %ebx - -switch: - mov (%ebx), %eax - cmp $0, %eax - je s_end - cmp $1, %eax - je tag_1 - cmp $3, %eax - je tag_3 - cmp $4, %eax - je tag_4 - cmp $6, %eax - je tag_6 - cmp $21, %eax - je tag_21 - jmp def - -# Boot command line -tag_1: - mov 4(%ebx), %ecx - sub $8, %ecx - mov %ebx, %esi - add $8, %esi - mov $_bootCmdLine, %edi - sub $BASE_DIFF, %edi - rep movsb - mov $system_info, %edi - sub $BASE_DIFF, %edi - jmp def - -tag_3: - mov 8(%ebx), %esi - mov (%esi), %eax - mov %al, (0xB8004) - mov %ah, (0xB8006) - shr $16, %eax - mov %al, (0xB8008) - mov %ah, (0xB800a) - jmp def - -# Basic memory info -tag_4: - mov 8(%ebx), %eax - mov %eax, (%edi) - mov 12(%ebx), %eax - mov %eax, 4(%edi) - jmp def - -# Memory map -tag_6: - mov $memory_map, %esi - sub $BASE_DIFF, %esi # set esi to point to the table in the kernel image - mov 4(%ebx), %ecx - sub $16, %ecx # set ecx to store the size of the table provided by the bootloader - mov 8(%ebx), %edx # set edx to store the size of each table entry - add $16, %ebx # move ebx up to the first entry -1: mov (%ebx), %eax - mov %eax, (%esi) # save the address of that region in memory - mov 8(%ebx), %eax - mov %eax, 4(%esi) # save the size of that region in memory - mov 16(%ebx), %eax - mov %eax, 8(%esi) # save the type of memory in that region - add $12, %esi # move esi to the next entry in the kernel's array - add %edx, %ebx # move ebx to the next entry in the bootloader's array - sub %edx, %ecx # subtract the size of an entry from ecx. - jnz 1b # loop if there are entries left - mov $0, %eax - mov %eax, (%esi) - mov %eax, 4(%esi) - mov %eax, 8(%esi) - jmp switch - -# Program image location -tag_21: - mov 8(%ebx), %eax - mov %eax, 8(%edi) - jmp def - -def: - mov 4(%ebx), %eax - add $7, %eax - and $0xFFFFFFF8, %eax - add %eax, %ebx - jmp switch -s_end: - - movb $64, 0xB8002 - - mov $0, %ecx -1: - # Generate a page table entry pointing to a page in the kernel binary - mov %ecx, %eax - mov $4096, %edx - mul %edx - or $3, %eax - - # Load the address of the temporary page table and translate it to a physical address - mov $_tempPgTable, %edi - sub $BASE_DIFF, %edi - - # Save the PTE into an entry in the temporary page table - mov %eax, (%edi, %ecx, 4) - - # Load the address of the identity map and translate it to a physical address - mov $_tempIdentityMap, %edi - sub $BASE_DIFF, %edi - - # Save the PTE into an entry in the identity map - mov %eax, (%edi, %ecx, 4) - - # Increment count and loop - inc %ecx - mov $IMAGE_SIZE, %edx - add $256, %edx - cmp %edx, %ecx - jne 1b - - # Load the physical address of the identity map, and generate a PDE + # Push physical address of identity map mov $_tempIdentityMap, %eax sub $BASE_DIFF, %eax - or $3, %eax + push %eax - # Load the physical address of the page directory - mov $_tempPgDir, %edi - sub $BASE_DIFF, %edi - - # Save the PDE to the first element in the page directory - mov %eax, (%edi) - - # Load the physical address of the temporary page table, and generate a PDE + # Push physical address of page table mov $_tempPgTable, %eax sub $BASE_DIFF, %eax - or $3, %eax + push %eax - # Save the PDE to the entry corresponding to 0xC0000000 - mov %eax, 4088(%edi) - - # Set the last entry in the page directory to point to the page directory itself - mov %edi, %eax - or $3, %eax - mov %eax, 4092(%edi) + # Push physical address of page directory + mov $_tempPgDir, %eax + sub $BASE_DIFF, %eax + push %eax - # Load the physical address of the page directory into CR3 - mov $_tempPgDir, %edi - sub $BASE_DIFF, %edi - mov %edi, %cr3 - - # Enable paging - mov %cr0, %eax - or $0x80010000, %eax - mov %eax, %cr0 + # Load physical address of startPaging() + mov $startPaging, %eax + sub $BASE_DIFF, %eax + + # Initialize paging + call *%eax # Jump into mapped kernel binary - lea 2f, %eax + lea 1f, %eax jmp *%eax -2: +1: # Delete PDE corresponding to identity map. We shouldn't need it anymore. movl $0, (_tempIdentityMap) - # Reload page tables + # Flush TLB mov %cr3, %eax mov %eax, %cr3 - # Initialize stack + # Initialize stack in virtual memory mov $stackTop, %esp + + # Load GPT lgdt gdt_info + # Load segment registers jmp $8, $.ldcs .ldcs: mov $16, %ax @@ -327,15 +200,27 @@ s_end: mov %ax, %fs mov %ax, %ss - mov $_bootCmdLine, %eax - push %eax + # Change EBX to point to the virtual address of the multiboot info + # If the new pointer is out-of-bounds, error + add $0xFF800000, %ebx + cmp $0xFF800000, %ebx + jl .err + cmp $0xFFC00000, %ebx + jge .err + + # Call initialize(void* multibootInfo) + push %ebx + call initialize + + # mov $_bootCmdLine, %eax + # push %eax # Call main function - call main + # call main -_err: +.err: cli -3: hlt - jmp 3b +2: hlt + jmp 2b .size _start, . - _start diff --git a/src/x86/initialize.cpp b/src/x86/initialize.cpp new file mode 100644 index 0000000..17dcdf0 --- /dev/null +++ b/src/x86/initialize.cpp @@ -0,0 +1,77 @@ +#include +#include "multiboot2.hpp" +#include "tty.hpp" +#include "../kernelstate.hpp" +#include "../systeminfo.hpp" +#include "../mmap.hpp" +#include "../util.hpp" + +using namespace kernel; + +extern int _kernelEnd; + +enum BootInfoType +{ + Terminate = 0, + CommandLine = 1, + BootLoader = 2, + Module = 3, + MemoryInfo = 4, + BootDevice = 5, + MMap = 6, + VBEInfo = 7, + FramebufferInfo = 8, + ELFSymbols = 9, + APMTable = 10 +}; + +extern "C" +int startPaging(uint32_t* directory, uint32_t* table, uint32_t* identityTable) +{ + for(int i = 0; i < 1024; i++) + { + uint32_t pte = i * 4096 + 3; + table[i] = pte; + identityTable[i] = pte; + } + directory[0] = ((uint32_t) identityTable) + 3; + directory[1022] = ((uint32_t) table) + 3; + directory[1023] = ((uint32_t) directory) + 3; + asm("mov %0, %%cr3" + : + : "r" (directory)); + asm("mov %%cr0, %%eax \n" + "or $0x80010000, %%eax \n" + "mov %%eax, %%cr0" + : + : + : "eax"); + return 0; +} + +extern "C" +int initialize(void* multibootInfo) +{ + size_t heapSize = 0xFFC00000 - (size_t) &_kernelEnd; + int log = 0; + for(; heapSize > 1; log++) + heapSize >>= 1; + heapSize <<= log; + new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64); + Multiboot2Info bootInfo(multibootInfo); + if(!bootInfo.isValid()) + return 1; + bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, MemoryMap::UNAVAILABLE); + new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine()); + TTY tty((char*) 0xFF8B8000); + tty << "Type\t\tLocation\t\tSize\n"; + for(size_t i = 0; i < bootInfo.getMemoryMap().size() && bootInfo.getMemoryMap()[i].getSize() > 0; i++) + { + tty << (int) bootInfo.getMemoryMap()[i].getType() << "\t\t\t"; + tty << (void*) bootInfo.getMemoryMap()[i].getLocation() << "\t\t"; + tty << (int) bootInfo.getMemoryMap()[i].getSize() << "\n"; + } + // TODO: Initialize page allocator + // TODO: Initialize process queue, add entry for each module + return 0; +} diff --git a/src/x86/linker.ld b/src/x86/linker.ld index 55d5651..df4267a 100755 --- a/src/x86/linker.ld +++ b/src/x86/linker.ld @@ -2,7 +2,6 @@ ENTRY(_start) SECTIONS { - . = 0xFF900000; VIRTUAL_BASE = .; PHYSICAL_BASE = 0x100000; diff --git a/src/tty.cpp b/src/x86/tty.cpp similarity index 100% rename from src/tty.cpp rename to src/x86/tty.cpp diff --git a/src/tty.hpp b/src/x86/tty.hpp similarity index 100% rename from src/tty.hpp rename to src/x86/tty.hpp From 2bff533ec1aa39c581e91584fda2081b9253ec0f Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 05:09:38 -0600 Subject: [PATCH 023/109] Updated .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e008fba..0a6e77e 100755 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ quark-kernel autom4te.cache/ .deps +.dirstamp aclocal.m4 ar-lib compile From b3b41549798d1e684920d5fe92d56af886758b96 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 06:24:27 -0600 Subject: [PATCH 024/109] Added function to map single page to specific frame --- src/mmap.hpp | 2 ++ src/x86/mmap.cpp | 55 +++++++++++++++++++++++++++--------------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/mmap.hpp b/src/mmap.hpp index 54b905d..83f243e 100644 --- a/src/mmap.hpp +++ b/src/mmap.hpp @@ -14,6 +14,8 @@ int mmap(void* start, size_t length, int flags); int mmap(void* start, physaddr_t p_start, size_t length, int flags); +int mapPage(void* start, physaddr_t p_start, int flags); + int munmap(void* start, size_t length); bool isMapped(void* addr); diff --git a/src/x86/mmap.cpp b/src/x86/mmap.cpp index 0aa9e2a..ea0e14f 100644 --- a/src/x86/mmap.cpp +++ b/src/x86/mmap.cpp @@ -178,7 +178,6 @@ int kernel::mmap(void* start, size_t length, int flags) pageTables[tableIndex].setUsermode(false); if(flags & MMAP_RW) pageTables[tableIndex].setRw(true); - } tableIndex++; } @@ -186,6 +185,20 @@ int kernel::mmap(void* start, size_t length, int flags) } int kernel::mmap(void* start, physaddr_t p_start, size_t length, int flags) +{ + if((size_t) start % 4096 != 0 || p_start % 4096 != 0) + return -1; + physaddr_t page = p_start; + for(int i = (int) length; i > 0; i -= 4096) + { + if(mapPage(start, page, flags) != 0) + return -1; + page += 4096; + } + return 0; +} + +int kernel::mapPage(void* start, physaddr_t p_start, int flags) { if((size_t) start % 4096 != 0 || p_start % 4096 != 0) return -1; @@ -193,30 +206,24 @@ int kernel::mmap(void* start, physaddr_t p_start, size_t length, int flags) PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; size_t tableIndex = (size_t) start / 4096; physaddr_t page = p_start; - for(int i = (int) length; i > 0; i -= 4096) + size_t directoryIndex = tableIndex / 1024; + if(!pageDirectory[directoryIndex].getPresent()) { - size_t directoryIndex = tableIndex / 1024; - if(!pageDirectory[directoryIndex].getPresent()) - { - physaddr_t newPT = State::pageAllocator.allocate(4096); - if(newPT == 0) - return -1; - pageDirectory[directoryIndex] = newPT; - pageDirectory[directoryIndex].setPresent(true); - pageDirectory[directoryIndex].setUsermode(false); - pageDirectory[directoryIndex].setRw(true); - } - if(!pageTables[tableIndex].getPresent()) - { - pageTables[tableIndex] = page; - pageTables[tableIndex].setPresent(true); - pageTables[tableIndex].setUsermode(false); - if(flags & MMAP_RW) - pageTables[tableIndex].setRw(true); - - } - tableIndex++; - page += 4096; + physaddr_t newPT = State::pageAllocator.allocate(4096); + if(newPT == 0) + return -1; + pageDirectory[directoryIndex] = newPT; + pageDirectory[directoryIndex].setPresent(true); + pageDirectory[directoryIndex].setUsermode(false); + pageDirectory[directoryIndex].setRw(true); + } + if(!pageTables[tableIndex].getPresent()) + { + pageTables[tableIndex] = page; + pageTables[tableIndex].setPresent(true); + pageTables[tableIndex].setUsermode(false); + if(flags & MMAP_RW) + pageTables[tableIndex].setRw(true); } return 0; } From ba91c9d0e222f142b0a9f6fbde879d143d52915b Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 06:46:24 -0600 Subject: [PATCH 025/109] Moved process class to its own file --- src/process.hpp | 23 +++++++++++++++++++++++ src/scheduler.hpp | 14 ++------------ 2 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 src/process.hpp diff --git a/src/process.hpp b/src/process.hpp new file mode 100644 index 0000000..73e7a1c --- /dev/null +++ b/src/process.hpp @@ -0,0 +1,23 @@ +#ifndef PROCESS_H +#define PROCESS_H + +#include + +namespace kernel +{ + +class Process +{ +public: + + Process(); + + size_t priority; + + void* stack; + +}; + +} + +#endif \ No newline at end of file diff --git a/src/scheduler.hpp b/src/scheduler.hpp index 73a69db..5e96496 100644 --- a/src/scheduler.hpp +++ b/src/scheduler.hpp @@ -3,21 +3,11 @@ #include +#include "process.hpp" + namespace kernel { -class Process -{ -public: - - Process(); - - size_t priority; - - void* stack; - -}; - class ProcessQueue { public: From ac844cdc60f7cede2523fff55507733acd65aaae Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 9 Dec 2020 06:48:55 -0600 Subject: [PATCH 026/109] Started work on kernel class --- src/kernel.hpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/kernel.hpp diff --git a/src/kernel.hpp b/src/kernel.hpp new file mode 100644 index 0000000..f959661 --- /dev/null +++ b/src/kernel.hpp @@ -0,0 +1,68 @@ +#ifndef KERNEL_H +#define KERNEL_H + +#include "systypes.hpp" + +class Kernel +{ +public: + + Kernel(); + + /** + * Maps a region of pages starting at the virtual address 'page', allocating + * each mapped frame and any necessary page tables. + * + * @param page The virtual address of the first page to map + * @param length The size in bytes of the region to map + * @param flags The flags to apply to each page + * + * @returns zero upon success, nonzero on failure + */ + int allocateRegion(void* page, size_t length, int flags); + + /** + * Maps a contiguous region of pages to a configuous region of frames, + * allocating new page tables as needed. All pages will share the same + * flags. + * + * @param page The virtual address of the first page to map + * @param frame The physical address of the first frame to map to + * @param length The size in bytes of the region to map + * @param flags The flags to apply to each page + * + * @returns zero upon success, nonzero on failure + */ + int mapRegion(void* page, physaddr_t frame, size_t length, int flags); + + /** + * Maps a single page to a single frame. Allocates a new page table if one + * does not exist for that frame. + * + * @param page the virtual address of the page to map + * @param frame the physical address of the frame to map to + * @param flags flags to apply to the entry + * + * @returns zero upon success, nonzero on failure + */ + int mapPage(void* page, physaddr_t frame, int flags); + + /** + * Reserve a single page frame. + * + * @returns the physical address of the reserved frame. + */ + physaddr_t reserveFrame(); + + /** + * Frees a single page frame. + */ + void freeFrame(physaddr_t frame); + +private: + + + +}; + +#endif \ No newline at end of file From a099a6dc101f022f02bb3107dd5b5f6fc10c2ea1 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Thu, 10 Dec 2020 01:55:37 -0600 Subject: [PATCH 027/109] Started abstract memory manager class --- src/memorymanager.hpp | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/memorymanager.hpp diff --git a/src/memorymanager.hpp b/src/memorymanager.hpp new file mode 100644 index 0000000..96d9c39 --- /dev/null +++ b/src/memorymanager.hpp @@ -0,0 +1,50 @@ +#ifndef MEMORYMANAGER_H +#define MEMORYMANAGER_H + +#include "systypes.h" + +class MemoryManager +{ +public: + + /** + * Allocates space for a new top-level page table, and initializes it to + * point only to the kernel's page tables. + * + * @returns the physical address of the new top-level page table + */ + virtual physaddr_t createAddressSpace() = 0; + + /** + * Loads the given top-level page table(s). + * + * @param table the top-level page table to load + */ + virtual void loadAddressSpace(physaddr_t table) = 0; + + /** + * Maps a single page to a single frame. Allocates a new page table if one + * does not exist for that frame. + * + * @param page the virtual address of the page to map + * @param frame the physical address of the frame to map to + * @param flags flags to apply to the entry + * + * @returns zero upon success, nonzero on failure + */ + virtual int mapPage(void* page, physaddr_t frame, int flags) = 0; + + /** + * Deletes the page table entry for the specified page. Does not deallocate + * redundant page tables or modify higher level tables; these are cleaned up + * after the owning process ends. + * + * @param page the virtual address of the page to unmap + * + * @returns zero upon success, nonzero on failure + */ + virtual int unmapPage(void* page) = 0; + +}; + +#endif \ No newline at end of file From e5764d91ea24cf317191f055493ec9de0158f75b Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Fri, 11 Dec 2020 09:16:53 -0600 Subject: [PATCH 028/109] Added pageSize() method to memory manager --- src/memorymanager.hpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/memorymanager.hpp b/src/memorymanager.hpp index 96d9c39..f8259ff 100644 --- a/src/memorymanager.hpp +++ b/src/memorymanager.hpp @@ -1,12 +1,19 @@ #ifndef MEMORYMANAGER_H #define MEMORYMANAGER_H -#include "systypes.h" +#include "systypes.hpp" class MemoryManager { public: + /** + * @brief Returns the size of a single page on the present platform. + * + * @return the size in bytes of a single page + */ + virtual unsigned int pageSize() const = 0; + /** * Allocates space for a new top-level page table, and initializes it to * point only to the kernel's page tables. @@ -40,10 +47,8 @@ public: * after the owning process ends. * * @param page the virtual address of the page to unmap - * - * @returns zero upon success, nonzero on failure */ - virtual int unmapPage(void* page) = 0; + virtual physaddr_t unmapPage(void* page) = 0; }; From e8c3de4a636f2cfe65455734db1aa28a0242ffb3 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Fri, 11 Dec 2020 09:17:08 -0600 Subject: [PATCH 029/109] Added doc/ folder to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0a6e77e..f6a9051 100755 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,5 @@ stamp-h1 *~ rootfs/apps -test/ \ No newline at end of file +test/ +doc/ \ No newline at end of file From 69c3c8a84724a00a387360fe89ce10131711bb87 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Fri, 11 Dec 2020 09:19:29 -0600 Subject: [PATCH 030/109] More work on Kernel class, syscalls --- src/allocator.cpp | 10 ++--- src/allocator.hpp | 2 +- src/elf.cpp | 10 ++--- src/elf.hpp | 2 +- src/interrupts.hpp | 2 +- src/kernel.cpp | 31 ++++++++++++++ src/kernel.hpp | 68 +++++++++++++++++++----------- src/kernelstate.cpp | 2 +- src/kernelstate.hpp | 2 +- src/map.hpp | 95 ++++++++++++++++++++++++++++++++++++++++++ src/memoryblock.hpp | 34 +++++++++++++++ src/memorymap.cpp | 2 +- src/memorymap.hpp | 2 +- src/mmap.hpp | 2 +- src/module.cpp | 2 +- src/module.hpp | 2 +- src/pageallocator.cpp | 42 +++++++++---------- src/pageallocator.hpp | 2 +- src/process.hpp | 13 ++++-- src/scheduler.cpp | 12 +++--- src/scheduler.hpp | 2 +- src/syscalls.cpp | 62 +++++++++++++++++++++++++++ src/syscalls.hpp | 23 ++++++++++ src/systeminfo.cpp | 2 +- src/systeminfo.hpp | 2 +- src/util.cpp | 23 +++++----- src/util.hpp | 2 + src/x86/initialize.cpp | 2 +- src/x86/interrupts.cpp | 8 ++-- src/x86/mmap.cpp | 16 +++---- src/x86/multiboot2.cpp | 2 +- src/x86/multiboot2.hpp | 2 +- src/x86/tty.cpp | 26 ++++++------ src/x86/tty.hpp | 2 +- 34 files changed, 390 insertions(+), 121 deletions(-) create mode 100644 src/kernel.cpp create mode 100644 src/map.hpp create mode 100644 src/memoryblock.hpp create mode 100644 src/syscalls.cpp create mode 100644 src/syscalls.hpp diff --git a/src/allocator.cpp b/src/allocator.cpp index 6ecef06..b7c5bbe 100644 --- a/src/allocator.cpp +++ b/src/allocator.cpp @@ -20,12 +20,12 @@ inline size_t ilog2(size_t n) return count - (isPowerOfTwo ? 1 : 0); } -kernel::Allocator::Allocator() +kernelns::Allocator::Allocator() { } -kernel::Allocator::Allocator(void* base, size_t heapSize, size_t blockSize) +kernelns::Allocator::Allocator(void* base, size_t heapSize, size_t blockSize) { this->base = (char*) base; this->heapSize = heapSize; @@ -54,7 +54,7 @@ kernel::Allocator::Allocator(void* base, size_t heapSize, size_t blockSize) } } -void* kernel::Allocator::allocate(size_t size) +void* kernelns::Allocator::allocate(size_t size) { size += blockSize - 1; size -= size % blockSize; @@ -68,7 +68,7 @@ void* kernel::Allocator::allocate(size_t size) return NULL; } -void kernel::Allocator::free(void* location) +void kernelns::Allocator::free(void* location) { size_t offset = (size_t) location - (size_t) base; size_t index = (offset / blockSize) + (1 << treeHeight); @@ -82,7 +82,7 @@ void kernel::Allocator::free(void* location) } } -size_t kernel::Allocator::findFreeBlock(size_t height) +size_t kernelns::Allocator::findFreeBlock(size_t height) { if(height > treeHeight) return 0; diff --git a/src/allocator.hpp b/src/allocator.hpp index bd9dfbf..d910ff8 100644 --- a/src/allocator.hpp +++ b/src/allocator.hpp @@ -3,7 +3,7 @@ #include -namespace kernel +namespace kernelns { class Allocator diff --git a/src/elf.cpp b/src/elf.cpp index e327acf..503da94 100644 --- a/src/elf.cpp +++ b/src/elf.cpp @@ -1,23 +1,23 @@ #include "elf.hpp" #include "util.hpp" -kernel::ELF::ELF() +kernelns::ELF::ELF() { this->m_fileLocation = (void*) NULL; } -kernel::ELF::ELF(void* location) +kernelns::ELF::ELF(void* location) { this->m_fileLocation = location; } -void* kernel::ELF::entry() +void* kernelns::ELF::entry() { Header* fileHeader = (Header*) m_fileLocation; return fileHeader->entry; } -int kernel::ELF::validate() +int kernelns::ELF::validate() { Header* fileHeader = (Header*) m_fileLocation; if(fileHeader->magic != 0x464c457f) @@ -29,7 +29,7 @@ int kernel::ELF::validate() return 0; } -int kernel::ELF::load() +int kernelns::ELF::load() { Header* fileHeader = (Header*) m_fileLocation; ProgramHeader* programHeader = (ProgramHeader*) ((size_t) m_fileLocation + fileHeader->phoffset); diff --git a/src/elf.hpp b/src/elf.hpp index 341296c..be986e6 100644 --- a/src/elf.hpp +++ b/src/elf.hpp @@ -3,7 +3,7 @@ #include "systypes.hpp" -namespace kernel +namespace kernelns { class ELF diff --git a/src/interrupts.hpp b/src/interrupts.hpp index d51d864..f8c99aa 100644 --- a/src/interrupts.hpp +++ b/src/interrupts.hpp @@ -1,7 +1,7 @@ #ifndef INTERRUPTS_H #define INTERRUPTS_H -namespace kernel +namespace kernelns { class Interrupts { diff --git a/src/kernel.cpp b/src/kernel.cpp new file mode 100644 index 0000000..98795ff --- /dev/null +++ b/src/kernel.cpp @@ -0,0 +1,31 @@ +#include "kernel.hpp" + +int Kernel::allocateRegion(void* page, size_t length, int flags) +{ + char* ptr = (char*) page; + for(int i = (int) length; i > 0; i -= mmgr.getPageSize()) + { + physaddr_t frame = pageAllocator.allocate(mmgr.getPageSize()); + if(frame != 0) + mmgr.mapPage(page, reserveFrame(), flags); + else + return -1; + ptr += mmgr.getPageSize(); + } + return 0; +} + +void Kernel::freeRegion(void* page, size_t length) +{ + char* ptr = (char*) page; + for(int i = (int) length; i > 0; i -= mmgr.getPageSize()) + { + pageAllocator.free(mmgr.unmapPage((void*) ptr), mmgr.getPageSize()); + ptr += mmgr.getPageSize(); + } +} + +int Kernel::mapRegion(void* page, physaddr_t frame, size_t length, int flags) +{ + +} \ No newline at end of file diff --git a/src/kernel.hpp b/src/kernel.hpp index f959661..107d9bf 100644 --- a/src/kernel.hpp +++ b/src/kernel.hpp @@ -1,17 +1,24 @@ #ifndef KERNEL_H #define KERNEL_H +#include "pageallocator.hpp" +#include "memorymanager.hpp" +#include "memoryblock.hpp" +#include "process.hpp" #include "systypes.hpp" +using namespace kernelns; + class Kernel { public: - Kernel(); - /** - * Maps a region of pages starting at the virtual address 'page', allocating - * each mapped frame and any necessary page tables. + * @brief Maps a region of pages starting at virtual address 'page' with + * length 'length'. Allocates each mapped frame and any necessary page + * tables. This method does not perform any checks before overwriting page + * tables; it is the responsibility of the caller to ensure that the + * operation is safe to perform. * * @param page The virtual address of the first page to map * @param length The size in bytes of the region to map @@ -22,9 +29,21 @@ public: int allocateRegion(void* page, size_t length, int flags); /** - * Maps a contiguous region of pages to a configuous region of frames, - * allocating new page tables as needed. All pages will share the same - * flags. + * @brief Unmaps and frees a region of mapped pages starting at virtual + * address 'page' with length 'length'. Does not free any page tables + * that are made redundant by this operation. It is the responsibility + * of the caller to ensure that all pages in the specified region are + * mapped and should be returned to the page allocator. + * + * @param page The virtual address of the first page to free + * @param length The size in bytes of the region to free + */ + void freeRegion(void* page, size_t length); + + /** + * @brief Maps a contiguous region of pages to a contiguous region of + * frames. Allocates new page tables as needed. All pages will share + * the same flags. * * @param page The virtual address of the first page to map * @param frame The physical address of the first frame to map to @@ -36,33 +55,32 @@ public: int mapRegion(void* page, physaddr_t frame, size_t length, int flags); /** - * Maps a single page to a single frame. Allocates a new page table if one - * does not exist for that frame. + * @brief Unmaps a region of pages; does not return them to the page + * allocator. * - * @param page the virtual address of the page to map - * @param frame the physical address of the frame to map to - * @param flags flags to apply to the entry - * - * @returns zero upon success, nonzero on failure + * @param page The virtual address of the first page to unmap + * @param length The size in bytes of the region to unmap */ - int mapPage(void* page, physaddr_t frame, int flags); + void unmapRegion(void* page, size_t length); - /** - * Reserve a single page frame. - * - * @returns the physical address of the reserved frame. - */ - physaddr_t reserveFrame(); + unsigned int createSharedBlock(size_t length, int flags); - /** - * Frees a single page frame. - */ - void freeFrame(physaddr_t frame); + void deleteSharedBlock(unsigned int id); + + const MemoryBlock& getSharedBlock(unsigned int id); + + const Process& getActiveProcess(); + + const Process& switchProcess(); private: + PageAllocator& pageAllocator; + MemoryManager& mmgr; }; +extern Kernel kernel; + #endif \ No newline at end of file diff --git a/src/kernelstate.cpp b/src/kernelstate.cpp index 561ba16..89e3301 100644 --- a/src/kernelstate.cpp +++ b/src/kernelstate.cpp @@ -1,6 +1,6 @@ #include "kernelstate.hpp" -using namespace kernel; +using namespace kernelns; BuddyAllocator State::pageAllocator; Allocator State::allocator; diff --git a/src/kernelstate.hpp b/src/kernelstate.hpp index 77a3cb8..ecb8b63 100644 --- a/src/kernelstate.hpp +++ b/src/kernelstate.hpp @@ -7,7 +7,7 @@ #include "scheduler.hpp" #include "systeminfo.hpp" -namespace kernel +namespace kernelns { class State diff --git a/src/map.hpp b/src/map.hpp new file mode 100644 index 0000000..e33ea38 --- /dev/null +++ b/src/map.hpp @@ -0,0 +1,95 @@ +#ifndef MAP_H +#define MAP_H + +template +class Map +{ +public: + + Map(); + + bool contains(const Key& key) const + { + if(m_tree == nullptr) + return false; + else if(m_tree->search(key) == nullptr) + return false; + return true; + } + + Value& get(const Key& key) + { + if(m_tree = nullptr) + return (Value&) *nullptr; + Node* node = m_tree->search(key); + if(node == nullptr) + return (Value&) *nullptr; + else + return node->m_value; + } + + void insert(const Value& value); + + void remove(const Key& key); + + unsigned int size() const; + +private: + + class Node + { + public: + + enum class Color + { + Black, + Red + } + + Key m_key; + + Value& m_value; + + Node *left, *right, *parent; + + Color color; + + Node(); + + Node* uncle() + { + if(parent != nullptr && parent->parent != nullptr) + { + if(parent == parent->parent->left) + return parent->parent->right; + return parent->parent->left; + } + return nullptr; + } + + Node* search(const Key& key) + { + if(key == m_key) + return this; + if(left != nullptr) + { + Node* lsearch = left->search(key); + if(lsearch != nullptr) + return lsearch; + } + if(right != nullptr) + { + Node* rsearch = right->search(key); + if(rsearch != nullptr) + return rsearch; + } + return nullptr; + } + + }; + + Node *m_tree; + +}; + +#endif \ No newline at end of file diff --git a/src/memoryblock.hpp b/src/memoryblock.hpp new file mode 100644 index 0000000..2df0625 --- /dev/null +++ b/src/memoryblock.hpp @@ -0,0 +1,34 @@ +#ifndef MEMORYBLOCK_H +#define MEMORYBLOCK_H + +#include "systypes.hpp" + +class MemoryBlock +{ +public: + + physaddr_t getLocation() const; + + physaddr_t getEnd() const; + + size_t getSize() const; + + int getAttributes() const; + + unsigned int getOwners() const; + + void decrementOwners(); + +private: + + physaddr_t m_location; + + size_t m_size; + + int m_attributes; + + unsigned int m_owners; + +}; + +#endif \ No newline at end of file diff --git a/src/memorymap.cpp b/src/memorymap.cpp index 43959df..d5e58e6 100644 --- a/src/memorymap.cpp +++ b/src/memorymap.cpp @@ -1,6 +1,6 @@ #include "memorymap.hpp" -using namespace kernel; +using namespace kernelns; MemoryMap::Region::Region() { diff --git a/src/memorymap.hpp b/src/memorymap.hpp index ddc2b7a..58aa1d0 100644 --- a/src/memorymap.hpp +++ b/src/memorymap.hpp @@ -3,7 +3,7 @@ #include "systypes.hpp" -namespace kernel +namespace kernelns { class MemoryMap diff --git a/src/mmap.hpp b/src/mmap.hpp index 83f243e..0e91955 100644 --- a/src/mmap.hpp +++ b/src/mmap.hpp @@ -7,7 +7,7 @@ #define MMAP_EXEC 0x02 #define MMAP_SHARED 0x04 -namespace kernel +namespace kernelns { int mmap(void* start, size_t length, int flags); diff --git a/src/module.cpp b/src/module.cpp index 7aae391..08ae855 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -1,7 +1,7 @@ #include "module.hpp" #include "util.hpp" -using namespace kernel; +using namespace kernelns; Module::Module() { diff --git a/src/module.hpp b/src/module.hpp index 2c4b586..2d3b024 100644 --- a/src/module.hpp +++ b/src/module.hpp @@ -5,7 +5,7 @@ #include "systypes.hpp" -namespace kernel +namespace kernelns { class Module diff --git a/src/pageallocator.cpp b/src/pageallocator.cpp index d31617c..08b6892 100755 --- a/src/pageallocator.cpp +++ b/src/pageallocator.cpp @@ -21,12 +21,12 @@ uint32_t ilog2(uint32_t n, bool roundUp) return count - (isPowerOfTwo ? 1 : (roundUp ? 0 : 1)); } -kernel::BuddyAllocator::BuddyAllocator() +kernelns::BuddyAllocator::BuddyAllocator() { } -kernel::BuddyAllocator::BuddyAllocator(const kernel::MemoryMap& memmap, +kernelns::BuddyAllocator::BuddyAllocator(const kernelns::MemoryMap& memmap, char* bitmap, size_t blockCount, size_t treeHeight) { @@ -44,7 +44,7 @@ kernel::BuddyAllocator::BuddyAllocator(const kernel::MemoryMap& memmap, physaddr_t location = 0x100000; for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++) { - if(memmap[i].getType() != kernel::MemoryMap::AVAILABLE) + if(memmap[i].getType() != kernelns::MemoryMap::AVAILABLE) continue; if(memmap[i].getLocation() > location) location = roundUp(memmap[i].getLocation(), 4096); @@ -58,7 +58,7 @@ kernel::BuddyAllocator::BuddyAllocator(const kernel::MemoryMap& memmap, } } -kernel::BuddyAllocator::BuddyAllocator(char* bitmap, size_t blockSize, +kernelns::BuddyAllocator::BuddyAllocator(char* bitmap, size_t blockSize, size_t blockCount, size_t treeHeight) { this->bitmap = bitmap; @@ -77,7 +77,7 @@ kernel::BuddyAllocator::BuddyAllocator(char* bitmap, size_t blockSize, } } -physaddr_t kernel::BuddyAllocator::allocate(size_t size) +physaddr_t kernelns::BuddyAllocator::allocate(size_t size) { size_t height = ilog2(roundUp(size, blockSize) / blockSize, true); if(height > treeHeight) // Requested block size is greater than maximum @@ -99,7 +99,7 @@ physaddr_t kernel::BuddyAllocator::allocate(size_t size) } } -void kernel::BuddyAllocator::free(physaddr_t location, size_t size) +void kernelns::BuddyAllocator::free(physaddr_t location, size_t size) { size_t height = ilog2(roundUp(size, blockSize) / blockSize, true); if(height <= treeHeight) @@ -113,7 +113,7 @@ void kernel::BuddyAllocator::free(physaddr_t location, size_t size) } } -size_t kernel::BuddyAllocator::freeBlocks() const +size_t kernelns::BuddyAllocator::freeBlocks() const { size_t count = 0; for(size_t j = 0; j < blockCount; j++) @@ -126,7 +126,7 @@ size_t kernel::BuddyAllocator::freeBlocks() const return count; } -size_t kernel::BuddyAllocator::maxAllocationSize() const +size_t kernelns::BuddyAllocator::maxAllocationSize() const { for(size_t i = treeHeight; i >= 0; i--) { @@ -141,17 +141,17 @@ size_t kernel::BuddyAllocator::maxAllocationSize() const return 0; } -size_t kernel::BuddyAllocator::getBlockSize() const +size_t kernelns::BuddyAllocator::getBlockSize() const { return blockSize; } -size_t kernel::BuddyAllocator::getMemorySize() const +size_t kernelns::BuddyAllocator::getMemorySize() const { return blockCount; } -size_t kernel::BuddyAllocator::findFreeBlock(size_t height) +size_t kernelns::BuddyAllocator::findFreeBlock(size_t height) { for(size_t i = 0; i < (blockCount >> height); i++) { @@ -171,7 +171,7 @@ size_t kernel::BuddyAllocator::findFreeBlock(size_t height) return INVALID; } -size_t kernel::BuddyAllocator::split(size_t height, size_t index) +size_t kernelns::BuddyAllocator::split(size_t height, size_t index) { if(height > 0 && isFree(height, index)) { @@ -186,7 +186,7 @@ size_t kernel::BuddyAllocator::split(size_t height, size_t index) } } -size_t kernel::BuddyAllocator::merge(size_t height, size_t index) +size_t kernelns::BuddyAllocator::merge(size_t height, size_t index) { if(isFree(height, index) && isFree(height, getBuddy(index)) && height < treeHeight) { @@ -209,34 +209,34 @@ size_t kernel::BuddyAllocator::merge(size_t height, size_t index) } } -size_t kernel::BuddyAllocator::getBuddy(size_t index) +size_t kernelns::BuddyAllocator::getBuddy(size_t index) { return index ^ 1; } -size_t kernel::BuddyAllocator::getParent(size_t index) +size_t kernelns::BuddyAllocator::getParent(size_t index) { return index / 2; } -size_t kernel::BuddyAllocator::getChild(size_t index) +size_t kernelns::BuddyAllocator::getChild(size_t index) { return index * 2; } -physaddr_t kernel::BuddyAllocator::nodeToAddress(size_t height, size_t index) +physaddr_t kernelns::BuddyAllocator::nodeToAddress(size_t height, size_t index) const { return index * (blockSize << height); } -size_t kernel::BuddyAllocator::addressToNode(size_t height, +size_t kernelns::BuddyAllocator::addressToNode(size_t height, physaddr_t location) const { return location / (blockSize << height); } -void kernel::BuddyAllocator::reserveNode(size_t height, size_t index) +void kernelns::BuddyAllocator::reserveNode(size_t height, size_t index) { size_t bit = (height == 0) ? 0 : ((blockCount * 2) - (blockCount >> (height - 1))); @@ -244,7 +244,7 @@ void kernel::BuddyAllocator::reserveNode(size_t height, size_t index) bitmap[bit / 8] |= 1 << (bit % 8); } -void kernel::BuddyAllocator::freeNode(size_t height, size_t index) +void kernelns::BuddyAllocator::freeNode(size_t height, size_t index) { size_t bit = (height == 0) ? 0 : ((blockCount * 2) - (blockCount >> (height - 1))); @@ -252,7 +252,7 @@ void kernel::BuddyAllocator::freeNode(size_t height, size_t index) bitmap[bit / 8] &= ~(1 << (bit % 8)); } -bool kernel::BuddyAllocator::isFree(size_t height, size_t index) const +bool kernelns::BuddyAllocator::isFree(size_t height, size_t index) const { size_t bit = (height == 0) ? 0 : ((blockCount * 2) - (blockCount >> (height - 1))); diff --git a/src/pageallocator.hpp b/src/pageallocator.hpp index 27e2acd..15b1ce5 100755 --- a/src/pageallocator.hpp +++ b/src/pageallocator.hpp @@ -5,7 +5,7 @@ #include "systypes.hpp" #include "memorymap.hpp" -namespace kernel +namespace kernelns { /** diff --git a/src/process.hpp b/src/process.hpp index 73e7a1c..ce363c7 100644 --- a/src/process.hpp +++ b/src/process.hpp @@ -2,20 +2,27 @@ #define PROCESS_H #include +#include "map.hpp" -namespace kernel +namespace kernelns { class Process { public: - Process(); - size_t priority; void* stack; + Process(); + + bool hasSharedBlock(unsigned int blockID) const; + +private: + + Map m_sharedBlocks; + }; } diff --git a/src/scheduler.cpp b/src/scheduler.cpp index c1c00c7..57089a1 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -1,17 +1,17 @@ #include "scheduler.hpp" -kernel::ProcessQueue::ProcessQueue() +kernelns::ProcessQueue::ProcessQueue() { } -kernel::ProcessQueue::ProcessQueue(Process** array) +kernelns::ProcessQueue::ProcessQueue(Process** array) { m_array = array; m_size = 0; } -kernel::Process* kernel::ProcessQueue::extractMin() +kernelns::Process* kernelns::ProcessQueue::extractMin() { if(m_size == 0) return NULL; @@ -22,7 +22,7 @@ kernel::Process* kernel::ProcessQueue::extractMin() return p; } -void kernel::ProcessQueue::insert(Process* n) +void kernelns::ProcessQueue::insert(Process* n) { size_t i = m_size; m_size++; @@ -33,7 +33,7 @@ void kernel::ProcessQueue::insert(Process* n) m_array[i] = n; } -void kernel::ProcessQueue::remove(Process* n) +void kernelns::ProcessQueue::remove(Process* n) { for(size_t i = 0; i < m_size; i++) { @@ -47,7 +47,7 @@ void kernel::ProcessQueue::remove(Process* n) } } -void kernel::ProcessQueue::heapify(size_t i) +void kernelns::ProcessQueue::heapify(size_t i) { if(i * 2 + 1 >= m_size) return; diff --git a/src/scheduler.hpp b/src/scheduler.hpp index 5e96496..c58ee32 100644 --- a/src/scheduler.hpp +++ b/src/scheduler.hpp @@ -5,7 +5,7 @@ #include "process.hpp" -namespace kernel +namespace kernelns { class ProcessQueue diff --git a/src/syscalls.cpp b/src/syscalls.cpp new file mode 100644 index 0000000..8255d15 --- /dev/null +++ b/src/syscalls.cpp @@ -0,0 +1,62 @@ +#include "syscalls.hpp" +#include "kernel.hpp" + +int mmap(void* location, size_t length, int flags) +{ + // TODO: check that the requested region does not overlap something important + return kernel.allocateRegion(location, length, flags); +} + +int munmap(void* location, size_t length) +{ + // TODO: check that the requested region does not overlap something important + kernel.freeRegion(location, length); + return 0; +} + +unsigned int createSharedBlock(void* location, size_t length, int flags) +{ + unsigned int blockID = kernel.createSharedBlock(length, flags); + if(blockID > 0) + { + const MemoryBlock& block = kernel.getSharedBlock(blockID); + kernel.mapRegion(location, block.getLocation(), length, flags); + // TODO: add block to current process + // TODO: perform safety checks + } + return blockID; +} + +int aquireSharedBlock(void* location, unsigned int id) +{ + const MemoryBlock& block = kernel.getSharedBlock(id); + kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getAttributes()); + // TODO: (somehow) handle invalid ids -- possibly hard while using references + // TODO: add block to current process + // TODO: perform safety checks + return 0; +} + +int releaseSharedBlock(int id) +{ + // (0) Check that process actually posesses block + // (1) Get virtual address of block + // (2) Unmap block + // (3) Delete block if no one posesses it anymore + return 0; +} + +int querySharedBlock(void* info, int id) +{ + // TODO: define struct for block info +} + +int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t length) +{ + return 0; +} + +int releasePhysicalBlock(int id) +{ + return 0; +} \ No newline at end of file diff --git a/src/syscalls.hpp b/src/syscalls.hpp new file mode 100644 index 0000000..3971369 --- /dev/null +++ b/src/syscalls.hpp @@ -0,0 +1,23 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include +#include "systypes.hpp" + +int mmap(void* location, size_t length, int flags); + +int munmap(void* location, size_t length); + +unsigned int createSharedBlock(void* location, size_t length, int flags); + +int aquireSharedBlock(void* location, unsigned int id); + +int releaseSharedBlock(int id); + +int querySharedBlock(void* info, int id); + +int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t length); + +int releasePhysicalBlock(int id); + +#endif \ No newline at end of file diff --git a/src/systeminfo.cpp b/src/systeminfo.cpp index 1151de1..a7ceb84 100644 --- a/src/systeminfo.cpp +++ b/src/systeminfo.cpp @@ -1,7 +1,7 @@ #include "systeminfo.hpp" #include "util.hpp" -using namespace kernel; +using namespace kernelns; SystemInfo::SystemInfo() { diff --git a/src/systeminfo.hpp b/src/systeminfo.hpp index 81727cd..caff548 100644 --- a/src/systeminfo.hpp +++ b/src/systeminfo.hpp @@ -6,7 +6,7 @@ #include "systypes.hpp" #include "memorymap.hpp" -namespace kernel +namespace kernelns { class SystemInfo diff --git a/src/util.cpp b/src/util.cpp index 284251b..89c2958 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -17,17 +17,6 @@ void* memcpy(void* destination, const void* source, size_t num) return destination; } -/* - * There are four distinct cases here: - * 1. destination and source blocks do not overlap - * 2. destination and source are the same - * 3. destination and source do overlap; destination starts before source - * 4. destination and source do overlap; destination starts after source - * - * Memcpy results in expected behavior in all cases except for case 4. In that - * case, copying must be done backwards to avoid reading from bytes that have - * already been overwritten. - */ void* memmove(void* destination, const void* source, size_t num) { if(num > 0) @@ -123,7 +112,7 @@ char* strcpy(char* destination, const char* source) void* malloc(size_t size) { - return kernel::State::allocator.allocate(size); + return kernelns::State::allocator.allocate(size); } void* calloc(size_t count, size_t size) @@ -131,9 +120,17 @@ void* calloc(size_t count, size_t size) return memset(malloc(count * size), 0, count * size); } +void* realloc(void* ptr, size_t size) +{ + void* n = kernelns::State::allocator.allocate(size); + memmove(n, ptr, size); + free(ptr); + return n; +} + void free(void* p) { - kernel::State::allocator.free(p); + kernelns::State::allocator.free(p); } void __cxa_pure_virtual() diff --git a/src/util.hpp b/src/util.hpp index 608f8e0..d82bcf5 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -19,6 +19,8 @@ extern "C" void* malloc(size_t size); extern "C" void* calloc(size_t count, size_t size); +extern "C" void* realloc(void* ptr, size_t size); + extern "C" void free(void* p); extern "C" void __cxa_pure_virtual(); diff --git a/src/x86/initialize.cpp b/src/x86/initialize.cpp index 17dcdf0..57255fb 100644 --- a/src/x86/initialize.cpp +++ b/src/x86/initialize.cpp @@ -6,7 +6,7 @@ #include "../mmap.hpp" #include "../util.hpp" -using namespace kernel; +using namespace kernelns; extern int _kernelEnd; diff --git a/src/x86/interrupts.cpp b/src/x86/interrupts.cpp index 7845ef5..6eda16d 100644 --- a/src/x86/interrupts.cpp +++ b/src/x86/interrupts.cpp @@ -140,7 +140,7 @@ void syscallHandler(void* frame) } -kernel::Interrupts::Interrupts() +kernelns::Interrupts::Interrupts() { for(unsigned int i = 0; i <= MAX_SYSCALL_ID; i++) syscalls[i] = (void*) NULL; @@ -152,17 +152,17 @@ kernel::Interrupts::Interrupts() lidt(); } -void kernel::Interrupts::enable() +void kernelns::Interrupts::enable() { asm("sti"); } -void kernel::Interrupts::disable() +void kernelns::Interrupts::disable() { asm("cli"); } -void kernel::Interrupts::addSyscall(unsigned int id, void* function) +void kernelns::Interrupts::addSyscall(unsigned int id, void* function) { if(id <= MAX_SYSCALL_ID) syscalls[id] = function; diff --git a/src/x86/mmap.cpp b/src/x86/mmap.cpp index ea0e14f..3cddf3b 100644 --- a/src/x86/mmap.cpp +++ b/src/x86/mmap.cpp @@ -150,7 +150,7 @@ private: uint32_t physicalAddress : 20; }; -int kernel::mmap(void* start, size_t length, int flags) +int kernelns::mmap(void* start, size_t length, int flags) { if((size_t) start % 4096 != 0) return -1; @@ -184,7 +184,7 @@ int kernel::mmap(void* start, size_t length, int flags) return 0; } -int kernel::mmap(void* start, physaddr_t p_start, size_t length, int flags) +int kernelns::mmap(void* start, physaddr_t p_start, size_t length, int flags) { if((size_t) start % 4096 != 0 || p_start % 4096 != 0) return -1; @@ -198,7 +198,7 @@ int kernel::mmap(void* start, physaddr_t p_start, size_t length, int flags) return 0; } -int kernel::mapPage(void* start, physaddr_t p_start, int flags) +int kernelns::mapPage(void* start, physaddr_t p_start, int flags) { if((size_t) start % 4096 != 0 || p_start % 4096 != 0) return -1; @@ -228,7 +228,7 @@ int kernel::mapPage(void* start, physaddr_t p_start, int flags) return 0; } -int kernel::munmap(void* start, size_t length) +int kernelns::munmap(void* start, size_t length) { if((size_t) start % 4096 != 0) return -1; @@ -250,7 +250,7 @@ int kernel::munmap(void* start, size_t length) return 0; } -bool kernel::isMapped(void* addr) +bool kernelns::isMapped(void* addr) { PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; size_t tableIndex = (size_t) addr / 4096; @@ -263,14 +263,14 @@ bool kernel::isMapped(void* addr) return false; } -physaddr_t kernel::getPhysicalAddress(void* addr) +physaddr_t kernelns::getPhysicalAddress(void* addr) { PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; size_t tableIndex = (size_t) addr / 4096; return pageTables[tableIndex].getPhysicalAddress() + ((size_t) addr & 0xFFF); } -int kernel::createAddressSpace(void* table) +int kernelns::createAddressSpace(void* table) { if(((size_t) table & 0xFFF) != 0) return -1; @@ -281,7 +281,7 @@ int kernel::createAddressSpace(void* table) return 0; } -int kernel::loadAddressSpace(physaddr_t table) +int kernelns::loadAddressSpace(physaddr_t table) { if((table & 0xFFF) != 0) return -1; diff --git a/src/x86/multiboot2.cpp b/src/x86/multiboot2.cpp index a191382..b1569f4 100644 --- a/src/x86/multiboot2.cpp +++ b/src/x86/multiboot2.cpp @@ -1,6 +1,6 @@ #include "multiboot2.hpp" -using namespace kernel; +using namespace kernelns; Multiboot2Info::Multiboot2Info(void* tableLocation) { diff --git a/src/x86/multiboot2.hpp b/src/x86/multiboot2.hpp index 9f9e944..6fcaf37 100644 --- a/src/x86/multiboot2.hpp +++ b/src/x86/multiboot2.hpp @@ -4,7 +4,7 @@ #include "../memorymap.hpp" #include "../module.hpp" -namespace kernel +namespace kernelns { class Multiboot2Info diff --git a/src/x86/tty.cpp b/src/x86/tty.cpp index b3132c5..8ee9929 100644 --- a/src/x86/tty.cpp +++ b/src/x86/tty.cpp @@ -1,7 +1,7 @@ #include #include "tty.hpp" -kernel::TTY::TTY(char* vga) +kernelns::TTY::TTY(char* vga) { this->vga = vga; this->cursor = 0; @@ -9,7 +9,7 @@ kernel::TTY::TTY(char* vga) this->base = 10; } -kernel::TTY& kernel::TTY::operator<<(kernel::TTY::Format fmt) +kernelns::TTY& kernelns::TTY::operator<<(kernelns::TTY::Format fmt) { switch(fmt) { @@ -25,42 +25,42 @@ kernel::TTY& kernel::TTY::operator<<(kernel::TTY::Format fmt) } } -kernel::TTY& kernel::TTY::operator<<(const char* str) +kernelns::TTY& kernelns::TTY::operator<<(const char* str) { return printString(str); } -kernel::TTY& kernel::TTY::operator<<(unsigned int n) +kernelns::TTY& kernelns::TTY::operator<<(unsigned int n) { return printNumber(n, base, width); } -kernel::TTY& kernel::TTY::operator<<(int n) +kernelns::TTY& kernelns::TTY::operator<<(int n) { return printNumber((unsigned int) n, base, width); } -kernel::TTY& kernel::TTY::operator<<(void* n) +kernelns::TTY& kernelns::TTY::operator<<(void* n) { return printNumber((unsigned int) n, 16, 8); } -kernel::TTY& kernel::TTY::operator<<(char c) +kernelns::TTY& kernelns::TTY::operator<<(char c) { return putChar(c); } -void kernel::TTY::setWidth(size_t width) +void kernelns::TTY::setWidth(size_t width) { this->width = width; } -size_t kernel::TTY::getWidth() +size_t kernelns::TTY::getWidth() { return width; } -void kernel::TTY::clear() +void kernelns::TTY::clear() { for(int i = 0; i < 80*25; i++) { @@ -69,7 +69,7 @@ void kernel::TTY::clear() cursor = 0; } -kernel::TTY& kernel::TTY::printNumber(unsigned int n, size_t base, +kernelns::TTY& kernelns::TTY::printNumber(unsigned int n, size_t base, size_t width) { const char* digits = "0123456789ABCDEF"; @@ -94,7 +94,7 @@ kernel::TTY& kernel::TTY::printNumber(unsigned int n, size_t base, return *this; } -kernel::TTY& kernel::TTY::printString(const char* str) +kernelns::TTY& kernelns::TTY::printString(const char* str) { while(*str) { @@ -104,7 +104,7 @@ kernel::TTY& kernel::TTY::printString(const char* str) return *this; } -kernel::TTY& kernel::TTY::putChar(char c) +kernelns::TTY& kernelns::TTY::putChar(char c) { switch(c) { diff --git a/src/x86/tty.hpp b/src/x86/tty.hpp index 47b5191..72bacf7 100644 --- a/src/x86/tty.hpp +++ b/src/x86/tty.hpp @@ -3,7 +3,7 @@ #include -namespace kernel +namespace kernelns { class TTY From 39945f33d748f722803c671b2fec4fc52ed299b8 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Fri, 11 Dec 2020 09:20:16 -0600 Subject: [PATCH 031/109] Added .vscode to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f6a9051..0db5efa 100755 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ quark-kernel autom4te.cache/ .deps .dirstamp +.vscode aclocal.m4 ar-lib compile From 512f81f515e43c7b2a88381dc16af5816d724f37 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Fri, 11 Dec 2020 10:35:09 -0600 Subject: [PATCH 032/109] Added new method declarations to kernel class --- src/kernel.hpp | 53 +++++++++++++++++++++++++++++++++++++++++++++---- src/process.hpp | 4 ++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/kernel.hpp b/src/kernel.hpp index 107d9bf..a8b5ef7 100644 --- a/src/kernel.hpp +++ b/src/kernel.hpp @@ -3,6 +3,7 @@ #include "pageallocator.hpp" #include "memorymanager.hpp" +#include "memorymap.hpp" #include "memoryblock.hpp" #include "process.hpp" #include "systypes.hpp" @@ -65,13 +66,55 @@ public: unsigned int createSharedBlock(size_t length, int flags); - void deleteSharedBlock(unsigned int id); - const MemoryBlock& getSharedBlock(unsigned int id); - const Process& getActiveProcess(); + /** + * @brief Get the process object corresponsing to 'pid' + * + * @param pid id of the process to fetch + * @returns a reference to the requested process + */ + Process& getProcess(unsigned int pid); - const Process& switchProcess(); + /** + * @brief Get the current active process object. + * + * @returns a reference to the active process + */ + Process& getActiveProcess(); + + /** + * @brief Puts the current active process back on the run queue, and sets + * the active process to the next one selected by the scheduler. + * + * @returns a reference to the new active process + */ + Process& yieldActiveProcess(); + + /** + * @brief Puts the current active process to sleep, and sets the active + * process to the next one selected by the scheduler. + * + * @returns a reference to the new active process + */ + Process& sleepActiveProcess(); + + /** + * @brief Terminates the current active process, freeing all its resources, + * and activates the next process selected by the scheduler. + * + * @return Process& + */ + Process& terminateActiveProcess(); + + /** + * @brief Terminates the process with id 'pid', freeing all its resources. + * If it holds any shared blocks which are not held by any other process, + * those blocks will be freed. + * + * @param pid pid of the process to terminate + */ + void terminateProcess(unsigned int pid); private: @@ -79,6 +122,8 @@ private: MemoryManager& mmgr; + MemoryMap& memoryMap; + }; extern Kernel kernel; diff --git a/src/process.hpp b/src/process.hpp index ce363c7..e84ef97 100644 --- a/src/process.hpp +++ b/src/process.hpp @@ -19,10 +19,14 @@ public: bool hasSharedBlock(unsigned int blockID) const; + bool hasPhysicalBlock(unsigned int blockID) const; + private: Map m_sharedBlocks; + Map m_physicalBlocks; + }; } From f4395ab6b5074b3d5cb464827bcc7b11e9a1a9b8 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Fri, 18 Dec 2020 14:12:00 -0600 Subject: [PATCH 033/109] More unfinished work on kernel API --- src/Makefile.am | 3 +- src/kernel.hpp | 31 +++- src/kernelstate.cpp | 9 - src/kernelstate.hpp | 33 ---- src/map.hpp | 95 ---------- src/memoryblock.hpp | 34 ---- src/memorymanager.hpp | 2 +- src/memorymap.cpp | 325 +++++++++++++++-------------------- src/memorymap.hpp | 183 ++++++++++++-------- src/memoryregion.cpp | 128 ++++++++++++++ src/memoryregion.hpp | 87 ++++++++++ src/memorytype.hpp | 11 ++ src/message.cpp | 38 ++++ src/message.hpp | 59 +++++++ src/mmgr.hpp | 7 - src/pageallocator.cpp | 3 +- src/process.hpp | 30 +++- src/sharedblock.hpp | 18 ++ src/syscalls.cpp | 45 ++++- src/syscalls.hpp | 5 + src/systeminfo.cpp | 25 --- src/systeminfo.hpp | 34 ---- src/util.cpp | 20 ++- src/x86/initialize.cpp | 24 +-- src/x86/memorymanagerx86.cpp | 31 ++++ src/x86/memorymanagerx86.hpp | 29 ++++ src/x86/multiboot2.cpp | 17 +- src/x86/multiboot2.hpp | 51 +++--- src/x86/pagetableentry.cpp | 132 ++++++++++++++ src/x86/pagetableentry.hpp | 83 +++++++++ 30 files changed, 1024 insertions(+), 568 deletions(-) delete mode 100644 src/kernelstate.cpp delete mode 100644 src/kernelstate.hpp delete mode 100644 src/map.hpp delete mode 100644 src/memoryblock.hpp create mode 100644 src/memoryregion.cpp create mode 100644 src/memoryregion.hpp create mode 100644 src/memorytype.hpp create mode 100644 src/message.cpp create mode 100644 src/message.hpp delete mode 100644 src/mmgr.hpp create mode 100644 src/sharedblock.hpp delete mode 100644 src/systeminfo.cpp delete mode 100644 src/systeminfo.hpp create mode 100644 src/x86/memorymanagerx86.cpp create mode 100644 src/x86/memorymanagerx86.hpp create mode 100644 src/x86/pagetableentry.cpp create mode 100644 src/x86/pagetableentry.hpp diff --git a/src/Makefile.am b/src/Makefile.am index aad19a1..b4709fc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = kernelstate.cpp module.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp +quark_kernel_SOURCES = module.cpp util.cpp memorymap.cpp memoryregion.cpp pageallocator.cpp allocator.cpp scheduler.cpp quark_kernel_LDADD = -lgcc quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -nostdlib @@ -14,3 +14,4 @@ quark_kernel_SOURCES += x86/mmap.cpp \ quark_kernel_LDFLAGS += -T x86/linker.ld quark_kernel_DEPENDENCIES = x86/linker.ld endif + diff --git a/src/kernel.hpp b/src/kernel.hpp index a8b5ef7..700989a 100644 --- a/src/kernel.hpp +++ b/src/kernel.hpp @@ -4,7 +4,7 @@ #include "pageallocator.hpp" #include "memorymanager.hpp" #include "memorymap.hpp" -#include "memoryblock.hpp" +#include "sharedblock.hpp" #include "process.hpp" #include "systypes.hpp" @@ -14,6 +14,10 @@ class Kernel { public: + void* malloc(size_t size); + + void free(void* ptr); + /** * @brief Maps a region of pages starting at virtual address 'page' with * length 'length'. Allocates each mapped frame and any necessary page @@ -64,9 +68,30 @@ public: */ void unmapRegion(void* page, size_t length); + /** + * @brief Create a Shared Block object + * + * @param length + * @param flags + * @returns The ID of the + */ unsigned int createSharedBlock(size_t length, int flags); - const MemoryBlock& getSharedBlock(unsigned int id); + /** + * @brief Get the shared memory block referred to by 'id' + * + * @param id + * @returns a reference + */ + const SharedBlock& getSharedBlock(unsigned int id); + + /** + * @brief Create a new process + * + * @param imageBlockID + * @return Process& + */ + Process& createProcess(unsigned int imageBlockID); /** * @brief Get the process object corresponsing to 'pid' @@ -112,7 +137,7 @@ public: * If it holds any shared blocks which are not held by any other process, * those blocks will be freed. * - * @param pid pid of the process to terminate + * @param pid id of the process to terminate */ void terminateProcess(unsigned int pid); diff --git a/src/kernelstate.cpp b/src/kernelstate.cpp deleted file mode 100644 index 89e3301..0000000 --- a/src/kernelstate.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "kernelstate.hpp" - -using namespace kernelns; - -BuddyAllocator State::pageAllocator; -Allocator State::allocator; -Interrupts State::interrupts; -ProcessQueue State::processQueue; -SystemInfo State::config; \ No newline at end of file diff --git a/src/kernelstate.hpp b/src/kernelstate.hpp deleted file mode 100644 index ecb8b63..0000000 --- a/src/kernelstate.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef KERNELSTATE_H -#define KERNELSTATE_H - -#include "pageallocator.hpp" -#include "allocator.hpp" -#include "interrupts.hpp" -#include "scheduler.hpp" -#include "systeminfo.hpp" - -namespace kernelns -{ - -class State -{ -public: - - static const unsigned int MAX_PROCESSES = 2048; - - static BuddyAllocator pageAllocator; - - static Allocator allocator; - - static Interrupts interrupts; - - static ProcessQueue processQueue; - - static SystemInfo config; - -}; - -} - -#endif \ No newline at end of file diff --git a/src/map.hpp b/src/map.hpp deleted file mode 100644 index e33ea38..0000000 --- a/src/map.hpp +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef MAP_H -#define MAP_H - -template -class Map -{ -public: - - Map(); - - bool contains(const Key& key) const - { - if(m_tree == nullptr) - return false; - else if(m_tree->search(key) == nullptr) - return false; - return true; - } - - Value& get(const Key& key) - { - if(m_tree = nullptr) - return (Value&) *nullptr; - Node* node = m_tree->search(key); - if(node == nullptr) - return (Value&) *nullptr; - else - return node->m_value; - } - - void insert(const Value& value); - - void remove(const Key& key); - - unsigned int size() const; - -private: - - class Node - { - public: - - enum class Color - { - Black, - Red - } - - Key m_key; - - Value& m_value; - - Node *left, *right, *parent; - - Color color; - - Node(); - - Node* uncle() - { - if(parent != nullptr && parent->parent != nullptr) - { - if(parent == parent->parent->left) - return parent->parent->right; - return parent->parent->left; - } - return nullptr; - } - - Node* search(const Key& key) - { - if(key == m_key) - return this; - if(left != nullptr) - { - Node* lsearch = left->search(key); - if(lsearch != nullptr) - return lsearch; - } - if(right != nullptr) - { - Node* rsearch = right->search(key); - if(rsearch != nullptr) - return rsearch; - } - return nullptr; - } - - }; - - Node *m_tree; - -}; - -#endif \ No newline at end of file diff --git a/src/memoryblock.hpp b/src/memoryblock.hpp deleted file mode 100644 index 2df0625..0000000 --- a/src/memoryblock.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef MEMORYBLOCK_H -#define MEMORYBLOCK_H - -#include "systypes.hpp" - -class MemoryBlock -{ -public: - - physaddr_t getLocation() const; - - physaddr_t getEnd() const; - - size_t getSize() const; - - int getAttributes() const; - - unsigned int getOwners() const; - - void decrementOwners(); - -private: - - physaddr_t m_location; - - size_t m_size; - - int m_attributes; - - unsigned int m_owners; - -}; - -#endif \ No newline at end of file diff --git a/src/memorymanager.hpp b/src/memorymanager.hpp index f8259ff..72d8237 100644 --- a/src/memorymanager.hpp +++ b/src/memorymanager.hpp @@ -12,7 +12,7 @@ public: * * @return the size in bytes of a single page */ - virtual unsigned int pageSize() const = 0; + virtual unsigned int getPageSize() const = 0; /** * Allocates space for a new top-level page table, and initializes it to diff --git a/src/memorymap.cpp b/src/memorymap.cpp index d5e58e6..e1b21e9 100644 --- a/src/memorymap.cpp +++ b/src/memorymap.cpp @@ -2,129 +2,6 @@ using namespace kernelns; -MemoryMap::Region::Region() -{ - m_location = 0; - m_size = 0; - m_type = (Type) 0; -} - -MemoryMap::Region::Region(Region& copy) -{ - m_location = copy.m_location; - m_size = copy.m_size; - m_type = copy.m_type; -} - -MemoryMap::Region::Region(physaddr_t location, size_t size, Type type) -{ - m_location = location; - m_size = size; - m_type = (size_t) type; -} - -const MemoryMap::Region& MemoryMap::Region::operator=(const MemoryMap::Region& rhs) -{ - m_location = rhs.m_location; - m_size = rhs.m_size; - m_type = rhs.m_type; - return rhs; -} - -const bool MemoryMap::Region::operator==(const MemoryMap::Region& rhs) const -{ - return (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)); -} - -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; @@ -137,7 +14,7 @@ MemoryMap::MemoryMap(MemoryMap& copy) this->m_entries = copy.m_entries; } -const MemoryMap::Region& MemoryMap::operator[](size_t index) const +const MemoryRegion& MemoryMap::operator[](size_t index) const { return m_map[index]; } @@ -147,76 +24,58 @@ size_t MemoryMap::size() const return m_entries; } -void MemoryMap::insertEntry(physaddr_t location, size_t size, Type type) +size_t MemoryMap::totalMemory() const { - 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++) + size_t sum = 0; + for(int i = 0; i < m_entries; 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--; - } + sum += m_map[i].getSize(); } + return sum; +} + +size_t MemoryMap::totalMemory(unsigned int type) const +{ + size_t sum = 0; + for(int i = 0; i < m_entries; i++) + { + if(m_map[i].getType() == type) + sum += m_map[i].getSize(); + } + return sum; +} + +bool MemoryMap::overlaps(const MemoryRegion& region) const +{ + for(int i = 0; i < m_entries; i++) + { + if(m_map[i].overlaps(region)) + return true; + } + return false; +} + +bool MemoryMap::contains(const MemoryRegion& region) const +{ + for(int i = 0; i < m_entries; i++) + { + if(m_map[i].contains(region) && m_map[i].getType() == region.getType()) + return true; + } + return false; +} + +void MemoryMap::insertEntry(const MemoryRegion& region) +{ + simpleInsert(region); + unsigned int i = 0; + while(i != invalidIndex) + i = trim(i); +} + +void MemoryMap::insertEntry(physaddr_t location, size_t size, unsigned int type) +{ + insertEntry(MemoryRegion(location, size, type)); } void MemoryMap::remove(unsigned int index) @@ -226,4 +85,88 @@ void MemoryMap::remove(unsigned int index) m_map[i] = m_map[i+1]; } m_entries--; +} + +void MemoryMap::simpleInsert(const MemoryRegion& region) +{ + MemoryRegion newRegion(region); + unsigned int i = 0; + while(i < m_entries) + { + if(newRegion < m_map[i]) + { + MemoryRegion buffer = newRegion; + newRegion = m_map[i]; + m_map[i] = buffer; + } + i++; + } + m_map[i] = newRegion; + m_entries++; +} + +void MemoryMap::simpleInsert(physaddr_t location, size_t size, unsigned int type) +{ + simpleInsert(MemoryRegion(location, size, type)); +} + +unsigned int MemoryMap::trim(unsigned int index) +{ + if(index + 1 >= m_entries) + return invalidIndex; + MemoryRegion& left = m_map[index]; + MemoryRegion& right = m_map[index+1]; + if(left.overlaps(right)) + { + if(left.getType() == right.getType()) + { + left = MemoryRegion(left.getLocation(), + (right.getEnd() > left.getEnd() ? right.getEnd() : left.getEnd()) - left.getLocation(), + left.getType()); + remove(index + 1); + return index; + } + else if(left.getType() < right.getType()) + { + if(right.contains(left)) + { + remove(index); + return index; + } + else if(left.getEnd() <= right.getEnd()) + { + left.truncateRight(right.getLocation()); + return index + 1; + } + else + { + MemoryRegion newRight(right.getEnd(), left.getEnd() - right.getEnd(), left.getType()); + left.truncateRight(right.getLocation()); + if(left.getSize() == 0) + remove(index); + simpleInsert(newRight); + return index + 2; + } + } + else + { + if(left.contains(right)) + { + remove(index + 1); + return index; + } + else + { + right.truncateLeft(left.getEnd()); + return index + 1; + } + } + } + else if(left.bordersLeft(right) && left.getType() == right.getType()) + { + left = MemoryRegion(left.getLocation(), right.getEnd() - left.getLocation(), left.getType()); + remove(index + 1); + return index; + } + return index + 1; } \ No newline at end of file diff --git a/src/memorymap.hpp b/src/memorymap.hpp index 58aa1d0..6c428af 100644 --- a/src/memorymap.hpp +++ b/src/memorymap.hpp @@ -2,6 +2,7 @@ #define MEMORYMAP_H #include "systypes.hpp" +#include "memoryregion.hpp" namespace kernelns { @@ -9,90 +10,138 @@ namespace kernelns class MemoryMap { public: - - enum Type - { - AVAILABLE = 1, - UNAVAILABLE = 2, - ACPI = 3, - DEFECTIVE = 5 - }; - - class Region - { - public: - - Region(); - - Region(Region& copy); - - Region(physaddr_t location, size_t size, Type type); - - 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 m_location; - - size_t m_size; - - size_t m_type; - - }; MemoryMap(); MemoryMap(MemoryMap& copy); - const Region& operator[](size_t index) const; + const MemoryRegion& operator[](size_t index) const; + /** + * @return The number of memory regions described by this object + */ size_t size() const; + /** + * @brief Get the total amount of memory described by this memory map. + * Since no two regions may overlap, this is equivalent to the sum of the + * size of each memory region stored in this object. + * + * @return The total amount of memory described by this memory map. + */ size_t totalMemory() const; - void insertEntry(physaddr_t location, size_t size, Type type); + /** + * @brief Get the total amount of memory of a specified type described by + * this memory map. Since no two regions overlap, this is equivalent to the + * sum of the size of each memory region stored in this object whose type + * is equal to `type`. + * + * @param type The type of memory region to count + * @return The total amount of memory of the specified type + */ + size_t totalMemory(unsigned int type) const; + + /** + * @brief Checks if `region` overlaps any memory region contained in this + * memory map. + * + * @param region + * @return true if, for any region `k` in this map, `k.overlaps(region)`. + * @return false if there is no region in this map where `k.overlaps(region)`. + */ + bool overlaps(const MemoryRegion& region) const; + + /** + * @brief Checks if `region` is contained an any memory region in this map + * with the same type as `region`. + * + * @param region + * @return true if, for any region `k` in this map, `k.contains(region) + * && k.getType() == region.getType()`. + * @return false if the condition above is not true + */ + bool contains(const MemoryRegion& region) const; + + /** + * @brief Adds `region` into the memory map. Adjusts the map as necessary + * so that no regions overlap. Regions of higher type take precedence over + * regions with lower types; therefore, the lower typed regions are trimmed + * or deleted where they overlap with higher typed regions. Adjacent or + * overlapping regions with identical types are merged. + * + * @param region The memory region to insert + */ + void insertEntry(const MemoryRegion& region); + + /** + * @brief Overload of `insertEntry()`. @see insertRegion(const MemoryRegion&). + * + * @param location + * @param size + * @param type + */ + void insertEntry(physaddr_t location, size_t size, unsigned int type); private: + /** + * @brief Removes the element at `index` in `m_map`. All objects located + * after that index are moved accordingly. + * + * @param index Locatation of the object to delete + */ void remove(unsigned int index); + /** + * @brief Inserts a copy of `region` into `m_map`. The new element is + * inserted such that `m_map` is sorted in ascending order. Overlapping + * elements are not trimmed. + * + * @param region The memory region to insert + */ + void simpleInsert(const MemoryRegion& region); + + /** + * @brief Overload of `simpleInsert(const MemoryRegion& region)`. + * + * @param location + * @param size + * @param type + */ + void simpleInsert(physaddr_t location, size_t size, unsigned int type); + + /** + * @brief If `m_map[index].overlaps(m_map[index+1])`, the two elements are + * modified so that they no longer overlap. The following rules apply: + * + * 1. This memory map will describe the same set of locations before and + * after performing this operation. + * + * 2. Adjacent regions of the same type are merged into a single region. + * + * 3. Where two regions of differing types overlap, the higher type takes + * precedence. The region of the lower type is truncated, split, or deleted + * so as to not overlap the region of the higher type. + * + * 4. This operation is local: only `m_map[index]` and `m_map[index+1]` are + * modified (although if a region must be split, a new region will be + * inserted at the location `index+2`). + * + * This function has no effect if `index+1 >= m_entries`, or if + * `m_map[index]` does not overlap the `m_map[index+1]`. + * + * @param index The location of the region to trim. + * + * @return The index of the rightmost region affected. + */ + unsigned int trim(unsigned int index); + static const unsigned int maxEntries = 16; - Region m_map[maxEntries]; + static const unsigned int invalidIndex = 0xFFFF; + + MemoryRegion m_map[maxEntries]; size_t m_entries; diff --git a/src/memoryregion.cpp b/src/memoryregion.cpp new file mode 100644 index 0000000..d0eeb15 --- /dev/null +++ b/src/memoryregion.cpp @@ -0,0 +1,128 @@ +#include "memoryregion.hpp" + +MemoryRegion::MemoryRegion() +{ + m_location = 0; + m_size = 0; + m_type = 0; +} + +MemoryRegion::MemoryRegion(const MemoryRegion& copy) +{ + m_location = copy.m_location; + m_size = copy.m_size; + m_type = copy.m_type; +} + +MemoryRegion::MemoryRegion(physaddr_t location, size_t size, unsigned int type) +{ + m_location = location; + m_size = size; + m_type = (size_t) type; +} + +const MemoryRegion& MemoryRegion::operator=(const MemoryRegion& rhs) +{ + m_location = rhs.m_location; + m_size = rhs.m_size; + m_type = rhs.m_type; + return rhs; +} + +bool MemoryRegion::operator==(const MemoryRegion& rhs) const +{ + return (m_location == rhs.m_location) && (m_size == rhs.m_size); +} + +bool MemoryRegion::operator!=(const MemoryRegion& rhs) const +{ + return (m_location != rhs.m_location) || (m_size != rhs.m_size); +} + +bool MemoryRegion::operator<(const MemoryRegion& rhs) const +{ + return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size < rhs.m_size)); +} + +bool MemoryRegion::operator>(const MemoryRegion& rhs) const +{ + return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size > rhs.m_size)); +} + +bool MemoryRegion::operator<=(const MemoryRegion& rhs) const +{ + return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size <= rhs.m_size)); +} + +bool MemoryRegion::operator>=(const MemoryRegion& rhs) const +{ + return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size >= rhs.m_size)); +} + +physaddr_t MemoryRegion::getLocation() const +{ + return m_location; +} + +size_t MemoryRegion::getSize() const +{ + return m_size; +} + +unsigned int MemoryRegion::getType() const +{ + return m_type; +} + +physaddr_t MemoryRegion::getEnd() const +{ + return m_location + m_size; +} + +bool MemoryRegion::contains(const MemoryRegion& r) const +{ + return contains(r.m_location, r.m_size); +} + +bool MemoryRegion::contains(physaddr_t location, size_t size) const +{ + return (location >= m_location) && + (location + size <= m_location + m_size); +} + +bool MemoryRegion::overlaps(const MemoryRegion& r) const +{ + if(r.m_location < m_location) + return r.m_location + r.m_size > m_location; + else + return r.m_location < getEnd(); +} + +bool MemoryRegion::bordersLeft(const MemoryRegion& right) const +{ + return getEnd() == right.m_location; +} + +bool MemoryRegion::bordersRight(const MemoryRegion& left) const +{ + return m_location == left.m_location + left.m_size; +} + +bool MemoryRegion::borders(const MemoryRegion& r) const +{ + return bordersLeft(r) || bordersRight(r); +} + +void MemoryRegion::truncateLeft(physaddr_t left) +{ + m_size = getEnd() - left; + m_location = left; +} + +void MemoryRegion::truncateRight(physaddr_t right) +{ + if(right > m_location) + m_size = right - m_location; + else + m_size = 0; +} \ No newline at end of file diff --git a/src/memoryregion.hpp b/src/memoryregion.hpp new file mode 100644 index 0000000..35e57e8 --- /dev/null +++ b/src/memoryregion.hpp @@ -0,0 +1,87 @@ +#ifndef MEMORYBLOCK_H +#define MEMORYBLOCK_H + +#include "systypes.hpp" + +class MemoryRegion +{ +public: + + MemoryRegion(); + + MemoryRegion(const MemoryRegion& copy); + + MemoryRegion(physaddr_t location, size_t size, unsigned int type); + + const MemoryRegion& operator=(const MemoryRegion& rhs); + + /** + * @brief Tests whether this object describes the same region of memory + * as rhs, irrespective of type. + * + * @param rhs The object to compare to + * @return true if and only if the location and size of the two regions are equal + * @return false if the two regions have differing locations or differing sizes + */ + bool operator==(const MemoryRegion& rhs) const; + + /** + * @brief Tests whether this object describes a different region of memory + * than rhs, irrespective of type. + * + * @param rhs The object to compare to + * @return true if the two regions have differing locations or differing sizes + * @return false if and only if the location and size of the two regions are equal + */ + bool operator!=(const MemoryRegion& rhs) const; + + /** + * @brief + * + * @param rhs + * @return true + * @return false + */ + bool operator<(const MemoryRegion& rhs) const; + + bool operator>(const MemoryRegion& rhs) const; + + bool operator<=(const MemoryRegion& rhs) const; + + bool operator>=(const MemoryRegion& rhs) const; + + physaddr_t getLocation() const; + + size_t getSize() const; + + unsigned int getType() const; + + physaddr_t getEnd() const; + + bool contains(const MemoryRegion& r) const; + + bool contains(physaddr_t location, size_t size) const; + + bool overlaps(const MemoryRegion& r) const; + + bool bordersLeft(const MemoryRegion& right) const; + + bool bordersRight(const MemoryRegion& left) const; + + bool borders(const MemoryRegion& r) const; + + void truncateLeft(physaddr_t left); + + void truncateRight(physaddr_t right); + +private: + + physaddr_t m_location; + + size_t m_size; + + unsigned int m_type; + +}; + +#endif \ No newline at end of file diff --git a/src/memorytype.hpp b/src/memorytype.hpp new file mode 100644 index 0000000..99ea80b --- /dev/null +++ b/src/memorytype.hpp @@ -0,0 +1,11 @@ +#ifndef MEMORYTYPE_H +#define MEMORYTYPE_H + +enum class MemoryType +{ + Available = 1, + Unavailable = 2, + Defective = 3 +}; + +#endif \ No newline at end of file diff --git a/src/message.cpp b/src/message.cpp new file mode 100644 index 0000000..2f503d5 --- /dev/null +++ b/src/message.cpp @@ -0,0 +1,38 @@ +#include "message.hpp" + +Message::Message() +{ + m_sender = 0; + m_type = 0; + m_args[0] = 0; + m_args[1] = 0; + m_args[2] = 0; +} + +Message::Message(const Message& copy) +{ + m_sender = copy.m_sender; + m_type = copy.m_type; + m_args[0] = copy.m_args[0]; + m_args[1] = copy.m_args[1]; + m_args[2] = copy.m_args[2]; +} + +Message::Message(unsigned int sender, unsigned int type, + unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ + m_sender = sender; + m_type = type; + m_args[0] = arg1; + m_args[1] = arg2; + m_args[2] = arg3; +} + +Message& Message::operator=(const Message& rhs) +{ + m_sender = rhs.m_sender; + m_type = rhs.m_type; + m_args[0] = rhs.m_args[0]; + m_args[1] = rhs.m_args[1]; + m_args[2] = rhs.m_args[2]; +} \ No newline at end of file diff --git a/src/message.hpp b/src/message.hpp new file mode 100644 index 0000000..0702b1e --- /dev/null +++ b/src/message.hpp @@ -0,0 +1,59 @@ +#ifndef MESSAGE_H +#define MESSAGE_H + +struct Message +{ + + /** + * @brief Default constructor. Initializes all members to 0. + * + */ + Message(); + + /** + * @brief Copy constructor. + * + * @param copy + */ + Message(const Message& copy); + + /** + * @brief Construct a new Message object. + * + * @param sender + * @param type + * @param arg1 + * @param arg2 + * @param arg3 + */ + Message(unsigned int sender, unsigned int type, + unsigned long arg1, unsigned long arg2, unsigned long arg3); + + /** + * @brief Copy the contents of `rhs` to this object. + * + * @param rhs + * @return Message& + */ + Message& operator=(const Message& rhs); + + /** + * @brief PID of the process that generated this message. + */ + unsigned int m_sender; + + /** + * @brief Context-specific parameter which indicates to the receiver how + * the arguments are to be interpreted. + */ + unsigned int m_type; + + /** + * @brief Arguments of this message. The meaning of these values depend on + * context, as well as the values of `m_sender` and `m_type`. + */ + unsigned long m_args[3]; + +}; + +#endif \ No newline at end of file diff --git a/src/mmgr.hpp b/src/mmgr.hpp deleted file mode 100644 index e39cb6e..0000000 --- a/src/mmgr.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef MMGR_H -#define MMGR_H - -#include "mmap.hpp" -#include "pageallocator.hpp" - -#endif \ No newline at end of file diff --git a/src/pageallocator.cpp b/src/pageallocator.cpp index 08b6892..43ea72b 100755 --- a/src/pageallocator.cpp +++ b/src/pageallocator.cpp @@ -1,6 +1,7 @@ #include "pageallocator.hpp" #include "systypes.hpp" #include "memorymap.hpp" +#include "memorytype.hpp" #define roundUp(n, m) ((n % m == 0) ? n : (n + m - (n % m))) @@ -44,7 +45,7 @@ kernelns::BuddyAllocator::BuddyAllocator(const kernelns::MemoryMap& memmap, physaddr_t location = 0x100000; for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++) { - if(memmap[i].getType() != kernelns::MemoryMap::AVAILABLE) + if(memmap[i].getType() != (unsigned int) MemoryType::Available) continue; if(memmap[i].getLocation() > location) location = roundUp(memmap[i].getLocation(), 4096); diff --git a/src/process.hpp b/src/process.hpp index e84ef97..b25238f 100644 --- a/src/process.hpp +++ b/src/process.hpp @@ -2,7 +2,8 @@ #define PROCESS_H #include -#include "map.hpp" + +#include "message.hpp" namespace kernelns { @@ -17,16 +18,35 @@ public: Process(); + unsigned int getID() const; + + bool map(void* location, size_t size); + + /** + * @brief If the specified region is mapped and does not overlap a shared + * or private block, or the kernel, removes that region from the process's + * internal memory map. If the specified region overlaps an unmapped region, + * a shared or private block, or the kernel, the object goes unmodified. + * This method does not affect the page tables in any way, only the process's + * internal bookkeeping. + * + * @param location + * @param size + * @return true if the memory map was sucessfully updated + * @return false if the memory map was not modified + */ + bool unmap(void* location, size_t size); + bool hasSharedBlock(unsigned int blockID) const; bool hasPhysicalBlock(unsigned int blockID) const; + void pushMessage(Message* message); + + Message* popMessage(); + private: - Map m_sharedBlocks; - - Map m_physicalBlocks; - }; } diff --git a/src/sharedblock.hpp b/src/sharedblock.hpp new file mode 100644 index 0000000..e9fe3d6 --- /dev/null +++ b/src/sharedblock.hpp @@ -0,0 +1,18 @@ +#ifndef SHAREDBLOCK_H +#define SHAREDBLOCK_H + +#include "memoryregion.hpp" + +class SharedBlock : public MemoryRegion +{ +public: + + unsigned int getFlags() const; + +private: + + unsigned int m_flags; + +}; + +#endif \ No newline at end of file diff --git a/src/syscalls.cpp b/src/syscalls.cpp index 8255d15..30e3918 100644 --- a/src/syscalls.cpp +++ b/src/syscalls.cpp @@ -1,17 +1,28 @@ #include "syscalls.hpp" #include "kernel.hpp" +#include "memorytype.hpp" int mmap(void* location, size_t length, int flags) { - // TODO: check that the requested region does not overlap something important + if(kernel.getActiveProcess().map(location, length)) + { + if(kernel.allocateRegion(location, length, flags)) + return 0; + else if(kernel.getActiveProcess().unmap(location, length)) + return 1; + kernel.terminateActiveProcess(); + } return kernel.allocateRegion(location, length, flags); } int munmap(void* location, size_t length) { - // TODO: check that the requested region does not overlap something important - kernel.freeRegion(location, length); - return 0; + if(kernel.getActiveProcess().unmap(location, length)) + { + kernel.freeRegion(location, length); + return 0; + } + return 1; } unsigned int createSharedBlock(void* location, size_t length, int flags) @@ -19,7 +30,7 @@ unsigned int createSharedBlock(void* location, size_t length, int flags) unsigned int blockID = kernel.createSharedBlock(length, flags); if(blockID > 0) { - const MemoryBlock& block = kernel.getSharedBlock(blockID); + const SharedBlock& block = kernel.getSharedBlock(blockID); kernel.mapRegion(location, block.getLocation(), length, flags); // TODO: add block to current process // TODO: perform safety checks @@ -29,8 +40,8 @@ unsigned int createSharedBlock(void* location, size_t length, int flags) int aquireSharedBlock(void* location, unsigned int id) { - const MemoryBlock& block = kernel.getSharedBlock(id); - kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getAttributes()); + const SharedBlock& block = kernel.getSharedBlock(id); + kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getFlags()); // TODO: (somehow) handle invalid ids -- possibly hard while using references // TODO: add block to current process // TODO: perform safety checks @@ -59,4 +70,24 @@ int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t lengt int releasePhysicalBlock(int id) { return 0; +} + +int sendMessage(unsigned int recipient, const Message* message) +{ + Message* copy = new Message(*message); + copy->m_sender = kernel.getActiveProcess().getID(); + kernel.getProcess(recipient).pushMessage(copy); + return 0; +} + +int receiveMessage(Message* buffer) +{ + if(buffer == nullptr) + return 1; + Message* message = kernel.getActiveProcess().popMessage(); + if(message == nullptr) + return 1; + *buffer = *message; + delete message; + return 0; } \ No newline at end of file diff --git a/src/syscalls.hpp b/src/syscalls.hpp index 3971369..5364426 100644 --- a/src/syscalls.hpp +++ b/src/syscalls.hpp @@ -3,6 +3,7 @@ #include #include "systypes.hpp" +#include "message.hpp" int mmap(void* location, size_t length, int flags); @@ -20,4 +21,8 @@ int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t lengt int releasePhysicalBlock(int id); +int sendMessage(unsigned int recipient, const Message* message); + +int receiveMessage(Message* buffer); + #endif \ No newline at end of file diff --git a/src/systeminfo.cpp b/src/systeminfo.cpp deleted file mode 100644 index a7ceb84..0000000 --- a/src/systeminfo.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "systeminfo.hpp" -#include "util.hpp" - -using namespace kernelns; - -SystemInfo::SystemInfo() -{ - -} - -SystemInfo::SystemInfo(MemoryMap& memoryMap, const char* commandLine) - : m_memmap(memoryMap) -{ - strcpy(this->commandLine, commandLine); -} - -const MemoryMap& SystemInfo::getMemoryMap() const -{ - return m_memmap; -} - -const char* SystemInfo::getCommandLine() const -{ - return commandLine; -} diff --git a/src/systeminfo.hpp b/src/systeminfo.hpp deleted file mode 100644 index caff548..0000000 --- a/src/systeminfo.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef SYSTEMINFO_H -#define SYSTEMINFO_H - -#include - -#include "systypes.hpp" -#include "memorymap.hpp" - -namespace kernelns -{ - -class SystemInfo -{ -public: - - SystemInfo(); - - SystemInfo(MemoryMap& memoryMap, const char* commandLine); - - const MemoryMap& getMemoryMap() const; - - const char* getCommandLine() const; - -private: - - MemoryMap m_memmap; - - char commandLine[128]; - -}; - -} - -#endif diff --git a/src/util.cpp b/src/util.cpp index 89c2958..1256dbc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,7 +1,7 @@ #include #include "util.hpp" -#include "kernelstate.hpp" +#include "kernel.hpp" void* memcpy(void* destination, const void* source, size_t num) { @@ -112,25 +112,31 @@ char* strcpy(char* destination, const char* source) void* malloc(size_t size) { - return kernelns::State::allocator.allocate(size); + return kernel.malloc(size); } void* calloc(size_t count, size_t size) { - return memset(malloc(count * size), 0, count * size); + void* ptr = malloc(count * size); + if(ptr != nullptr) + memset(malloc(count * size), 0, count * size); + return ptr; } void* realloc(void* ptr, size_t size) { - void* n = kernelns::State::allocator.allocate(size); - memmove(n, ptr, size); - free(ptr); + void* n = kernel.malloc(size); + if(n != nullptr) + { + memmove(n, ptr, size); + free(ptr); + } return n; } void free(void* p) { - kernelns::State::allocator.free(p); + kernel.free(p); } void __cxa_pure_virtual() diff --git a/src/x86/initialize.cpp b/src/x86/initialize.cpp index 57255fb..361cd4f 100644 --- a/src/x86/initialize.cpp +++ b/src/x86/initialize.cpp @@ -1,30 +1,14 @@ #include #include "multiboot2.hpp" #include "tty.hpp" -#include "../kernelstate.hpp" -#include "../systeminfo.hpp" #include "../mmap.hpp" #include "../util.hpp" +#include "../memorytype.hpp" using namespace kernelns; extern int _kernelEnd; -enum BootInfoType -{ - Terminate = 0, - CommandLine = 1, - BootLoader = 2, - Module = 3, - MemoryInfo = 4, - BootDevice = 5, - MMap = 6, - VBEInfo = 7, - FramebufferInfo = 8, - ELFSymbols = 9, - APMTable = 10 -}; - extern "C" int startPaging(uint32_t* directory, uint32_t* table, uint32_t* identityTable) { @@ -57,12 +41,12 @@ int initialize(void* multibootInfo) for(; heapSize > 1; log++) heapSize >>= 1; heapSize <<= log; - new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64); + //new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64); Multiboot2Info bootInfo(multibootInfo); if(!bootInfo.isValid()) return 1; - bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, MemoryMap::UNAVAILABLE); - new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine()); + bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, (unsigned int) MemoryType::Unavailable); + //new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine()); TTY tty((char*) 0xFF8B8000); tty << "Type\t\tLocation\t\tSize\n"; for(size_t i = 0; i < bootInfo.getMemoryMap().size() && bootInfo.getMemoryMap()[i].getSize() > 0; i++) diff --git a/src/x86/memorymanagerx86.cpp b/src/x86/memorymanagerx86.cpp new file mode 100644 index 0000000..b4aaefc --- /dev/null +++ b/src/x86/memorymanagerx86.cpp @@ -0,0 +1,31 @@ +#include "memorymanagerx86.hpp" + +unsigned int MemoryManagerx86::getPageSize() const +{ + return pageSize; +} + +physaddr_t MemoryManagerx86::createAddressSpace() +{ + if(((size_t) table & 0xFFF) != 0) + return -1; + PageTableEntry* newDirectory = (PageTableEntry*) table; + newDirectory[1022] = m_pageDirectory[1022]; + newDirectory[1023] = m_pageDirectory[1023]; + return 0; +} + +void MemoryManagerx86::loadAddressSpace(physaddr_t table) +{ + +} + +int MemoryManagerx86::mapPage(void *page, physaddr_t frame, int flags) +{ + +} + +physaddr_t MemoryManagerx86::unmapPage(void *page) +{ + +} \ No newline at end of file diff --git a/src/x86/memorymanagerx86.hpp b/src/x86/memorymanagerx86.hpp new file mode 100644 index 0000000..ed3273e --- /dev/null +++ b/src/x86/memorymanagerx86.hpp @@ -0,0 +1,29 @@ +#ifndef MEMORYMANAGERX86_H +#define MEMORYMANAGERX86_H + +#include "../memorymanager.hpp" +#include "pagetableentry.hpp" + +class MemoryManagerx86 : public MemoryManager +{ +public: + + virtual unsigned int getPageSize() const; + + virtual physaddr_t createAddressSpace(); + + virtual void loadAddressSpace(physaddr_t table); + + virtual int mapPage(void* page, physaddr_t frame, int flags); + + virtual physaddr_t unmapPage(void* page); + +private: + + static const unsigned int pageSize = 4096; + + PageTableEntry *m_pageTables, *m_pageDirectory; + +}; + +#endif \ No newline at end of file diff --git a/src/x86/multiboot2.cpp b/src/x86/multiboot2.cpp index b1569f4..ba745b5 100644 --- a/src/x86/multiboot2.cpp +++ b/src/x86/multiboot2.cpp @@ -1,4 +1,5 @@ #include "multiboot2.hpp" +#include "../memorytype.hpp" using namespace kernelns; @@ -11,31 +12,35 @@ Multiboot2Info::Multiboot2Info(void* tableLocation) ptr += 2; while(*ptr != 0) { - if(*ptr == T_BootCommand) + if(*ptr == (uint32_t) Tag::BootCommand) { m_commandLine = &reinterpret_cast(ptr)->str; } - else if(*ptr == T_Bootloader) + else if(*ptr == (uint32_t) Tag::Bootloader) { m_bootloader = &reinterpret_cast(ptr)->str; } - else if(*ptr == T_MemoryMap) + else if(*ptr == (uint32_t) Tag::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); + unsigned int regionType = + (entry->type == (unsigned int) Multiboot2MemoryType::Available) ? (unsigned int) MemoryType::Available + : ((entry->type == (unsigned int) Multiboot2MemoryType::Defective) ? (unsigned int) MemoryType::Defective + : (unsigned int) MemoryType::Unavailable); + m_memmap.insertEntry(entry->base, entry->length, entry->type); entry = (MemoryMapEntry*) (reinterpret_cast(entry) + entrySize); tagSize -= entrySize; } } - else if(*ptr == T_Module) + else if(*ptr == (uint32_t) Tag::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); + m_memmap.insertEntry(moduleTag->start, moduleTag->end - moduleTag->start, (unsigned int) MemoryType::Unavailable); } unsigned int size = (ptr[1] + 7) - ((ptr[1] + 7) % 8); ptr += size / sizeof(uint32_t); diff --git a/src/x86/multiboot2.hpp b/src/x86/multiboot2.hpp index 6fcaf37..73962e1 100644 --- a/src/x86/multiboot2.hpp +++ b/src/x86/multiboot2.hpp @@ -11,29 +11,36 @@ class Multiboot2Info { public: - enum TagType + enum class Tag { - 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 + BootCommand = 1, + Bootloader = 2, + Module = 3, + MemoryInfo = 4, + BIOSBootDevice = 5, + MemoryMap = 6, + VBE = 7, + Framebuffer = 8, + ELFSymbols = 9, + APM = 10, + EFI32SystemTable = 11, + EFI64SystemTable = 12, + SMBIOS = 13, + ACPI10RSDP = 14, + ACPT20RSDP = 15, + Network = 16, + EFIMemoryMap = 17, + EFIBootServices = 18, + EFI32Image = 19, + EFI64Image = 20, + LoadAddress = 21 + }; + + enum class Multiboot2MemoryType + { + Available = 1, + ACPI = 3, + Defective = 5 }; struct TagString diff --git a/src/x86/pagetableentry.cpp b/src/x86/pagetableentry.cpp new file mode 100644 index 0000000..5e50799 --- /dev/null +++ b/src/x86/pagetableentry.cpp @@ -0,0 +1,132 @@ +#include "pagetableentry.hpp" + +PageTableEntry::PageTableEntry() +{ + this->present = 0; + this->rw = 0; + this->usermode = 0; + this->writeThrough = 0; + this->cacheDisable = 0; + this->accessed = 0; + this->dirty = 0; + this->pat = 0; + this->global = 0; + this->shared = 0; + this->ignored = 0; + this->physicalAddress = 0; +} + +bool PageTableEntry::getAccessed() const +{ + return accessed == 1; +} + +bool PageTableEntry::getCacheDisable() const +{ + return cacheDisable == 1; +} + +void PageTableEntry::setCacheDisable(bool cacheDisable) +{ + this->cacheDisable = cacheDisable ? 1 : 0; +} + +bool PageTableEntry::getDirty() const +{ + return dirty == 1; +} + +bool PageTableEntry::getGlobal() const +{ + return global == 1; +} + +void PageTableEntry::setGlobal(bool global) +{ + this->global = global ? 1 : 0; +} + +bool PageTableEntry::getPat() const +{ + return pat == 1; +} + +void PageTableEntry::setPat(bool pat) +{ + this->pat = pat ? 1 : 0; +} + +physaddr_t PageTableEntry::getPhysicalAddress() const +{ + physaddr_t physicalAddress = this->physicalAddress; + return physicalAddress << 12; +} + +physaddr_t PageTableEntry::setPhysicalAddress(physaddr_t physicalAddress) +{ + this->physicalAddress = physicalAddress >> 12; + return this->physicalAddress << 12; +} + +bool PageTableEntry::getPresent() const +{ + return present == 1; +} + +void PageTableEntry::setPresent(bool present) +{ + this->present = present ? 1 : 0; +} + +bool PageTableEntry::getRw() const +{ + return rw == 1; +} + +void PageTableEntry::setRw(bool rw) +{ + this->rw = rw ? 1 : 0; +} + +bool PageTableEntry::getShared() const +{ + return shared == 1; +} + +void PageTableEntry::setShared(bool shared) +{ + this->shared = shared ? 1 : 0; +} + +bool PageTableEntry::getUsermode() const +{ + return usermode == 1; +} + +void PageTableEntry::setUsermode(bool usermode) +{ + this->usermode = usermode ? 1 : 0; +} + +bool PageTableEntry::getWriteThrough() const +{ + return writeThrough == 1; +} + +void PageTableEntry::setWriteThrough(bool writeThrough) +{ + this->writeThrough = writeThrough ? 1 : 0; +} + +physaddr_t PageTableEntry::operator=(physaddr_t rhs) +{ + return setPhysicalAddress(rhs); +} + +PageTableEntry PageTableEntry::operator=(PageTableEntry rhs) +{ + uint32_t *iThis = (uint32_t *)this; + uint32_t *iThat = (uint32_t *)&rhs; + *iThis = *iThat; + return rhs; +} \ No newline at end of file diff --git a/src/x86/pagetableentry.hpp b/src/x86/pagetableentry.hpp new file mode 100644 index 0000000..1a5381c --- /dev/null +++ b/src/x86/pagetableentry.hpp @@ -0,0 +1,83 @@ +#ifndef PAGETABLEENTRY_H +#define PAGETABLEENTRY_H + +#include "../systypes.hpp" + +class PageTableEntry { +public: + + PageTableEntry(); + + bool getAccessed() const; + + bool getCacheDisable() const; + + void setCacheDisable(bool cacheDisable); + + bool getDirty() const; + + bool getGlobal() const; + + void setGlobal(bool global); + + bool getPat() const; + + void setPat(bool pat); + + physaddr_t getPhysicalAddress() const; + + physaddr_t setPhysicalAddress(physaddr_t physicalAddress); + + bool getPresent() const; + + void setPresent(bool present); + + bool getRw() const; + + void setRw(bool rw); + + bool getShared() const; + + void setShared(bool shared); + + bool getUsermode() const; + + void setUsermode(bool usermode); + + bool getWriteThrough() const; + + void setWriteThrough(bool writeThrough); + + physaddr_t operator=(physaddr_t rhs); + + PageTableEntry operator=(PageTableEntry rhs); + +private: + + uint32_t present : 1; + + uint32_t rw : 1; + + uint32_t usermode : 1; + + uint32_t writeThrough : 1; + + uint32_t cacheDisable : 1; + + uint32_t accessed : 1; + + uint32_t dirty : 1; + + uint32_t pat : 1; + + uint32_t global : 1; + + uint32_t shared : 1; + + uint32_t ignored : 2; + + uint32_t physicalAddress : 20; + +}; + +#endif \ No newline at end of file From 51b6c13b161f58ae4a94848dd9f818167b406ab5 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sun, 4 Apr 2021 19:05:26 -0500 Subject: [PATCH 034/109] Rewrote page allocator; now allocate one at a time --- src/pageallocator.cpp | 270 ------------------------------------- src/pageallocator.hpp | 107 +-------------- src/pageallocatorstack.cpp | 52 +++++++ src/pageallocatorstack.hpp | 34 +++++ 4 files changed, 92 insertions(+), 371 deletions(-) delete mode 100755 src/pageallocator.cpp create mode 100644 src/pageallocatorstack.cpp create mode 100644 src/pageallocatorstack.hpp diff --git a/src/pageallocator.cpp b/src/pageallocator.cpp deleted file mode 100755 index 43ea72b..0000000 --- a/src/pageallocator.cpp +++ /dev/null @@ -1,270 +0,0 @@ -#include "pageallocator.hpp" -#include "systypes.hpp" -#include "memorymap.hpp" -#include "memorytype.hpp" - -#define roundUp(n, m) ((n % m == 0) ? n : (n + m - (n % m))) - -uint32_t ilog2(uint32_t n, bool roundUp) -{ - uint32_t m = n; - uint32_t count = 0; - bool isPowerOfTwo = true; - while(m) - { - if((m & 1) == 1 && m > 1) - { - isPowerOfTwo = false; - } - count++; - m >>= 1; - } - return count - (isPowerOfTwo ? 1 : (roundUp ? 0 : 1)); -} - -kernelns::BuddyAllocator::BuddyAllocator() -{ - -} - -kernelns::BuddyAllocator::BuddyAllocator(const kernelns::MemoryMap& memmap, - char* bitmap, size_t blockCount, - size_t treeHeight) -{ - this->bitmap = bitmap; - this->blockSize = 4096; - this->blockCount = blockCount; - this->treeHeight = treeHeight; - for(size_t i = 0; i <= treeHeight; i++) - { - for(size_t j = 0; j < (blockCount >> i); j++) - { - reserveNode(i, j); - } - } - physaddr_t location = 0x100000; - for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++) - { - if(memmap[i].getType() != (unsigned int) MemoryType::Available) - continue; - if(memmap[i].getLocation() > location) - location = roundUp(memmap[i].getLocation(), 4096); - while(memmap[i].contains(location, 4096)) - { - freeNode(0, location / 4096); - if(isFree(0, getBuddy(location / 4096))) - merge(0, location / 4096); - location += 4096; - } - } -} - -kernelns::BuddyAllocator::BuddyAllocator(char* bitmap, size_t blockSize, - size_t blockCount, size_t treeHeight) -{ - this->bitmap = bitmap; - this->blockSize = blockSize; - this->blockCount = blockCount; - this->treeHeight = treeHeight; - for(size_t i = 0; i <= treeHeight; i++) - { - for(size_t j = 0; j < (blockCount >> i); j++) - { - if(i < treeHeight) - reserveNode(i, j); - else - freeNode(i, j); - } - } -} - -physaddr_t kernelns::BuddyAllocator::allocate(size_t size) -{ - size_t height = ilog2(roundUp(size, blockSize) / blockSize, true); - if(height > treeHeight) // Requested block size is greater than maximum - { - return 0; - } - else - { - size_t index = findFreeBlock(height); - if(index == INVALID) // Failed to find a big enough free block; out of memory - { - return 0; - } - else - { - reserveNode(height, index); - return nodeToAddress(height, index); - } - } -} - -void kernelns::BuddyAllocator::free(physaddr_t location, size_t size) -{ - size_t height = ilog2(roundUp(size, blockSize) / blockSize, true); - if(height <= treeHeight) - { - size_t index = addressToNode(height, location); - freeNode(height, index); - if(isFree(height, getBuddy(index))) - { - merge(height, index); - } - } -} - -size_t kernelns::BuddyAllocator::freeBlocks() const -{ - size_t count = 0; - for(size_t j = 0; j < blockCount; j++) - { - if(isFree(0, j)) - { - count++; - } - } - return count; -} - -size_t kernelns::BuddyAllocator::maxAllocationSize() const -{ - for(size_t i = treeHeight; i >= 0; i--) - { - for(size_t j = 0; j < (blockCount >> i); j++) - { - if(isFree(i, j)) - { - return 1 << i; - } - } - } - return 0; -} - -size_t kernelns::BuddyAllocator::getBlockSize() const -{ - return blockSize; -} - -size_t kernelns::BuddyAllocator::getMemorySize() const -{ - return blockCount; -} - -size_t kernelns::BuddyAllocator::findFreeBlock(size_t height) -{ - for(size_t i = 0; i < (blockCount >> height); i++) - { - if(isFree(height, i)) - { - return i; - } - } - if(height < treeHeight) - { - size_t parentIndex = findFreeBlock(height + 1); - if(parentIndex != INVALID) - { - return split(height + 1, parentIndex); - } - } - return INVALID; -} - -size_t kernelns::BuddyAllocator::split(size_t height, size_t index) -{ - if(height > 0 && isFree(height, index)) - { - reserveNode(height, index); - freeNode(height - 1, getChild(index)); - freeNode(height - 1, getBuddy(getChild(index))); - return getChild(index); - } - else - { - return INVALID; - } -} - -size_t kernelns::BuddyAllocator::merge(size_t height, size_t index) -{ - if(isFree(height, index) && isFree(height, getBuddy(index)) && height < treeHeight) - { - reserveNode(height, index); - reserveNode(height, getBuddy(index)); - freeNode(height + 1, getParent(index)); - if((height + 1) < treeHeight) - { - if(isFree(height + 1, getBuddy(getParent(index)))) - { - return merge(height + 1, getParent(index)); - - } - } - return getParent(index); - } - else - { - return INVALID; - } -} - -size_t kernelns::BuddyAllocator::getBuddy(size_t index) -{ - return index ^ 1; -} - -size_t kernelns::BuddyAllocator::getParent(size_t index) -{ - return index / 2; -} - -size_t kernelns::BuddyAllocator::getChild(size_t index) -{ - return index * 2; -} - -physaddr_t kernelns::BuddyAllocator::nodeToAddress(size_t height, size_t index) - const -{ - return index * (blockSize << height); -} - -size_t kernelns::BuddyAllocator::addressToNode(size_t height, - physaddr_t location) const -{ - return location / (blockSize << height); -} - -void kernelns::BuddyAllocator::reserveNode(size_t height, size_t index) -{ - size_t bit = (height == 0) ? 0 - : ((blockCount * 2) - (blockCount >> (height - 1))); - bit += index; - bitmap[bit / 8] |= 1 << (bit % 8); -} - -void kernelns::BuddyAllocator::freeNode(size_t height, size_t index) -{ - size_t bit = (height == 0) ? 0 - : ((blockCount * 2) - (blockCount >> (height - 1))); - bit += index; - bitmap[bit / 8] &= ~(1 << (bit % 8)); -} - -bool kernelns::BuddyAllocator::isFree(size_t height, size_t index) const -{ - size_t bit = (height == 0) ? 0 - : ((blockCount * 2) - (blockCount >> (height - 1))); - bit += index; - char data = bitmap[bit / 8] & (1 << (bit % 8)); - if(data == 0) - { - return true; - } - else - { - return false; - } -} diff --git a/src/pageallocator.hpp b/src/pageallocator.hpp index 15b1ce5..2e600a7 100755 --- a/src/pageallocator.hpp +++ b/src/pageallocator.hpp @@ -3,46 +3,33 @@ #include #include "systypes.hpp" -#include "memorymap.hpp" namespace kernelns { /** - * Interface for a dymanic memory allocator. + * Interface for a physical memory allocator. */ class PageAllocator { public: /** - * Allocate a block of memory containing 'size' bytes. May round up - * depending on the implementation. + * Allocate a single page, returning its physical address. Upon failure, + * returns an error code such that the least signifigant byte is nonzero. */ - virtual physaddr_t allocate(size_t size) = 0; + virtual physaddr_t next() = 0; /** - * Free the region of memory starting at 'location' and containing - * 'size' bytes. + * Frees a single page that has previously been allocated. */ - virtual void free(physaddr_t location, size_t size) = 0; + virtual void free(physaddr_t location) = 0; /** * @returns the total number of free blocks of memory. */ virtual size_t freeBlocks() const = 0; - /** - * @returns the size in blocks of the largest possible allocation that - * will not fail due to lack of memory. - */ - virtual size_t maxAllocationSize() const = 0; - - /** - * @returns the size in bytes of a single block. - */ - virtual size_t getBlockSize() const = 0; - /** * @returns the total number of blocks managed by this memory * allocator. @@ -50,88 +37,6 @@ public: virtual size_t getMemorySize() const = 0; }; - -class BuddyAllocator : public PageAllocator -{ -public: - - BuddyAllocator(); - - BuddyAllocator(const MemoryMap& memmap, char* bitmap, size_t blockCount, - size_t treeHeight); - - BuddyAllocator(char* bitmap, size_t blockSize, size_t blockCount, - size_t treeHeight); - - /** - * Allocate a block of memory containing at least 'size' bytes. - * Rounds up to the nearest power of 2 times the size of a block. - */ - virtual physaddr_t allocate(size_t size); - - /** - * Free the region of memory starting at 'location' and containing - * 'size' bytes. - */ - virtual void free(physaddr_t location, size_t size); - - /** - * @returns the total number of free blocks of memory. - */ - virtual size_t freeBlocks() const; - - /** - * @returns the size in blocks of the largest possible allocation that - * will not fail due to lack of memory. - */ - virtual size_t maxAllocationSize() const; - - /** - * @returns the size in bytes of a single block. - */ - virtual size_t getBlockSize() const; - - /** - * @returns the total number of blocks managed by this memory - * allocator. - */ - virtual size_t getMemorySize() const; - -private: - - static const size_t INVALID = (size_t) -1; - - char* bitmap; - - size_t blockSize; - - size_t blockCount; - - size_t treeHeight; - - size_t findFreeBlock(size_t height); - - size_t split(size_t height, size_t index); - - size_t merge(size_t height, size_t index); - - size_t getBuddy(size_t index); - - size_t getParent(size_t index); - - size_t getChild(size_t index); - - physaddr_t nodeToAddress(size_t height, size_t index) const; - - size_t addressToNode(size_t height, physaddr_t location) const; - - void reserveNode(size_t height, size_t index); - - void freeNode(size_t height, size_t index); - - bool isFree(size_t height, size_t index) const; - -}; } diff --git a/src/pageallocatorstack.cpp b/src/pageallocatorstack.cpp new file mode 100644 index 0000000..8425dcd --- /dev/null +++ b/src/pageallocatorstack.cpp @@ -0,0 +1,52 @@ +#include "pageallocatorstack.hpp" +#include "memorytype.hpp" + +using namespace kernelns; + +PageAllocatorStack::PageAllocatorStack(physaddr_t *stackBase, physaddr_t *stackTop, size_t frameSize, const MemoryMap& memoryMap) +{ + m_base = stackBase; + m_top = stackTop; + m_stack = m_base; + for(int i = 0; i < memoryMap.size(); i++) + { + if((MemoryType) memoryMap[i].getType() == MemoryType::Available) + { + for(int j = 0; j < memoryMap[i].getSize() / frameSize; j++) + { + free(memoryMap[i].getLocation() + j * frameSize); + } + } + } +} + +physaddr_t PageAllocatorStack::next() +{ + if(m_stack < m_base) + { + physaddr_t frame = *m_stack; + *m_stack = (physaddr_t) 0; + m_stack++; + return frame; + } + return (physaddr_t) -1; +} + +void PageAllocatorStack::free(physaddr_t location) +{ + if(m_stack > m_top) + { + m_stack--; + *m_stack = location; + } +} + +size_t PageAllocatorStack::freeBlocks() const +{ + return m_base - m_stack; +} + +size_t PageAllocatorStack::getMemorySize() const +{ + return m_totalSize; +} \ No newline at end of file diff --git a/src/pageallocatorstack.hpp b/src/pageallocatorstack.hpp new file mode 100644 index 0000000..f5710ed --- /dev/null +++ b/src/pageallocatorstack.hpp @@ -0,0 +1,34 @@ +#ifndef PAGEALLOCATORSTACK_H +#define PAGEALLOCATORSTACK_H + +#include "pageallocator.hpp" +#include "memorymap.hpp" + +namespace kernelns +{ + +class PageAllocatorStack : public PageAllocator +{ +public: + + PageAllocatorStack(physaddr_t *stackBase, physaddr_t *stackTop, size_t frameSize, const MemoryMap& memoryMap); + + virtual physaddr_t next(); + + virtual void free(physaddr_t location); + + virtual size_t freeBlocks() const; + + virtual size_t getMemorySize() const; + +private: + + size_t m_totalSize; + + physaddr_t *m_stack, *m_base, *m_top; + +}; + +} + +#endif \ No newline at end of file From 603a1a9dccfd540ad47b700997355b050e2bb37a Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Tue, 6 Apr 2021 14:44:45 -0500 Subject: [PATCH 035/109] Turned Scheduler into more generic heap --- src/heap.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++++ src/heap.hpp | 38 +++++++++++++++++++++++ src/scheduler.cpp | 68 ----------------------------------------- src/scheduler.hpp | 37 ---------------------- 4 files changed, 116 insertions(+), 105 deletions(-) create mode 100644 src/heap.cpp create mode 100644 src/heap.hpp delete mode 100644 src/scheduler.cpp delete mode 100644 src/scheduler.hpp diff --git a/src/heap.cpp b/src/heap.cpp new file mode 100644 index 0000000..6ad056c --- /dev/null +++ b/src/heap.cpp @@ -0,0 +1,78 @@ +#include "heap.hpp" + +template +kernelns::Heap::Heap() +{ + +} + +template +kernelns::Heap::Heap(T** array, size_t maxSize) +{ + m_array = array; + m_size = 0; + m_limit = maxSize; +} + +template +T* kernelns::Heap::extractMin() +{ + if(m_size == 0) + return nullptr; + m_size--; + T* p = m_array[0]; + m_array[0] = m_array[m_size]; + heapify(0); + return p; +} + +template +void kernelns::Heap::insert(T* n) +{ + if(m_size == m_limit) // TODO: have insert return status code + return; + size_t i = m_size; + m_size++; + while(i > 0 && *m_array[(i - 1) / 2] > *n) + { + m_array[i] = m_array[(i - 1) / 2]; + i = (i - 1) / 2; + } + m_array[i] = n; +} + +template +void kernelns::Heap::remove(T* n) +{ + for(size_t i = 0; i < m_size; i++) + { + if(m_array[i] == n) + { + m_size--; + m_array[i] = m_array[m_size]; + heapify(i); + break; + } + } +} + +template +void kernelns::Heap::heapify(size_t i) +{ + if(i * 2 + 1 >= m_size) + return; + if (*m_array[i * 2 + 1] <= *m_array[i] && *m_array[i * 2 + 1] <= *m_array[i * 2 + 2]) + { + T buffer = m_array[i]; + m_array[i] = m_array[i * 2 + 1]; + m_array[i * 2 + 1] = buffer; + heapify(i * 2 + 1); + } + else if (*m_array[i * 2 + 2] <= *m_array[i] && *m_array[i * 2 + 2] <= *m_array[i * 2 + 1]) + { + T buffer = m_array[i]; + m_array[i] = m_array[i * 2 + 2]; + m_array[i * 2 + 2] = buffer; + heapify(i * 2 + 2); + } +} \ No newline at end of file diff --git a/src/heap.hpp b/src/heap.hpp new file mode 100644 index 0000000..93af712 --- /dev/null +++ b/src/heap.hpp @@ -0,0 +1,38 @@ +#ifndef SCHEDULER_H +#define SCHEDULER_H + +#include + +#include "process.hpp" + +namespace kernelns +{ + +template +class Heap +{ +public: + + Heap(); + + Heap(T** array, size_t maxSize); + + T* extractMin(); + + void insert(T* n); + + void remove(T* n); + +private: + + void heapify(size_t index); + + T** m_array; + + size_t m_size, m_limit; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/scheduler.cpp b/src/scheduler.cpp deleted file mode 100644 index 57089a1..0000000 --- a/src/scheduler.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "scheduler.hpp" - -kernelns::ProcessQueue::ProcessQueue() -{ - -} - -kernelns::ProcessQueue::ProcessQueue(Process** array) -{ - m_array = array; - m_size = 0; -} - -kernelns::Process* kernelns::ProcessQueue::extractMin() -{ - if(m_size == 0) - return NULL; - m_size--; - Process* p = m_array[0]; - m_array[0] = m_array[m_size]; - heapify(0); - return p; -} - -void kernelns::ProcessQueue::insert(Process* n) -{ - size_t i = m_size; - m_size++; - for(; i > 0 && m_array[(i - 1) / 2]->priority > n->priority; i = (i - 1) / 2) - { - m_array[i] = m_array[(i - 1) / 2]; - } - m_array[i] = n; -} - -void kernelns::ProcessQueue::remove(Process* n) -{ - for(size_t i = 0; i < m_size; i++) - { - if(m_array[i] == n) - { - m_size--; - m_array[i] = m_array[m_size]; - heapify(i); - break; - } - } -} - -void kernelns::ProcessQueue::heapify(size_t i) -{ - if(i * 2 + 1 >= m_size) - return; - if (m_array[i]->priority >= m_array[i * 2 + 1]->priority && m_array[i * 2 + 1]->priority <= m_array[i * 2 + 2]->priority) - { - Process* buffer = m_array[i]; - m_array[i] = m_array[i * 2 + 1]; - m_array[i * 2 + 1] = buffer; - heapify(i * 2 + 1); - } - else if (m_array[i]->priority >= m_array[i * 2 + 2]->priority && m_array[i * 2 + 2]->priority <= m_array[i * 2 + 1]->priority) - { - Process* buffer = m_array[i]; - m_array[i] = m_array[i * 2 + 2]; - m_array[i * 2 + 2] = buffer; - heapify(i * 2 + 2); - } -} \ No newline at end of file diff --git a/src/scheduler.hpp b/src/scheduler.hpp deleted file mode 100644 index c58ee32..0000000 --- a/src/scheduler.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SCHEDULER_H -#define SCHEDULER_H - -#include - -#include "process.hpp" - -namespace kernelns -{ - -class ProcessQueue -{ -public: - - ProcessQueue(); - - ProcessQueue(Process** array); - - Process* extractMin(); - - void insert(Process* n); - - void remove(Process* n); - -private: - - void heapify(size_t index); - - Process** m_array; - - size_t m_size; - -}; - -}; - -#endif \ No newline at end of file From f19fdac44466976384af6f7dc8daf22609f51e96 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Tue, 6 Apr 2021 18:36:49 -0500 Subject: [PATCH 036/109] Moved basic types to their own headers --- src/systypes.hpp | 13 +++---------- src/types/handle.h | 8 ++++++++ src/types/physaddr.h | 15 +++++++++++++++ src/types/status.h | 11 +++++++++++ 4 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 src/types/handle.h create mode 100644 src/types/physaddr.h create mode 100644 src/types/status.h diff --git a/src/systypes.hpp b/src/systypes.hpp index cffce0b..2487de5 100644 --- a/src/systypes.hpp +++ b/src/systypes.hpp @@ -1,15 +1,8 @@ #ifndef SYSTYPES_H #define SYSTYPES_H -#include -#include - -#if defined __i386__ || __arm__ -typedef uint32_t physaddr_t; -#elif defined __x86_64__ || __aarch64__ -typedef uint64_t physaddr_t; -#else -typedef uint64_t physaddr_t; -#endif +#include "types/physaddr.h" +#include "types/status.h" +#include "types/handle.h" #endif diff --git a/src/types/handle.h b/src/types/handle.h new file mode 100644 index 0000000..6444d60 --- /dev/null +++ b/src/types/handle.h @@ -0,0 +1,8 @@ +#ifndef HANDLE_H +#define HANDLE_H + +#include + +typedef uint64_t handle_t; + +#endif \ No newline at end of file diff --git a/src/types/physaddr.h b/src/types/physaddr.h new file mode 100644 index 0000000..5cd2f26 --- /dev/null +++ b/src/types/physaddr.h @@ -0,0 +1,15 @@ +#ifndef PHYSADDR_H +#define PHYSADDR_H + +#include +#include + +#if defined __i386__ || __arm__ +typedef uint32_t physaddr_t; +#elif defined __x86_64__ || __aarch64__ +typedef uint64_t physaddr_t; +#else +typedef uint64_t physaddr_t; +#endif + +#endif \ No newline at end of file diff --git a/src/types/status.h b/src/types/status.h new file mode 100644 index 0000000..3771191 --- /dev/null +++ b/src/types/status.h @@ -0,0 +1,11 @@ +#ifndef STATUS_H +#define STATUS_H + +enum class Status +{ + OK = 0, + BadArgument, + NoMemory +}; + +#endif \ No newline at end of file From 8faf353425646f7fe3e6927788f1a4fb0251bd6b Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 7 Apr 2021 00:16:42 -0500 Subject: [PATCH 037/109] Moved heap template class to header file --- src/heap.cpp | 78 ---------------------------------------------------- src/heap.hpp | 72 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 84 deletions(-) delete mode 100644 src/heap.cpp diff --git a/src/heap.cpp b/src/heap.cpp deleted file mode 100644 index 6ad056c..0000000 --- a/src/heap.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "heap.hpp" - -template -kernelns::Heap::Heap() -{ - -} - -template -kernelns::Heap::Heap(T** array, size_t maxSize) -{ - m_array = array; - m_size = 0; - m_limit = maxSize; -} - -template -T* kernelns::Heap::extractMin() -{ - if(m_size == 0) - return nullptr; - m_size--; - T* p = m_array[0]; - m_array[0] = m_array[m_size]; - heapify(0); - return p; -} - -template -void kernelns::Heap::insert(T* n) -{ - if(m_size == m_limit) // TODO: have insert return status code - return; - size_t i = m_size; - m_size++; - while(i > 0 && *m_array[(i - 1) / 2] > *n) - { - m_array[i] = m_array[(i - 1) / 2]; - i = (i - 1) / 2; - } - m_array[i] = n; -} - -template -void kernelns::Heap::remove(T* n) -{ - for(size_t i = 0; i < m_size; i++) - { - if(m_array[i] == n) - { - m_size--; - m_array[i] = m_array[m_size]; - heapify(i); - break; - } - } -} - -template -void kernelns::Heap::heapify(size_t i) -{ - if(i * 2 + 1 >= m_size) - return; - if (*m_array[i * 2 + 1] <= *m_array[i] && *m_array[i * 2 + 1] <= *m_array[i * 2 + 2]) - { - T buffer = m_array[i]; - m_array[i] = m_array[i * 2 + 1]; - m_array[i * 2 + 1] = buffer; - heapify(i * 2 + 1); - } - else if (*m_array[i * 2 + 2] <= *m_array[i] && *m_array[i * 2 + 2] <= *m_array[i * 2 + 1]) - { - T buffer = m_array[i]; - m_array[i] = m_array[i * 2 + 2]; - m_array[i * 2 + 2] = buffer; - heapify(i * 2 + 2); - } -} \ No newline at end of file diff --git a/src/heap.hpp b/src/heap.hpp index 93af712..cf6b456 100644 --- a/src/heap.hpp +++ b/src/heap.hpp @@ -13,19 +13,79 @@ class Heap { public: - Heap(); + Heap() + { - Heap(T** array, size_t maxSize); + } - T* extractMin(); + Heap(T** array, size_t maxSize) + { + m_array = array; + m_size = 0; + m_limit = maxSize; + } - void insert(T* n); + T* extractMin() + { + if(m_size == 0) + return nullptr; + m_size--; + T* p = m_array[0]; + m_array[0] = m_array[m_size]; + heapify(0); + return p; + } - void remove(T* n); + Status insert(T* n) + { + if(m_size == m_limit) + return Status::NoMemory; + size_t i = m_size; + m_size++; + while(i > 0 && *m_array[(i - 1) / 2] > *n) + { + m_array[i] = m_array[(i - 1) / 2]; + i = (i - 1) / 2; + } + m_array[i] = n; + return Status::OK; + } + + void remove(T* n) + { + for(size_t i = 0; i < m_size; i++) + { + if(m_array[i] == n) + { + m_size--; + m_array[i] = m_array[m_size]; + heapify(i); + break; + } + } + } private: - void heapify(size_t index); + void heapify(size_t index) + { + if(i * 2 + 1 >= m_size) + return; + if (*m_array[i * 2 + 1] <= *m_array[i] && *m_array[i * 2 + 1] <= *m_array[i * 2 + 2]) + { + T buffer = m_array[i]; + m_array[i] = m_array[i * 2 + 1]; + m_array[i * 2 + 1] = buffer; + heapify(i * 2 + 1); + } + else if (*m_array[i * 2 + 2] <= *m_array[i] && *m_array[i * 2 + 2] <= *m_array[i * 2 + 1]) + { + T buffer = m_array[i]; + m_array[i] = m_array[i * 2 + 2]; + m_array[i * 2 + 2] = buffer; + heapify(i * 2 + 2); + } + } T** m_array; From 505213b7dcbc1abecf0e3db6c96561dd2be44332 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 17:37:05 -0500 Subject: [PATCH 038/109] Started writing C headers --- include/kernel.h | 6 +++++ include/priorityqueue.h | 55 ++++++++++++++++++++++++++++++++++++++++ include/process.h | 12 +++++++++ include/types/physaddr.h | 9 +++++++ include/types/status.h | 8 ++++++ 5 files changed, 90 insertions(+) create mode 100644 include/kernel.h create mode 100644 include/priorityqueue.h create mode 100644 include/process.h create mode 100644 include/types/physaddr.h create mode 100644 include/types/status.h diff --git a/include/kernel.h b/include/kernel.h new file mode 100644 index 0000000..1ca0240 --- /dev/null +++ b/include/kernel.h @@ -0,0 +1,6 @@ +#pragma once + +struct kernel_t +{ + +}; \ No newline at end of file diff --git a/include/priorityqueue.h b/include/priorityqueue.h new file mode 100644 index 0000000..f080232 --- /dev/null +++ b/include/priorityqueue.h @@ -0,0 +1,55 @@ +#pragma once + +#include "process.h" +#include + +/** + * @brief + * + */ +struct priority_queue_t +{ + /** + * @brief A pointer to the heap described by this structure. + * + */ + struct process_t **heap; + + /** + * @brief The current number of elements stored in the heap. + * + */ + size_t size; + + /** + * @brief The maximum number of elements that the heap can currently hold. + * + */ + size_t capacity; +}; + +/** + * @brief + * + * @param queue + * @return struct process_t* + */ +struct process_t *extract_min(struct priority_queue_t *queue); + +/** + * @brief + * + * @param queue + * @param process + * @return int + */ +int insert(struct priority_queue_t *queue, struct process_t *process); + +/** + * @brief + * + * @param queue + * @param process + * @return int + */ +int remove(struct priority_queue_t *queue, struct process_t *process); \ No newline at end of file diff --git a/include/process.h b/include/process.h new file mode 100644 index 0000000..be2bdbf --- /dev/null +++ b/include/process.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +struct process_state_t; + +struct process_t +{ + size_t priority; + + struct process_state_t *state; +}; \ No newline at end of file diff --git a/include/types/physaddr.h b/include/types/physaddr.h new file mode 100644 index 0000000..9cf0725 --- /dev/null +++ b/include/types/physaddr.h @@ -0,0 +1,9 @@ +#pragma once + +#if defined __i386__ || __arm__ +typedef uint32_t physaddr_t; +#elif defined __x86_64__ || __aarch64__ +typedef uint64_t physaddr_t; +#else +typedef uint64_t physaddr_t; +#endif \ No newline at end of file diff --git a/include/types/status.h b/include/types/status.h new file mode 100644 index 0000000..3366c8d --- /dev/null +++ b/include/types/status.h @@ -0,0 +1,8 @@ +#pragma once + +enum status_t +{ + S_OK = 0, + S_BAD_SYSCALL, + S_OUT_OF_MEMORY +}; \ No newline at end of file From 8210d25c936748a7895c611b2e22be1a96bd2406 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 17:57:10 -0500 Subject: [PATCH 039/109] Added a C header for a page allocator. --- include/pageallocator.h | 58 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 include/pageallocator.h diff --git a/include/pageallocator.h b/include/pageallocator.h new file mode 100644 index 0000000..63d564c --- /dev/null +++ b/include/pageallocator.h @@ -0,0 +1,58 @@ +#pragma once + +#include "types/physaddr.h" +#include + +/** + * @brief Describes a stack containing the physical addresses of available page + * frames. + * + */ +struct page_stack_t +{ + /** + * @brief The total number of physical pages managed by the system. + * + */ + size_t total_pages; + + /** + * @brief Points to the topmost physical address on the stack. + * + */ + physaddr_t *stack_pointer; + + /** + * @brief Points to the bottom of the stack. + * + */ + physaddr_t *base_pointer; + + /** + * @brief Points to the limit of the stack. The stack cannot grow beyond + * this point. + * + */ + physaddr_t *limit_pointer; +}; + +/** + * @brief Pop the topmost address from the stack and returns that value. + * + * If the stack is empty, this function will instead return a status code. This + * can be identified by testing the least signifigant bits of the return value. + * + * @param stack + * @return physaddr_t + */ +physaddr_t reserve_page(struct page_stack_t *stack); + +/** + * @brief Pushes `location` onto the stack. + * + * If there is no room on the stack, the stack will be unaffected. + * + * @param stack + * @param location + */ +int free_page(struct page_stack_t *stack, physaddr_t location); \ No newline at end of file From 6ee078e6feff82b2480d8034ca833563b3e849f8 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 19:15:37 -0500 Subject: [PATCH 040/109] Added C header for page table management --- include/mmgr.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 include/mmgr.h diff --git a/include/mmgr.h b/include/mmgr.h new file mode 100644 index 0000000..0bc0f53 --- /dev/null +++ b/include/mmgr.h @@ -0,0 +1,38 @@ +#pragma once + +#include "types/physaddr.h" + +/** + * @brief Create a new top-level page table and map the kernel in it. + * + * This function does not load the page table; it only initializes it. + * + * @return physaddr_t + */ +physaddr_t create_address_space(); + +/** + * @brief Load an existing top-level page table + * + * @param table + */ +void load_address_space(physaddr_t table); + +/** + * @brief Maps a single page with the specified flags. + * + * @param page + * @param frame + * @param flags + * @return int + */ +int map_page(void *page, physaddr_t frame, int flags); + +/** + * @brief Unmaps a single page, returning the physical address of the frame it + * pointed to. + * + * @param page + * @return physaddr_t + */ +physaddr_t unmap_page(void *page); \ No newline at end of file From 7c3a40bc47f46f785fce8afae456c640ceb040c2 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 19:15:59 -0500 Subject: [PATCH 041/109] Added declaration for page count function --- include/pageallocator.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/pageallocator.h b/include/pageallocator.h index 63d564c..bccca63 100644 --- a/include/pageallocator.h +++ b/include/pageallocator.h @@ -55,4 +55,12 @@ physaddr_t reserve_page(struct page_stack_t *stack); * @param stack * @param location */ -int free_page(struct page_stack_t *stack, physaddr_t location); \ No newline at end of file +int free_page(struct page_stack_t *stack, physaddr_t location); + +/** + * @brief Computes the number of available pages. + * + * @param stack + * @return size_t + */ +size_t free_page_count(struct page_stack_t *stack); From 327fbc70c66400c18382dd3c188383e1eacfe338 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 19:16:31 -0500 Subject: [PATCH 042/109] Implemented page allocator in C; removed C++. --- src/pageallocator.c | 30 ++++++++++++++++++++++ src/pageallocator.hpp | 43 ------------------------------- src/pageallocatorstack.cpp | 52 -------------------------------------- src/pageallocatorstack.hpp | 34 ------------------------- 4 files changed, 30 insertions(+), 129 deletions(-) create mode 100644 src/pageallocator.c delete mode 100755 src/pageallocator.hpp delete mode 100644 src/pageallocatorstack.cpp delete mode 100644 src/pageallocatorstack.hpp diff --git a/src/pageallocator.c b/src/pageallocator.c new file mode 100644 index 0000000..631e578 --- /dev/null +++ b/src/pageallocator.c @@ -0,0 +1,30 @@ +#include "pageallocator.h" +#include "types/status.h" + +physaddr_t reserve_page(struct page_stack_t *stack) +{ + if(stack->stack_pointer < stack->base_pointer) + { + physaddr_t frame = *stack->stack_pointer; + *stack->stack_pointer = (physaddr_t) 0; + stack->stack_pointer++; + return frame; + } + return S_OUT_OF_MEMORY; +} + +int free_page(struct page_stack_t *stack, physaddr_t location) +{ + if(stack->stack_pointer > stack->limit_pointer) + { + stack->stack_pointer--; + *stack->stack_pointer = location; + return S_OK; + } + return S_OUT_OF_MEMORY; +} + +size_t free_page_count(struct page_stack_t *stack) +{ + return stack->base_pointer - stack->stack_pointer; +} \ No newline at end of file diff --git a/src/pageallocator.hpp b/src/pageallocator.hpp deleted file mode 100755 index 2e600a7..0000000 --- a/src/pageallocator.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __MEMORYALLOCATOR_H_ -#define __MEMORYALLOCATOR_H_ - -#include -#include "systypes.hpp" - -namespace kernelns -{ - -/** - * Interface for a physical memory allocator. - */ -class PageAllocator -{ -public: - - /** - * Allocate a single page, returning its physical address. Upon failure, - * returns an error code such that the least signifigant byte is nonzero. - */ - virtual physaddr_t next() = 0; - - /** - * Frees a single page that has previously been allocated. - */ - virtual void free(physaddr_t location) = 0; - - /** - * @returns the total number of free blocks of memory. - */ - virtual size_t freeBlocks() const = 0; - - /** - * @returns the total number of blocks managed by this memory - * allocator. - */ - virtual size_t getMemorySize() const = 0; - -}; - -} - -#endif diff --git a/src/pageallocatorstack.cpp b/src/pageallocatorstack.cpp deleted file mode 100644 index 8425dcd..0000000 --- a/src/pageallocatorstack.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "pageallocatorstack.hpp" -#include "memorytype.hpp" - -using namespace kernelns; - -PageAllocatorStack::PageAllocatorStack(physaddr_t *stackBase, physaddr_t *stackTop, size_t frameSize, const MemoryMap& memoryMap) -{ - m_base = stackBase; - m_top = stackTop; - m_stack = m_base; - for(int i = 0; i < memoryMap.size(); i++) - { - if((MemoryType) memoryMap[i].getType() == MemoryType::Available) - { - for(int j = 0; j < memoryMap[i].getSize() / frameSize; j++) - { - free(memoryMap[i].getLocation() + j * frameSize); - } - } - } -} - -physaddr_t PageAllocatorStack::next() -{ - if(m_stack < m_base) - { - physaddr_t frame = *m_stack; - *m_stack = (physaddr_t) 0; - m_stack++; - return frame; - } - return (physaddr_t) -1; -} - -void PageAllocatorStack::free(physaddr_t location) -{ - if(m_stack > m_top) - { - m_stack--; - *m_stack = location; - } -} - -size_t PageAllocatorStack::freeBlocks() const -{ - return m_base - m_stack; -} - -size_t PageAllocatorStack::getMemorySize() const -{ - return m_totalSize; -} \ No newline at end of file diff --git a/src/pageallocatorstack.hpp b/src/pageallocatorstack.hpp deleted file mode 100644 index f5710ed..0000000 --- a/src/pageallocatorstack.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef PAGEALLOCATORSTACK_H -#define PAGEALLOCATORSTACK_H - -#include "pageallocator.hpp" -#include "memorymap.hpp" - -namespace kernelns -{ - -class PageAllocatorStack : public PageAllocator -{ -public: - - PageAllocatorStack(physaddr_t *stackBase, physaddr_t *stackTop, size_t frameSize, const MemoryMap& memoryMap); - - virtual physaddr_t next(); - - virtual void free(physaddr_t location); - - virtual size_t freeBlocks() const; - - virtual size_t getMemorySize() const; - -private: - - size_t m_totalSize; - - physaddr_t *m_stack, *m_base, *m_top; - -}; - -} - -#endif \ No newline at end of file From c6a1b8fa2951fc9ee691d10fad05d1319ca55a9e Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 19:41:02 -0500 Subject: [PATCH 043/109] Removed type headers in src/ --- src/systypes.hpp | 8 -------- src/types/handle.h | 8 -------- src/types/physaddr.h | 15 --------------- src/types/status.h | 11 ----------- 4 files changed, 42 deletions(-) delete mode 100644 src/systypes.hpp delete mode 100644 src/types/handle.h delete mode 100644 src/types/physaddr.h delete mode 100644 src/types/status.h diff --git a/src/systypes.hpp b/src/systypes.hpp deleted file mode 100644 index 2487de5..0000000 --- a/src/systypes.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SYSTYPES_H -#define SYSTYPES_H - -#include "types/physaddr.h" -#include "types/status.h" -#include "types/handle.h" - -#endif diff --git a/src/types/handle.h b/src/types/handle.h deleted file mode 100644 index 6444d60..0000000 --- a/src/types/handle.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef HANDLE_H -#define HANDLE_H - -#include - -typedef uint64_t handle_t; - -#endif \ No newline at end of file diff --git a/src/types/physaddr.h b/src/types/physaddr.h deleted file mode 100644 index 5cd2f26..0000000 --- a/src/types/physaddr.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PHYSADDR_H -#define PHYSADDR_H - -#include -#include - -#if defined __i386__ || __arm__ -typedef uint32_t physaddr_t; -#elif defined __x86_64__ || __aarch64__ -typedef uint64_t physaddr_t; -#else -typedef uint64_t physaddr_t; -#endif - -#endif \ No newline at end of file diff --git a/src/types/status.h b/src/types/status.h deleted file mode 100644 index 3771191..0000000 --- a/src/types/status.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef STATUS_H -#define STATUS_H - -enum class Status -{ - OK = 0, - BadArgument, - NoMemory -}; - -#endif \ No newline at end of file From 93d8c06d2f44d1c14bb51609aad4182d59d40107 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 19:41:17 -0500 Subject: [PATCH 044/109] Added out of bounds status enum --- include/types/status.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/types/status.h b/include/types/status.h index 3366c8d..232f39b 100644 --- a/include/types/status.h +++ b/include/types/status.h @@ -4,5 +4,6 @@ enum status_t { S_OK = 0, S_BAD_SYSCALL, - S_OUT_OF_MEMORY + S_OUT_OF_MEMORY, + S_OUT_OF_BOUNDS }; \ No newline at end of file From a57d84108557c249647548e1ac9fb3d449ff9e5c Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 19:42:16 -0500 Subject: [PATCH 045/109] Implemented priority queue in C; removed C++ heap --- include/priorityqueue.h | 2 +- src/heap.hpp | 98 ----------------------------------------- src/priorityqueue.c | 67 ++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 99 deletions(-) delete mode 100644 src/heap.hpp create mode 100644 src/priorityqueue.c diff --git a/include/priorityqueue.h b/include/priorityqueue.h index f080232..85aed7a 100644 --- a/include/priorityqueue.h +++ b/include/priorityqueue.h @@ -52,4 +52,4 @@ int insert(struct priority_queue_t *queue, struct process_t *process); * @param process * @return int */ -int remove(struct priority_queue_t *queue, struct process_t *process); \ No newline at end of file +int remove(struct priority_queue_t *queue, struct process_t *process); diff --git a/src/heap.hpp b/src/heap.hpp deleted file mode 100644 index cf6b456..0000000 --- a/src/heap.hpp +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef SCHEDULER_H -#define SCHEDULER_H - -#include - -#include "process.hpp" - -namespace kernelns -{ - -template -class Heap -{ -public: - - Heap() - { - - } - - Heap(T** array, size_t maxSize) - { - m_array = array; - m_size = 0; - m_limit = maxSize; - } - - T* extractMin() - { - if(m_size == 0) - return nullptr; - m_size--; - T* p = m_array[0]; - m_array[0] = m_array[m_size]; - heapify(0); - return p; - } - - Status insert(T* n) - { - if(m_size == m_limit) - return Status::NoMemory; - size_t i = m_size; - m_size++; - while(i > 0 && *m_array[(i - 1) / 2] > *n) - { - m_array[i] = m_array[(i - 1) / 2]; - i = (i - 1) / 2; - } - m_array[i] = n; - return Status::OK; - } - - void remove(T* n) - { - for(size_t i = 0; i < m_size; i++) - { - if(m_array[i] == n) - { - m_size--; - m_array[i] = m_array[m_size]; - heapify(i); - break; - } - } - } - -private: - - void heapify(size_t index) - { - if(i * 2 + 1 >= m_size) - return; - if (*m_array[i * 2 + 1] <= *m_array[i] && *m_array[i * 2 + 1] <= *m_array[i * 2 + 2]) - { - T buffer = m_array[i]; - m_array[i] = m_array[i * 2 + 1]; - m_array[i * 2 + 1] = buffer; - heapify(i * 2 + 1); - } - else if (*m_array[i * 2 + 2] <= *m_array[i] && *m_array[i * 2 + 2] <= *m_array[i * 2 + 1]) - { - T buffer = m_array[i]; - m_array[i] = m_array[i * 2 + 2]; - m_array[i * 2 + 2] = buffer; - heapify(i * 2 + 2); - } - } - - T** m_array; - - size_t m_size, m_limit; - -}; - -}; - -#endif \ No newline at end of file diff --git a/src/priorityqueue.c b/src/priorityqueue.c new file mode 100644 index 0000000..5ab2873 --- /dev/null +++ b/src/priorityqueue.c @@ -0,0 +1,67 @@ +#include "priorityqueue.h" +#include "types/status.h" + +void heapify(struct priority_queue_t *queue, size_t i) +{ + if(i * 2 + 1 >= queue->size) + { + return; + } + else if(queue->heap[i * 2 + 1]->priority <= queue->heap[i]->priority + && queue->heap[i * 2 + 1]->priority <= queue->heap[i * 2 + 2]->priority) + { + struct process_t *buffer = queue->heap[i]; + queue->heap[i] = queue->heap[i * 2 + 1]; + queue->heap[i * 2 + 1] = buffer; + heapify(queue, i * 2 + 1); + } + else if(queue->heap[i * 2 + 2]->priority <= queue->heap[i]->priority + && queue->heap[i * 2 + 2]->priority <= queue->heap[i * 2 + 1]->priority) + { + struct process_t *buffer = queue->heap[i]; + queue->heap[i] = queue->heap[i * 2 + 2]; + queue->heap[i * 2 + 2] = buffer; + heapify(queue, i * 2 + 2); + } +} + +struct process_t *extract_min(struct priority_queue_t *queue) +{ + if(queue->size == 0) + return NULL; + queue->size--; + struct process_t *p = queue->heap[0]; + queue->heap[0] = queue->heap[queue->size]; + heapify(queue, 0); + return p; +} + +int insert(struct priority_queue_t *queue, struct process_t *process) +{ + if(queue->size == queue->capacity) + return S_OUT_OF_MEMORY; + size_t i = queue->size; + queue->size++; + while(i > 0 && queue->heap[(i - 1) / 2]->priority > process->priority) + { + queue->heap[i] = queue->heap[(i - 1) / 2]; + i = (i - 1) / 2; + } + queue->heap[i] = process; + return S_OK; +} + +int remove(struct priority_queue_t *queue, struct process_t *process) +{ + for(size_t i = 0; i < queue->size; i++) + { + if(queue->heap[i] == process) + { + queue->size--; + queue->heap[i] = queue->heap[queue->size]; + heapify(queue, i); + return S_OK; + } + } + return S_OUT_OF_BOUNDS; +} \ No newline at end of file From 6a4f7773408569fe0620de914249bd28f7c90486 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 20:15:23 -0500 Subject: [PATCH 046/109] Created string.h header; moved code to string.c --- include/string.h | 15 +++++ src/string.c | 110 +++++++++++++++++++++++++++++++ src/util.cpp | 165 ----------------------------------------------- src/util.hpp | 56 ---------------- 4 files changed, 125 insertions(+), 221 deletions(-) create mode 100644 include/string.h create mode 100644 src/string.c delete mode 100644 src/util.cpp delete mode 100644 src/util.hpp diff --git a/include/string.h b/include/string.h new file mode 100644 index 0000000..459eea8 --- /dev/null +++ b/include/string.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +void *memcpy(void *destination, const void *source, size_t num); + +void *memmove(void *destination, const void *source, size_t num); + +int memcmp(const void *ptr1, const void *ptr2, size_t num); + +void *memset(void *ptr, int value, size_t num); + +int strlen(const char *str); + +char *strcpy(char *destination, const char *source); diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..4dd71ab --- /dev/null +++ b/src/string.c @@ -0,0 +1,110 @@ +#include "string.h" +#include +#include + +void *memcpy(void *destination, const void *source, size_t num) +{ + if (num > 0) + { + const uint8_t *src = (const uint8_t *)source; + uint8_t *dest = (uint8_t *)destination; + for (size_t i = 0; i < num; i++) + { + dest[i] = src[i]; + } + } + return destination; +} + +void *memmove(void *destination, const void *source, size_t num) +{ + if (num > 0) + { + if (((size_t)destination) < ((size_t)source) || ((size_t)destination) >= (((size_t)source)) + num) + { + return memcpy(destination, source, num); + } + else if (destination != source) + { + size_t i = num - 1; + const uint8_t *src = (const uint8_t *)source; + uint8_t *dest = (uint8_t *)destination; + do + { + dest[i] = src[i]; + i--; + } while (i != 0); + } + } + return destination; +} + +int memcmp(const void *ptr1, const void *ptr2, size_t num) +{ + const uint8_t *a = (const uint8_t *)ptr1; + const uint8_t *b = (const uint8_t *)ptr2; + for (size_t i = 0; i < num; i++) + { + if (a[i] < b[i]) + return -1; + else if (a[i] > b[i]) + return 1; + } + return 0; +} + +void *memset(void *ptr, int value, size_t num) +{ + uint8_t *dest = (uint8_t *)ptr; + uint8_t v = (uint8_t)value; + for (size_t i = 0; i < num; i++) + { + dest[i] = v; + } + return ptr; +} + +int strlen(const char *str) +{ + int i = 0; + while (str[i] != '\0') + { + i++; + } + return i; +} + +char *strcpy(char *destination, const char *source) +{ + int sourceLen = strlen(source); + if ((destination <= source) || (destination > (source + sourceLen))) + { + char *d = destination; + const char *s = source; + while (true) + { + *d = *s; + if (*s == '\0') + { + break; + } + else + { + s++; + d++; + } + } + } + else + { + char *d = destination + sourceLen; + const char *s = source + sourceLen; + do + { + *d = *s; + d--; + s--; + } while (d > destination); + } + return destination; +} diff --git a/src/util.cpp b/src/util.cpp deleted file mode 100644 index 1256dbc..0000000 --- a/src/util.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include - -#include "util.hpp" -#include "kernel.hpp" - -void* memcpy(void* destination, const void* source, size_t num) -{ - if(num > 0) - { - const uint8_t* src = (const uint8_t*) source; - uint8_t* dest = (uint8_t*) destination; - for(size_t i = 0; i < num; i++) - { - dest[i] = src[i]; - } - } - return destination; -} - -void* memmove(void* destination, const void* source, size_t num) -{ - if(num > 0) - { - if(((size_t) destination) < ((size_t) source) || ((size_t) destination) >= (((size_t) source)) + num) - { - return memcpy(destination, source, num); - } - else if(destination != source) - { - size_t i = num - 1; - const uint8_t* src = (const uint8_t*) source; - uint8_t* dest = (uint8_t*) destination; - do - { - dest[i] = src[i]; - i--; - } while(i != 0); - } - } - return destination; -} - -int memcmp(const void* ptr1, const void* ptr2, size_t num) -{ - const uint8_t* a = (const uint8_t*) ptr1; - const uint8_t* b = (const uint8_t*) ptr2; - for(size_t i = 0; i < num; i++) - { - if(a[i] < b[i]) - return -1; - else if(a[i] > b[i]) - return 1; - } - return 0; -} - -void* memset(void* ptr, int value, size_t num) -{ - uint8_t* dest = (uint8_t*) ptr; - uint8_t v = (uint8_t) value; - for(size_t i = 0; i < num; i++) - { - dest[i] = v; - } - return ptr; -} - -int strlen(const char* str) -{ - int i = 0; - while(str[i] != '\0') - { - i++; - } - return i; -} - -char* strcpy(char* destination, const char* source) -{ - int sourceLen = strlen(source); - if((destination <= source) || (destination > (source + sourceLen))) - { - char* d = destination; - const char* s = source; - while(true) - { - *d = *s; - if(*s == '\0') - { - break; - } - else - { - s++; - d++; - } - } - } - else - { - char* d = destination + sourceLen; - const char* s = source + sourceLen; - do - { - *d = *s; - d--; - s--; - } while(d > destination); - } - return destination; -} - -void* malloc(size_t size) -{ - return kernel.malloc(size); -} - -void* calloc(size_t count, size_t size) -{ - void* ptr = malloc(count * size); - if(ptr != nullptr) - memset(malloc(count * size), 0, count * size); - return ptr; -} - -void* realloc(void* ptr, size_t size) -{ - void* n = kernel.malloc(size); - if(n != nullptr) - { - memmove(n, ptr, size); - free(ptr); - } - return n; -} - -void free(void* p) -{ - kernel.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 deleted file mode 100644 index d82bcf5..0000000 --- a/src/util.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef UTIL_H -#define UTIL_H - -#include - -extern "C" void* memcpy(void* destination, const void* source, size_t num); - -extern "C" void* memmove(void* destination, const void* source, size_t num); - -extern "C" int memcmp(const void* ptr1, const void* ptr2, size_t num); - -extern "C" void* memset(void* ptr, int value, size_t num); - -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* realloc(void* ptr, 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 From 68166e58ca4caf4fbc5022cc6c26158f14293583 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 20:43:01 -0500 Subject: [PATCH 047/109] Implemented C x86 paging, removed C++ code --- include/mmgr.h | 5 +- src/memorymanager.hpp | 55 ------- src/x86/memorymanagerx86.cpp | 31 ---- src/x86/memorymanagerx86.hpp | 29 ---- src/x86/mmap.cpp | 292 ----------------------------------- src/x86/mmgr.c | 121 +++++++++++++++ src/x86/pagetableentry.cpp | 132 ---------------- src/x86/pagetableentry.hpp | 83 ---------- 8 files changed, 124 insertions(+), 624 deletions(-) delete mode 100644 src/memorymanager.hpp delete mode 100644 src/x86/memorymanagerx86.cpp delete mode 100644 src/x86/memorymanagerx86.hpp delete mode 100644 src/x86/mmap.cpp create mode 100644 src/x86/mmgr.c delete mode 100644 src/x86/pagetableentry.cpp delete mode 100644 src/x86/pagetableentry.hpp diff --git a/include/mmgr.h b/include/mmgr.h index 0bc0f53..dc80161 100644 --- a/include/mmgr.h +++ b/include/mmgr.h @@ -1,5 +1,6 @@ #pragma once +#include "pageallocator.h" #include "types/physaddr.h" /** @@ -9,7 +10,7 @@ * * @return physaddr_t */ -physaddr_t create_address_space(); +physaddr_t create_address_space(struct page_stack_t *page_stack); /** * @brief Load an existing top-level page table @@ -26,7 +27,7 @@ void load_address_space(physaddr_t table); * @param flags * @return int */ -int map_page(void *page, physaddr_t frame, int flags); +int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int flags); /** * @brief Unmaps a single page, returning the physical address of the frame it diff --git a/src/memorymanager.hpp b/src/memorymanager.hpp deleted file mode 100644 index 72d8237..0000000 --- a/src/memorymanager.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef MEMORYMANAGER_H -#define MEMORYMANAGER_H - -#include "systypes.hpp" - -class MemoryManager -{ -public: - - /** - * @brief Returns the size of a single page on the present platform. - * - * @return the size in bytes of a single page - */ - virtual unsigned int getPageSize() const = 0; - - /** - * Allocates space for a new top-level page table, and initializes it to - * point only to the kernel's page tables. - * - * @returns the physical address of the new top-level page table - */ - virtual physaddr_t createAddressSpace() = 0; - - /** - * Loads the given top-level page table(s). - * - * @param table the top-level page table to load - */ - virtual void loadAddressSpace(physaddr_t table) = 0; - - /** - * Maps a single page to a single frame. Allocates a new page table if one - * does not exist for that frame. - * - * @param page the virtual address of the page to map - * @param frame the physical address of the frame to map to - * @param flags flags to apply to the entry - * - * @returns zero upon success, nonzero on failure - */ - virtual int mapPage(void* page, physaddr_t frame, int flags) = 0; - - /** - * Deletes the page table entry for the specified page. Does not deallocate - * redundant page tables or modify higher level tables; these are cleaned up - * after the owning process ends. - * - * @param page the virtual address of the page to unmap - */ - virtual physaddr_t unmapPage(void* page) = 0; - -}; - -#endif \ No newline at end of file diff --git a/src/x86/memorymanagerx86.cpp b/src/x86/memorymanagerx86.cpp deleted file mode 100644 index b4aaefc..0000000 --- a/src/x86/memorymanagerx86.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "memorymanagerx86.hpp" - -unsigned int MemoryManagerx86::getPageSize() const -{ - return pageSize; -} - -physaddr_t MemoryManagerx86::createAddressSpace() -{ - if(((size_t) table & 0xFFF) != 0) - return -1; - PageTableEntry* newDirectory = (PageTableEntry*) table; - newDirectory[1022] = m_pageDirectory[1022]; - newDirectory[1023] = m_pageDirectory[1023]; - return 0; -} - -void MemoryManagerx86::loadAddressSpace(physaddr_t table) -{ - -} - -int MemoryManagerx86::mapPage(void *page, physaddr_t frame, int flags) -{ - -} - -physaddr_t MemoryManagerx86::unmapPage(void *page) -{ - -} \ No newline at end of file diff --git a/src/x86/memorymanagerx86.hpp b/src/x86/memorymanagerx86.hpp deleted file mode 100644 index ed3273e..0000000 --- a/src/x86/memorymanagerx86.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef MEMORYMANAGERX86_H -#define MEMORYMANAGERX86_H - -#include "../memorymanager.hpp" -#include "pagetableentry.hpp" - -class MemoryManagerx86 : public MemoryManager -{ -public: - - virtual unsigned int getPageSize() const; - - virtual physaddr_t createAddressSpace(); - - virtual void loadAddressSpace(physaddr_t table); - - virtual int mapPage(void* page, physaddr_t frame, int flags); - - virtual physaddr_t unmapPage(void* page); - -private: - - static const unsigned int pageSize = 4096; - - PageTableEntry *m_pageTables, *m_pageDirectory; - -}; - -#endif \ No newline at end of file diff --git a/src/x86/mmap.cpp b/src/x86/mmap.cpp deleted file mode 100644 index 3cddf3b..0000000 --- a/src/x86/mmap.cpp +++ /dev/null @@ -1,292 +0,0 @@ -#include "../mmap.hpp" -#include "../kernelstate.hpp" - -class PageTableEntry { -public: - - PageTableEntry() - { - this->present = 0; - this->rw = 0; - this->usermode = 0; - this->writeThrough = 0; - this->cacheDisable = 0; - this->accessed = 0; - this->dirty = 0; - this->pat = 0; - this->global = 0; - this->shared = 0; - this->ignored = 0; - this->physicalAddress = 0; - } - - bool getAccessed() const - { - return accessed == 1; - } - - bool getCacheDisable() const - { - return cacheDisable == 1; - } - - void setCacheDisable(bool cacheDisable) - { - this->cacheDisable = cacheDisable ? 1 : 0; - } - - bool getDirty() const - { - return dirty == 1; - } - - bool getGlobal() const - { - return global == 1; - } - - void setGlobal(bool global) - { - this->global = global ? 1 : 0; - } - - bool getPat() const - { - return pat == 1; - } - - void setPat(bool pat) - { - this->pat = pat ? 1 : 0; - } - - physaddr_t getPhysicalAddress() const - { - physaddr_t physicalAddress = this->physicalAddress; - return physicalAddress << 12; - } - - physaddr_t setPhysicalAddress(physaddr_t physicalAddress) - { - this->physicalAddress = physicalAddress >> 12; - return this->physicalAddress << 12; - } - - bool getPresent() const - { - return present == 1; - } - - void setPresent(bool present) - { - this->present = present ? 1 : 0; - } - - bool getRw() const - { - return rw == 1; - } - - void setRw(bool rw) - { - this->rw = rw ? 1 : 0; - } - - bool getShared() const - { - return shared == 1; - } - - void setShared(bool shared) - { - this->shared = shared ? 1 : 0; - } - - bool getUsermode() const - { - return usermode == 1; - } - - void setUsermode(bool usermode) - { - this->usermode = usermode ? 1 : 0; - } - - bool getWriteThrough() const - { - return writeThrough == 1; - } - - void setWriteThrough(bool writeThrough) - { - this->writeThrough = writeThrough ? 1 : 0; - } - - physaddr_t operator=(physaddr_t rhs) - { - return setPhysicalAddress(rhs); - } - - PageTableEntry operator=(PageTableEntry rhs) - { - uint32_t* iThis = (uint32_t*) this; - uint32_t* iThat = (uint32_t*) &rhs; - *iThis = *iThat; - return rhs; - } - -private: - uint32_t present : 1; - uint32_t rw : 1; - uint32_t usermode : 1; - uint32_t writeThrough : 1; - uint32_t cacheDisable : 1; - uint32_t accessed : 1; - uint32_t dirty : 1; - uint32_t pat : 1; - uint32_t global : 1; - uint32_t shared : 1; - uint32_t ignored : 2; - uint32_t physicalAddress : 20; -}; - -int kernelns::mmap(void* start, size_t length, int flags) -{ - if((size_t) start % 4096 != 0) - return -1; - PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; - PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; - size_t tableIndex = (size_t) start / 4096; - for(int i = (int) length; i > 0; i -= 4096) - { - size_t directoryIndex = tableIndex / 1024; - if(!pageDirectory[directoryIndex].getPresent()) - { - physaddr_t newPT = State::pageAllocator.allocate(4096); - if(newPT == 0) - return -1; - pageDirectory[directoryIndex] = newPT; - pageDirectory[directoryIndex].setPresent(true); - pageDirectory[directoryIndex].setUsermode(false); - pageDirectory[directoryIndex].setRw(true); - } - if(!pageTables[tableIndex].getPresent()) - { - physaddr_t page = State::pageAllocator.allocate(4096); - pageTables[tableIndex] = page; - pageTables[tableIndex].setPresent(true); - pageTables[tableIndex].setUsermode(false); - if(flags & MMAP_RW) - pageTables[tableIndex].setRw(true); - } - tableIndex++; - } - return 0; -} - -int kernelns::mmap(void* start, physaddr_t p_start, size_t length, int flags) -{ - if((size_t) start % 4096 != 0 || p_start % 4096 != 0) - return -1; - physaddr_t page = p_start; - for(int i = (int) length; i > 0; i -= 4096) - { - if(mapPage(start, page, flags) != 0) - return -1; - page += 4096; - } - return 0; -} - -int kernelns::mapPage(void* start, physaddr_t p_start, int flags) -{ - if((size_t) start % 4096 != 0 || p_start % 4096 != 0) - return -1; - PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; - PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; - size_t tableIndex = (size_t) start / 4096; - physaddr_t page = p_start; - size_t directoryIndex = tableIndex / 1024; - if(!pageDirectory[directoryIndex].getPresent()) - { - physaddr_t newPT = State::pageAllocator.allocate(4096); - if(newPT == 0) - return -1; - pageDirectory[directoryIndex] = newPT; - pageDirectory[directoryIndex].setPresent(true); - pageDirectory[directoryIndex].setUsermode(false); - pageDirectory[directoryIndex].setRw(true); - } - if(!pageTables[tableIndex].getPresent()) - { - pageTables[tableIndex] = page; - pageTables[tableIndex].setPresent(true); - pageTables[tableIndex].setUsermode(false); - if(flags & MMAP_RW) - pageTables[tableIndex].setRw(true); - } - return 0; -} - -int kernelns::munmap(void* start, size_t length) -{ - if((size_t) start % 4096 != 0) - return -1; - PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; - PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; - size_t tableIndex = (size_t) start / 4096; - for(int i = (int) length; i > 0; i -= 4096) - { - size_t directoryIndex = tableIndex / 1024; - if(pageDirectory[directoryIndex].getPresent()) - { - pageTables[tableIndex] = 0; - pageTables[tableIndex].setPresent(false); - pageTables[tableIndex].setUsermode(false); - pageTables[tableIndex].setRw(false); - } - tableIndex++; - } - return 0; -} - -bool kernelns::isMapped(void* addr) -{ - PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; - size_t tableIndex = (size_t) addr / 4096; - size_t directoryIndex = tableIndex / 1024; - if(pageDirectory[directoryIndex].getPresent()) - { - PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; - return pageTables[tableIndex].getPresent(); - } - return false; -} - -physaddr_t kernelns::getPhysicalAddress(void* addr) -{ - PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; - size_t tableIndex = (size_t) addr / 4096; - return pageTables[tableIndex].getPhysicalAddress() + ((size_t) addr & 0xFFF); -} - -int kernelns::createAddressSpace(void* table) -{ - if(((size_t) table & 0xFFF) != 0) - return -1; - PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; - PageTableEntry* newDirectory = (PageTableEntry*) table; - newDirectory[1022] = pageDirectory[1022]; - newDirectory[1023] = pageDirectory[1023]; - return 0; -} - -int kernelns::loadAddressSpace(physaddr_t table) -{ - if((table & 0xFFF) != 0) - return -1; - asm("mov %0, %%cr3" - : - : "r" (table)); - return 0; -} \ No newline at end of file diff --git a/src/x86/mmgr.c b/src/x86/mmgr.c new file mode 100644 index 0000000..80ce59e --- /dev/null +++ b/src/x86/mmgr.c @@ -0,0 +1,121 @@ +#include "mmgr.h" +#include "pageallocator.h" +#include "string.h" +#include "types/status.h" +#include + +const size_t page_size = 4096; + +const size_t page_bits = 12; + +struct page_table_entry_t +{ + uint32_t present : 1; + + uint32_t rw : 1; + + uint32_t usermode : 1; + + uint32_t writeThrough : 1; + + uint32_t cacheDisable : 1; + + uint32_t accessed : 1; + + uint32_t dirty : 1; + + uint32_t pat : 1; + + uint32_t global : 1; + + uint32_t shared : 1; + + uint32_t ignored : 2; + + uint32_t physicalAddress : 20; +}; + +struct page_table_entry_t *page_tables = (struct page_table_entry_t*) 0xFFC00000; + +struct page_table_entry_t *page_directory = (struct page_table_entry_t*) 0xFFFFF000; + +physaddr_t create_address_space(struct page_stack_t *page_stack) +{ + physaddr_t table = reserve_page(page_stack); + if(table == S_OUT_OF_MEMORY) + { + return S_OUT_OF_MEMORY; + } + struct page_table_entry_t buffer = page_directory[0]; + page_directory[0] = table; + asm volatile("invlpg $0xFFC00000" ::: "memory"); + memset((void*) page_tables, 0, 1022 * 4); + page_tables[1022] = page_directory[1022]; + page_tables[1023] = page_directory[1023]; + page_directory[0] = buffer; + asm volatile("invlpg $0xFFC00000" ::: "memory"); + return table; +} + +void load_address_space(physaddr_t table) +{ + asm volatile("mov %0, %%cr3" + : + : "r" (table) + : "memory"); +} + +int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int flags) +{ + if((size_t) page % page_size != 0 || frame % page_size != 0) + { + return S_OUT_OF_BOUNDS; + } + size_t table_index = (size_t) page / page_size; + size_t directory_index = table_index / (page_size / sizeof(struct page_table_entry_t)); + if(!page_directory[directory_index].present) + { + physaddr_t new_table = reserve_page(page_stack); + if(new_table == S_OUT_OF_MEMORY) + { + return S_OUT_OF_MEMORY; + } + page_directory[directory_index] = new_table >> page_bits; + page_directory[directory_index].present = 1; + page_directory[directory_index].usermode = 0; + page_directory[directory_index].rw = 1; + } + page_tables[table_index] = frame >> 12; + page_tables[table_index].present = 1; + page_tables[table_index].usermode = 1; + page_tables[table_index].rw = 1; + asm volatile("invlpg (%0)" + : + : "r" (page) + : "memory"); + return S_OK; +} + +physaddr_t unmap_page(void *page) +{ + if((size_t) page % page_size != 0) + { + return S_OUT_OF_BOUNDS; + } + size_t table_index = (size_t) page / page_size; + size_t directory_index = table_index / (page_size / sizeof(struct page_table_entry_t)); + if(!page_directory[directory_index].present || !page_tables[table_index].present) + { + return S_OUT_OF_BOUNDS; + } + else + { + physaddr_t frame = page_tables[table_index].physicalAddress << page_bits; + memset(&page_tables[table_index], 0, sizeof(struct page_table_entry_t)); + asm volatile("invlpg (%0)" + : + : "r" (page) + : "memory"); + return frame; + } +} \ No newline at end of file diff --git a/src/x86/pagetableentry.cpp b/src/x86/pagetableentry.cpp deleted file mode 100644 index 5e50799..0000000 --- a/src/x86/pagetableentry.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "pagetableentry.hpp" - -PageTableEntry::PageTableEntry() -{ - this->present = 0; - this->rw = 0; - this->usermode = 0; - this->writeThrough = 0; - this->cacheDisable = 0; - this->accessed = 0; - this->dirty = 0; - this->pat = 0; - this->global = 0; - this->shared = 0; - this->ignored = 0; - this->physicalAddress = 0; -} - -bool PageTableEntry::getAccessed() const -{ - return accessed == 1; -} - -bool PageTableEntry::getCacheDisable() const -{ - return cacheDisable == 1; -} - -void PageTableEntry::setCacheDisable(bool cacheDisable) -{ - this->cacheDisable = cacheDisable ? 1 : 0; -} - -bool PageTableEntry::getDirty() const -{ - return dirty == 1; -} - -bool PageTableEntry::getGlobal() const -{ - return global == 1; -} - -void PageTableEntry::setGlobal(bool global) -{ - this->global = global ? 1 : 0; -} - -bool PageTableEntry::getPat() const -{ - return pat == 1; -} - -void PageTableEntry::setPat(bool pat) -{ - this->pat = pat ? 1 : 0; -} - -physaddr_t PageTableEntry::getPhysicalAddress() const -{ - physaddr_t physicalAddress = this->physicalAddress; - return physicalAddress << 12; -} - -physaddr_t PageTableEntry::setPhysicalAddress(physaddr_t physicalAddress) -{ - this->physicalAddress = physicalAddress >> 12; - return this->physicalAddress << 12; -} - -bool PageTableEntry::getPresent() const -{ - return present == 1; -} - -void PageTableEntry::setPresent(bool present) -{ - this->present = present ? 1 : 0; -} - -bool PageTableEntry::getRw() const -{ - return rw == 1; -} - -void PageTableEntry::setRw(bool rw) -{ - this->rw = rw ? 1 : 0; -} - -bool PageTableEntry::getShared() const -{ - return shared == 1; -} - -void PageTableEntry::setShared(bool shared) -{ - this->shared = shared ? 1 : 0; -} - -bool PageTableEntry::getUsermode() const -{ - return usermode == 1; -} - -void PageTableEntry::setUsermode(bool usermode) -{ - this->usermode = usermode ? 1 : 0; -} - -bool PageTableEntry::getWriteThrough() const -{ - return writeThrough == 1; -} - -void PageTableEntry::setWriteThrough(bool writeThrough) -{ - this->writeThrough = writeThrough ? 1 : 0; -} - -physaddr_t PageTableEntry::operator=(physaddr_t rhs) -{ - return setPhysicalAddress(rhs); -} - -PageTableEntry PageTableEntry::operator=(PageTableEntry rhs) -{ - uint32_t *iThis = (uint32_t *)this; - uint32_t *iThat = (uint32_t *)&rhs; - *iThis = *iThat; - return rhs; -} \ No newline at end of file diff --git a/src/x86/pagetableentry.hpp b/src/x86/pagetableentry.hpp deleted file mode 100644 index 1a5381c..0000000 --- a/src/x86/pagetableentry.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef PAGETABLEENTRY_H -#define PAGETABLEENTRY_H - -#include "../systypes.hpp" - -class PageTableEntry { -public: - - PageTableEntry(); - - bool getAccessed() const; - - bool getCacheDisable() const; - - void setCacheDisable(bool cacheDisable); - - bool getDirty() const; - - bool getGlobal() const; - - void setGlobal(bool global); - - bool getPat() const; - - void setPat(bool pat); - - physaddr_t getPhysicalAddress() const; - - physaddr_t setPhysicalAddress(physaddr_t physicalAddress); - - bool getPresent() const; - - void setPresent(bool present); - - bool getRw() const; - - void setRw(bool rw); - - bool getShared() const; - - void setShared(bool shared); - - bool getUsermode() const; - - void setUsermode(bool usermode); - - bool getWriteThrough() const; - - void setWriteThrough(bool writeThrough); - - physaddr_t operator=(physaddr_t rhs); - - PageTableEntry operator=(PageTableEntry rhs); - -private: - - uint32_t present : 1; - - uint32_t rw : 1; - - uint32_t usermode : 1; - - uint32_t writeThrough : 1; - - uint32_t cacheDisable : 1; - - uint32_t accessed : 1; - - uint32_t dirty : 1; - - uint32_t pat : 1; - - uint32_t global : 1; - - uint32_t shared : 1; - - uint32_t ignored : 2; - - uint32_t physicalAddress : 20; - -}; - -#endif \ No newline at end of file From 62a0bb2d5797d9e3230de01ab01b098f863369b8 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 20:46:02 -0500 Subject: [PATCH 048/109] Removed some useless C++ files --- src/mmap.hpp | 31 ------------------------------- src/module.cpp | 39 --------------------------------------- src/module.hpp | 39 --------------------------------------- src/sharedblock.hpp | 18 ------------------ 4 files changed, 127 deletions(-) delete mode 100644 src/mmap.hpp delete mode 100644 src/module.cpp delete mode 100644 src/module.hpp delete mode 100644 src/sharedblock.hpp diff --git a/src/mmap.hpp b/src/mmap.hpp deleted file mode 100644 index 0e91955..0000000 --- a/src/mmap.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef MMAP_H -#define MMAP_H - -#include "pageallocator.hpp" - -#define MMAP_RW 0x01 -#define MMAP_EXEC 0x02 -#define MMAP_SHARED 0x04 - -namespace kernelns -{ - -int mmap(void* start, size_t length, int flags); - -int mmap(void* start, physaddr_t p_start, size_t length, int flags); - -int mapPage(void* start, physaddr_t p_start, int flags); - -int munmap(void* start, size_t length); - -bool isMapped(void* addr); - -physaddr_t getPhysicalAddress(void* addr); - -int createAddressSpace(void* table); - -int loadAddressSpace(physaddr_t table); - -} - -#endif \ No newline at end of file diff --git a/src/module.cpp b/src/module.cpp deleted file mode 100644 index 08ae855..0000000 --- a/src/module.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "module.hpp" -#include "util.hpp" - -using namespace kernelns; - -Module::Module() -{ - m_start = 0; - m_end = 0; - m_command = NULL; -} - -Module::Module(physaddr_t start, physaddr_t end, const char* command) -{ - m_start = start; - m_end = end; - m_command = new char[strlen(command) + 1]; - strcpy(m_command, command); -} - -Module::~Module() -{ - delete[] m_command; -} - -physaddr_t Module::getStart() const -{ - return m_start; -} - -physaddr_t Module::getEnd() const -{ - 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 deleted file mode 100644 index 2d3b024..0000000 --- a/src/module.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef ELF_H -#define ELF_H - -#include - -#include "systypes.hpp" - -namespace kernelns -{ - -class Module -{ -public: - - Module(); - - Module(physaddr_t start, physaddr_t end, const char* command); - - ~Module(); - - physaddr_t getStart() const; - - physaddr_t getEnd() const; - - const char* getCommand() const; - -private: - - physaddr_t m_start; - - physaddr_t m_end; - - char* m_command; - -}; - -} - -#endif \ No newline at end of file diff --git a/src/sharedblock.hpp b/src/sharedblock.hpp deleted file mode 100644 index e9fe3d6..0000000 --- a/src/sharedblock.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef SHAREDBLOCK_H -#define SHAREDBLOCK_H - -#include "memoryregion.hpp" - -class SharedBlock : public MemoryRegion -{ -public: - - unsigned int getFlags() const; - -private: - - unsigned int m_flags; - -}; - -#endif \ No newline at end of file From 1661abee7926c119d569988b2e3d92197de03a0f Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 21:13:15 -0500 Subject: [PATCH 049/109] Removed more useless C++ files --- src/message.cpp | 38 ------------------------------- src/message.hpp | 59 ------------------------------------------------- 2 files changed, 97 deletions(-) delete mode 100644 src/message.cpp delete mode 100644 src/message.hpp diff --git a/src/message.cpp b/src/message.cpp deleted file mode 100644 index 2f503d5..0000000 --- a/src/message.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "message.hpp" - -Message::Message() -{ - m_sender = 0; - m_type = 0; - m_args[0] = 0; - m_args[1] = 0; - m_args[2] = 0; -} - -Message::Message(const Message& copy) -{ - m_sender = copy.m_sender; - m_type = copy.m_type; - m_args[0] = copy.m_args[0]; - m_args[1] = copy.m_args[1]; - m_args[2] = copy.m_args[2]; -} - -Message::Message(unsigned int sender, unsigned int type, - unsigned long arg1, unsigned long arg2, unsigned long arg3) -{ - m_sender = sender; - m_type = type; - m_args[0] = arg1; - m_args[1] = arg2; - m_args[2] = arg3; -} - -Message& Message::operator=(const Message& rhs) -{ - m_sender = rhs.m_sender; - m_type = rhs.m_type; - m_args[0] = rhs.m_args[0]; - m_args[1] = rhs.m_args[1]; - m_args[2] = rhs.m_args[2]; -} \ No newline at end of file diff --git a/src/message.hpp b/src/message.hpp deleted file mode 100644 index 0702b1e..0000000 --- a/src/message.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef MESSAGE_H -#define MESSAGE_H - -struct Message -{ - - /** - * @brief Default constructor. Initializes all members to 0. - * - */ - Message(); - - /** - * @brief Copy constructor. - * - * @param copy - */ - Message(const Message& copy); - - /** - * @brief Construct a new Message object. - * - * @param sender - * @param type - * @param arg1 - * @param arg2 - * @param arg3 - */ - Message(unsigned int sender, unsigned int type, - unsigned long arg1, unsigned long arg2, unsigned long arg3); - - /** - * @brief Copy the contents of `rhs` to this object. - * - * @param rhs - * @return Message& - */ - Message& operator=(const Message& rhs); - - /** - * @brief PID of the process that generated this message. - */ - unsigned int m_sender; - - /** - * @brief Context-specific parameter which indicates to the receiver how - * the arguments are to be interpreted. - */ - unsigned int m_type; - - /** - * @brief Arguments of this message. The meaning of these values depend on - * context, as well as the values of `m_sender` and `m_type`. - */ - unsigned long m_args[3]; - -}; - -#endif \ No newline at end of file From 1f4fb5dd0bb845c7ad9fe66748e5825df8af93a4 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 21:13:58 -0500 Subject: [PATCH 050/109] Removed old unused source file --- src/x86/interrupts.cpp | 169 ----------------------------------------- 1 file changed, 169 deletions(-) delete mode 100644 src/x86/interrupts.cpp diff --git a/src/x86/interrupts.cpp b/src/x86/interrupts.cpp deleted file mode 100644 index 6eda16d..0000000 --- a/src/x86/interrupts.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "../interrupts.hpp" - -#include -#include - -class InterruptDescriptor -{ -public: - - enum Type - { - TASK32 = 5, - TRAP32 = 15, - INT32 = 14, - TRAP16 = 7, - INT16 = 6 - }; - - InterruptDescriptor() - { - this->m_offset1 = 0; - this->m_selector = 0; - this->m_zero = 0; - this->m_type = 0; - this->m_storage = 0; - this->m_dpl = 0; - this->m_present = 0; - this->m_offset2 = 0; - } - - InterruptDescriptor(void* handler, Type type, unsigned int dpl) - { - uint32_t offset = (uint32_t) handler; - this->m_offset1 = (uint16_t) offset; - this->m_selector = 8; - this->m_zero = 0; - this->m_type = (uint16_t) type; - this->m_storage = 0; - this->m_dpl = dpl; - this->m_present = 1; - this->m_offset2 = offset >> 16; - } - - bool present() - { - return m_present == 1; - } - - void present(bool present) - { - m_present = present ? 1 : 0; - } - - Type type() - { - return (Type) m_type; - } - - void type(Type type) - { - m_type = (unsigned int) type; - } - - unsigned int dpl() - { - return m_dpl; - } - - void dpl(unsigned int dpl) - { - m_dpl = dpl; - } - - void* operator=(void* rhs) - { - uint32_t offset = (uint32_t) rhs; - m_offset1 = (uint16_t) offset; - m_offset2 = (offset >> 16); - return rhs; - } - -private: - - uint16_t m_offset1; - uint16_t m_selector; - uint16_t m_zero : 8; - uint16_t m_type : 4; - uint16_t m_storage : 1; - uint16_t m_dpl : 2; - uint16_t m_present : 1; - uint16_t m_offset2; - -}; - -struct IDTInfo -{ - uint16_t size; - void* location; -}; - -InterruptDescriptor idt[256]; - -void lidt() -{ - IDTInfo idtInfo; - idtInfo.size = sizeof(idt) - 1; - idtInfo.location = (void*) &idt; - asm("lidt (%0)" - : - : "r" (&idtInfo)); -} - -__attribute__ ((interrupt)) -void divisionByZero(void* frame) -{ - -} - -__attribute__ ((interrupt)) -void gpFaultHandler(void* frame, unsigned int error) -{ - -} - -__attribute__ ((interrupt)) -void pageFaultHandler(void* frame, unsigned int error) -{ - -} - -__attribute__ ((interrupt)) -void doubleFaultHandler(void* frame, unsigned int error) -{ - asm("hlt"); -} - -__attribute__ ((interrupt)) -void syscallHandler(void* frame) -{ - -} - -kernelns::Interrupts::Interrupts() -{ - for(unsigned int i = 0; i <= MAX_SYSCALL_ID; i++) - syscalls[i] = (void*) NULL; - idt[0] = InterruptDescriptor((void*) &divisionByZero, InterruptDescriptor::INT32, 0); - idt[8] = InterruptDescriptor((void*) &doubleFaultHandler, InterruptDescriptor::INT32, 0); - idt[0x80] = InterruptDescriptor((void*) &syscallHandler, InterruptDescriptor::INT32, 0); - // Load interrupt handlers - // Configure PIC - lidt(); -} - -void kernelns::Interrupts::enable() -{ - asm("sti"); -} - -void kernelns::Interrupts::disable() -{ - asm("cli"); -} - -void kernelns::Interrupts::addSyscall(unsigned int id, void* function) -{ - if(id <= MAX_SYSCALL_ID) - syscalls[id] = function; -} \ No newline at end of file From 557f3194ed907b626a89a98b12523952b5114369 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 21:15:32 -0500 Subject: [PATCH 051/109] Reduced number of statically allocated page tables --- src/x86/entry.S | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/x86/entry.S b/src/x86/entry.S index fd6c079..6ec1c8b 100755 --- a/src/x86/entry.S +++ b/src/x86/entry.S @@ -124,7 +124,7 @@ _tempPgDir: _tempIdentityMap: .skip 4096 _tempPgTable: -.skip 8192 +.skip 4096 _bootCmdLine: .skip 64 @@ -143,6 +143,9 @@ memory_map: .global _start .type _start, @function _start: + + cli + # This platform reqires a Multiboot2 bootloader. cmp $0x36d76289, %eax jne .err @@ -212,12 +215,6 @@ _start: push %ebx call initialize - # mov $_bootCmdLine, %eax - # push %eax - - # Call main function - # call main - .err: cli 2: hlt From 7fc6c40c5428683f9dbe8a03fc786a82eb388883 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sun, 11 Apr 2021 04:04:09 -0500 Subject: [PATCH 052/109] Wrote memory map in C, removed C++ code --- include/memorymap.h | 20 +++++ src/memorymap.c | 131 ++++++++++++++++++++++++++++++++ src/memorymap.cpp | 172 ------------------------------------------- src/memorymap.hpp | 152 -------------------------------------- src/memoryregion.cpp | 128 -------------------------------- src/memoryregion.hpp | 87 ---------------------- 6 files changed, 151 insertions(+), 539 deletions(-) create mode 100644 include/memorymap.h create mode 100644 src/memorymap.c delete mode 100644 src/memorymap.cpp delete mode 100644 src/memorymap.hpp delete mode 100644 src/memoryregion.cpp delete mode 100644 src/memoryregion.hpp diff --git a/include/memorymap.h b/include/memorymap.h new file mode 100644 index 0000000..e33eb40 --- /dev/null +++ b/include/memorymap.h @@ -0,0 +1,20 @@ +#pragma once + +#include "types/physaddr.h" +#include + +struct memory_region_t +{ + physaddr_t location; + size_t size; + unsigned int type; +}; + +struct memory_map_t +{ + struct memory_region_t *array; + size_t size; + size_t capacity; +}; + +void insert_region(struct memory_map_t *map, physaddr_t location, size_t size, unsigned int type); \ No newline at end of file diff --git a/src/memorymap.c b/src/memorymap.c new file mode 100644 index 0000000..5bc6864 --- /dev/null +++ b/src/memorymap.c @@ -0,0 +1,131 @@ +#include "memorymap.h" +#include + +int compare_regions(struct memory_region_t *lhs, struct memory_region_t *rhs) +{ + if(lhs->location == rhs->location) + { + return lhs->size - rhs->size; + } + else + { + return lhs->location - rhs->location; + } +} + +bool region_overlaps(struct memory_region_t *lhs, struct memory_region_t *rhs) +{ + if(rhs->location < lhs->location) + { + return rhs->location + rhs->size > lhs->location; + } + return rhs->location < lhs->location + lhs->size; +} + +bool region_contains(struct memory_region_t *lhs, struct memory_region_t *rhs) +{ + return (rhs->location >= lhs->location) && + (rhs->location + rhs->size <= lhs->location + lhs->size); +} + +void insert_map_entry(struct memory_map_t *map, physaddr_t location, size_t size, unsigned int type) +{ + struct memory_region_t new_region = {.location = location, .size = size, .type = type}; + unsigned int i = 0; + while(i < map->size) + { + if(compare_regions(&new_region, &map->array[i]) < 0) + { + struct memory_region_t buffer = new_region; + new_region = map->array[i]; + map->array[i] = buffer; + } + i++; + } + map->array[i] = new_region; + map->size++; +} + +void remove_map_entry(struct memory_map_t *map, int index) +{ + if(index >= 0 && index < map->size) + { + for(int i = index; i < map->size - 1; i++) + { + map->array[i] = map->array[i + 1]; + } + map->size--; + } +} + +int trim_map(struct memory_map_t *map, int index) +{ + if(index + 1 >= map->size) + { + return -1; + } + struct memory_region_t left = map->array[index]; + struct memory_region_t right = map->array[index + 1]; + if(region_overlaps(&left, &right)) + { + if(left.type == right.type) + { + left.size = (right.location + right.size > left.location + left.size ? right.location + right.size : left.location + left.size) - left.location; + remove_map_entry(map, index + 1); + return index; + } + else if(left.type < right.type) + { + if(region_contains(&right, &left)) + { + remove_map_entry(map, index); + return index; + } + else if(left.location + left.size <= right.location + right.size) + { + left.size = (right.location > left.location) ? right.location - left.location : 0; + return index + 1; + } + else + { + struct memory_region_t new_right = {.location = right.location + right.size, .size = (left.location + left.size) - (right.location + right.size), .type = left.type}; + left.size = (right.location > left.location) ? right.location - left.location : 0; + if(left.size == 0) + remove_map_entry(map, index); + insert_map_entry(map, new_right.location, new_right.size, new_right.type); + return index + 2; + } + } + else + { + if(region_contains(&left, &right)) + { + remove_map_entry(map, index + 1); + return index; + } + else + { + right.size = (right.location + right.size) - (left.location + left.size); + right.location = left.location + left.size; + return index + 1; + } + } + } + else if((left.location + left.size == right.location) && left.type == right.type) + { + left.size = right.location + right.size - left.location; + remove_map_entry(map, index + 1); + return index; + } + return index + 1; +} + +void insert_region(struct memory_map_t *map, physaddr_t location, size_t size, unsigned int type) +{ + insert_map_entry(map, location, size, type); + unsigned int i = 0; + while(i >= 0) + { + i = trim_map(map, i); + } +} \ No newline at end of file diff --git a/src/memorymap.cpp b/src/memorymap.cpp deleted file mode 100644 index e1b21e9..0000000 --- a/src/memorymap.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include "memorymap.hpp" - -using namespace kernelns; - -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 MemoryRegion& MemoryMap::operator[](size_t index) const -{ - return m_map[index]; -} - -size_t MemoryMap::size() const -{ - return m_entries; -} - -size_t MemoryMap::totalMemory() const -{ - size_t sum = 0; - for(int i = 0; i < m_entries; i++) - { - sum += m_map[i].getSize(); - } - return sum; -} - -size_t MemoryMap::totalMemory(unsigned int type) const -{ - size_t sum = 0; - for(int i = 0; i < m_entries; i++) - { - if(m_map[i].getType() == type) - sum += m_map[i].getSize(); - } - return sum; -} - -bool MemoryMap::overlaps(const MemoryRegion& region) const -{ - for(int i = 0; i < m_entries; i++) - { - if(m_map[i].overlaps(region)) - return true; - } - return false; -} - -bool MemoryMap::contains(const MemoryRegion& region) const -{ - for(int i = 0; i < m_entries; i++) - { - if(m_map[i].contains(region) && m_map[i].getType() == region.getType()) - return true; - } - return false; -} - -void MemoryMap::insertEntry(const MemoryRegion& region) -{ - simpleInsert(region); - unsigned int i = 0; - while(i != invalidIndex) - i = trim(i); -} - -void MemoryMap::insertEntry(physaddr_t location, size_t size, unsigned int type) -{ - insertEntry(MemoryRegion(location, size, type)); -} - -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--; -} - -void MemoryMap::simpleInsert(const MemoryRegion& region) -{ - MemoryRegion newRegion(region); - unsigned int i = 0; - while(i < m_entries) - { - if(newRegion < m_map[i]) - { - MemoryRegion buffer = newRegion; - newRegion = m_map[i]; - m_map[i] = buffer; - } - i++; - } - m_map[i] = newRegion; - m_entries++; -} - -void MemoryMap::simpleInsert(physaddr_t location, size_t size, unsigned int type) -{ - simpleInsert(MemoryRegion(location, size, type)); -} - -unsigned int MemoryMap::trim(unsigned int index) -{ - if(index + 1 >= m_entries) - return invalidIndex; - MemoryRegion& left = m_map[index]; - MemoryRegion& right = m_map[index+1]; - if(left.overlaps(right)) - { - if(left.getType() == right.getType()) - { - left = MemoryRegion(left.getLocation(), - (right.getEnd() > left.getEnd() ? right.getEnd() : left.getEnd()) - left.getLocation(), - left.getType()); - remove(index + 1); - return index; - } - else if(left.getType() < right.getType()) - { - if(right.contains(left)) - { - remove(index); - return index; - } - else if(left.getEnd() <= right.getEnd()) - { - left.truncateRight(right.getLocation()); - return index + 1; - } - else - { - MemoryRegion newRight(right.getEnd(), left.getEnd() - right.getEnd(), left.getType()); - left.truncateRight(right.getLocation()); - if(left.getSize() == 0) - remove(index); - simpleInsert(newRight); - return index + 2; - } - } - else - { - if(left.contains(right)) - { - remove(index + 1); - return index; - } - else - { - right.truncateLeft(left.getEnd()); - return index + 1; - } - } - } - else if(left.bordersLeft(right) && left.getType() == right.getType()) - { - left = MemoryRegion(left.getLocation(), right.getEnd() - left.getLocation(), left.getType()); - remove(index + 1); - return index; - } - return index + 1; -} \ No newline at end of file diff --git a/src/memorymap.hpp b/src/memorymap.hpp deleted file mode 100644 index 6c428af..0000000 --- a/src/memorymap.hpp +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef MEMORYMAP_H -#define MEMORYMAP_H - -#include "systypes.hpp" -#include "memoryregion.hpp" - -namespace kernelns -{ - -class MemoryMap -{ -public: - - MemoryMap(); - - MemoryMap(MemoryMap& copy); - - const MemoryRegion& operator[](size_t index) const; - - /** - * @return The number of memory regions described by this object - */ - size_t size() const; - - /** - * @brief Get the total amount of memory described by this memory map. - * Since no two regions may overlap, this is equivalent to the sum of the - * size of each memory region stored in this object. - * - * @return The total amount of memory described by this memory map. - */ - size_t totalMemory() const; - - /** - * @brief Get the total amount of memory of a specified type described by - * this memory map. Since no two regions overlap, this is equivalent to the - * sum of the size of each memory region stored in this object whose type - * is equal to `type`. - * - * @param type The type of memory region to count - * @return The total amount of memory of the specified type - */ - size_t totalMemory(unsigned int type) const; - - /** - * @brief Checks if `region` overlaps any memory region contained in this - * memory map. - * - * @param region - * @return true if, for any region `k` in this map, `k.overlaps(region)`. - * @return false if there is no region in this map where `k.overlaps(region)`. - */ - bool overlaps(const MemoryRegion& region) const; - - /** - * @brief Checks if `region` is contained an any memory region in this map - * with the same type as `region`. - * - * @param region - * @return true if, for any region `k` in this map, `k.contains(region) - * && k.getType() == region.getType()`. - * @return false if the condition above is not true - */ - bool contains(const MemoryRegion& region) const; - - /** - * @brief Adds `region` into the memory map. Adjusts the map as necessary - * so that no regions overlap. Regions of higher type take precedence over - * regions with lower types; therefore, the lower typed regions are trimmed - * or deleted where they overlap with higher typed regions. Adjacent or - * overlapping regions with identical types are merged. - * - * @param region The memory region to insert - */ - void insertEntry(const MemoryRegion& region); - - /** - * @brief Overload of `insertEntry()`. @see insertRegion(const MemoryRegion&). - * - * @param location - * @param size - * @param type - */ - void insertEntry(physaddr_t location, size_t size, unsigned int type); - -private: - - /** - * @brief Removes the element at `index` in `m_map`. All objects located - * after that index are moved accordingly. - * - * @param index Locatation of the object to delete - */ - void remove(unsigned int index); - - /** - * @brief Inserts a copy of `region` into `m_map`. The new element is - * inserted such that `m_map` is sorted in ascending order. Overlapping - * elements are not trimmed. - * - * @param region The memory region to insert - */ - void simpleInsert(const MemoryRegion& region); - - /** - * @brief Overload of `simpleInsert(const MemoryRegion& region)`. - * - * @param location - * @param size - * @param type - */ - void simpleInsert(physaddr_t location, size_t size, unsigned int type); - - /** - * @brief If `m_map[index].overlaps(m_map[index+1])`, the two elements are - * modified so that they no longer overlap. The following rules apply: - * - * 1. This memory map will describe the same set of locations before and - * after performing this operation. - * - * 2. Adjacent regions of the same type are merged into a single region. - * - * 3. Where two regions of differing types overlap, the higher type takes - * precedence. The region of the lower type is truncated, split, or deleted - * so as to not overlap the region of the higher type. - * - * 4. This operation is local: only `m_map[index]` and `m_map[index+1]` are - * modified (although if a region must be split, a new region will be - * inserted at the location `index+2`). - * - * This function has no effect if `index+1 >= m_entries`, or if - * `m_map[index]` does not overlap the `m_map[index+1]`. - * - * @param index The location of the region to trim. - * - * @return The index of the rightmost region affected. - */ - unsigned int trim(unsigned int index); - - static const unsigned int maxEntries = 16; - - static const unsigned int invalidIndex = 0xFFFF; - - MemoryRegion m_map[maxEntries]; - - size_t m_entries; - -}; - -} - -#endif \ No newline at end of file diff --git a/src/memoryregion.cpp b/src/memoryregion.cpp deleted file mode 100644 index d0eeb15..0000000 --- a/src/memoryregion.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "memoryregion.hpp" - -MemoryRegion::MemoryRegion() -{ - m_location = 0; - m_size = 0; - m_type = 0; -} - -MemoryRegion::MemoryRegion(const MemoryRegion& copy) -{ - m_location = copy.m_location; - m_size = copy.m_size; - m_type = copy.m_type; -} - -MemoryRegion::MemoryRegion(physaddr_t location, size_t size, unsigned int type) -{ - m_location = location; - m_size = size; - m_type = (size_t) type; -} - -const MemoryRegion& MemoryRegion::operator=(const MemoryRegion& rhs) -{ - m_location = rhs.m_location; - m_size = rhs.m_size; - m_type = rhs.m_type; - return rhs; -} - -bool MemoryRegion::operator==(const MemoryRegion& rhs) const -{ - return (m_location == rhs.m_location) && (m_size == rhs.m_size); -} - -bool MemoryRegion::operator!=(const MemoryRegion& rhs) const -{ - return (m_location != rhs.m_location) || (m_size != rhs.m_size); -} - -bool MemoryRegion::operator<(const MemoryRegion& rhs) const -{ - return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size < rhs.m_size)); -} - -bool MemoryRegion::operator>(const MemoryRegion& rhs) const -{ - return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size > rhs.m_size)); -} - -bool MemoryRegion::operator<=(const MemoryRegion& rhs) const -{ - return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size <= rhs.m_size)); -} - -bool MemoryRegion::operator>=(const MemoryRegion& rhs) const -{ - return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size >= rhs.m_size)); -} - -physaddr_t MemoryRegion::getLocation() const -{ - return m_location; -} - -size_t MemoryRegion::getSize() const -{ - return m_size; -} - -unsigned int MemoryRegion::getType() const -{ - return m_type; -} - -physaddr_t MemoryRegion::getEnd() const -{ - return m_location + m_size; -} - -bool MemoryRegion::contains(const MemoryRegion& r) const -{ - return contains(r.m_location, r.m_size); -} - -bool MemoryRegion::contains(physaddr_t location, size_t size) const -{ - return (location >= m_location) && - (location + size <= m_location + m_size); -} - -bool MemoryRegion::overlaps(const MemoryRegion& r) const -{ - if(r.m_location < m_location) - return r.m_location + r.m_size > m_location; - else - return r.m_location < getEnd(); -} - -bool MemoryRegion::bordersLeft(const MemoryRegion& right) const -{ - return getEnd() == right.m_location; -} - -bool MemoryRegion::bordersRight(const MemoryRegion& left) const -{ - return m_location == left.m_location + left.m_size; -} - -bool MemoryRegion::borders(const MemoryRegion& r) const -{ - return bordersLeft(r) || bordersRight(r); -} - -void MemoryRegion::truncateLeft(physaddr_t left) -{ - m_size = getEnd() - left; - m_location = left; -} - -void MemoryRegion::truncateRight(physaddr_t right) -{ - if(right > m_location) - m_size = right - m_location; - else - m_size = 0; -} \ No newline at end of file diff --git a/src/memoryregion.hpp b/src/memoryregion.hpp deleted file mode 100644 index 35e57e8..0000000 --- a/src/memoryregion.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef MEMORYBLOCK_H -#define MEMORYBLOCK_H - -#include "systypes.hpp" - -class MemoryRegion -{ -public: - - MemoryRegion(); - - MemoryRegion(const MemoryRegion& copy); - - MemoryRegion(physaddr_t location, size_t size, unsigned int type); - - const MemoryRegion& operator=(const MemoryRegion& rhs); - - /** - * @brief Tests whether this object describes the same region of memory - * as rhs, irrespective of type. - * - * @param rhs The object to compare to - * @return true if and only if the location and size of the two regions are equal - * @return false if the two regions have differing locations or differing sizes - */ - bool operator==(const MemoryRegion& rhs) const; - - /** - * @brief Tests whether this object describes a different region of memory - * than rhs, irrespective of type. - * - * @param rhs The object to compare to - * @return true if the two regions have differing locations or differing sizes - * @return false if and only if the location and size of the two regions are equal - */ - bool operator!=(const MemoryRegion& rhs) const; - - /** - * @brief - * - * @param rhs - * @return true - * @return false - */ - bool operator<(const MemoryRegion& rhs) const; - - bool operator>(const MemoryRegion& rhs) const; - - bool operator<=(const MemoryRegion& rhs) const; - - bool operator>=(const MemoryRegion& rhs) const; - - physaddr_t getLocation() const; - - size_t getSize() const; - - unsigned int getType() const; - - physaddr_t getEnd() const; - - bool contains(const MemoryRegion& r) const; - - bool contains(physaddr_t location, size_t size) const; - - bool overlaps(const MemoryRegion& r) const; - - bool bordersLeft(const MemoryRegion& right) const; - - bool bordersRight(const MemoryRegion& left) const; - - bool borders(const MemoryRegion& r) const; - - void truncateLeft(physaddr_t left); - - void truncateRight(physaddr_t right); - -private: - - physaddr_t m_location; - - size_t m_size; - - unsigned int m_type; - -}; - -#endif \ No newline at end of file From e16cbd4ec958014ba8fabbd59d08357925480d5d Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sun, 11 Apr 2021 17:04:18 -0500 Subject: [PATCH 053/109] Added C header for memory type enum, removed C++ --- include/types/memorytype.h | 8 ++++++++ src/memorytype.hpp | 11 ----------- 2 files changed, 8 insertions(+), 11 deletions(-) create mode 100644 include/types/memorytype.h delete mode 100644 src/memorytype.hpp diff --git a/include/types/memorytype.h b/include/types/memorytype.h new file mode 100644 index 0000000..ddb018d --- /dev/null +++ b/include/types/memorytype.h @@ -0,0 +1,8 @@ +#pragma once + +enum memory_type +{ + M_AVAILABLE = 1, + M_UNAVAILABLE = 1, + M_DEFECTIVE = 3 +}; \ No newline at end of file diff --git a/src/memorytype.hpp b/src/memorytype.hpp deleted file mode 100644 index 99ea80b..0000000 --- a/src/memorytype.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef MEMORYTYPE_H -#define MEMORYTYPE_H - -enum class MemoryType -{ - Available = 1, - Unavailable = 2, - Defective = 3 -}; - -#endif \ No newline at end of file From 259aa3fabcb5b625cd9e59be41dcfed86009fbfb Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sun, 11 Apr 2021 17:20:57 -0500 Subject: [PATCH 054/109] Rewrote x86 initialize program in C --- include/tty.h | 9 ++++ src/x86/initialize.c | 98 ++++++++++++++++++++++++++++++++++++++++++ src/x86/initialize.cpp | 61 -------------------------- 3 files changed, 107 insertions(+), 61 deletions(-) create mode 100644 include/tty.h create mode 100644 src/x86/initialize.c delete mode 100644 src/x86/initialize.cpp diff --git a/include/tty.h b/include/tty.h new file mode 100644 index 0000000..9f577aa --- /dev/null +++ b/include/tty.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +int putchar(int c); + +int printf(const char *format, ...); + +int sprintf(char *str, const char *format, ...); \ No newline at end of file diff --git a/src/x86/initialize.c b/src/x86/initialize.c new file mode 100644 index 0000000..6522232 --- /dev/null +++ b/src/x86/initialize.c @@ -0,0 +1,98 @@ +#include "memorymap.h" +#include "tty.h" +#include "types/memorytype.h" +#include +#include + +struct interrupt_descriptor_t +{ + uint16_t m_offset1; + uint16_t m_selector; + uint16_t m_zero : 8; + uint16_t m_type : 4; + uint16_t m_storage : 1; + uint16_t m_dpl : 2; + uint16_t m_present : 1; + uint16_t m_offset2; +}; + +struct boot_info_t +{ + struct memory_map_t map; + char *bootloader; + char *parameters; +}; + +extern int _kernelEnd; + +struct interrupt_descriptor_t idt[256]; + +struct idt_info_t +{ + uint16_t size; + void *location; +}; + +void lidt() +{ + struct idt_info_t idt_info; + idt_info.size = sizeof(idt) - 1; + idt_info.location = (void *)&idt; + asm("lidt (%0)" + : + : "r"(&idt_info)); +} + +int startPaging(uint32_t *directory, uint32_t *table, uint32_t *identityTable) +{ + for (int i = 0; i < 1024; i++) + { + uint32_t pte = i * 4096 + 3; + table[i] = pte; + identityTable[i] = pte; + } + directory[0] = ((uint32_t)identityTable) + 3; + directory[1022] = ((uint32_t)table) + 3; + directory[1023] = ((uint32_t)directory) + 3; + asm("mov %0, %%cr3" + : + : "r"(directory)); + asm("mov %%cr0, %%eax \n" + "or $0x80010000, %%eax \n" + "mov %%eax, %%cr0" + : + : + : "eax"); + return 0; +} + +void *read_multiboot_table(struct boot_info_t *boot_info, void *table) +{ +} + +int initialize(void *multiboot_info) +{ + struct memory_region_t map_array[16]; + struct boot_info_t boot_info = { + .map = { + .array = map_array, + .size = 0, + .capacity = 16 + }, + .bootloader = NULL, + .parameters = NULL + }; + while(multiboot_info != NULL) + { + multiboot_info = read_multiboot_table(&boot_info, multiboot_info); + } + insert_region(&boot_info.map, 0, 1 << 22, M_UNAVAILABLE); + printf("Type\t\tLocation\t\tSize\n"); + for (size_t i = 0; i < boot_info.map.size && boot_info.map.array[i].size > 0; i++) + { + printf("%i\t\t\t%08X\t\t%i\n", boot_info.map.array[i].type, boot_info.map.array[i].location, boot_info.map.array[i].size); + } + // TODO: Initialize page allocator + // TODO: Initialize process queue, add entry for each module + return 0; +} diff --git a/src/x86/initialize.cpp b/src/x86/initialize.cpp deleted file mode 100644 index 361cd4f..0000000 --- a/src/x86/initialize.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include "multiboot2.hpp" -#include "tty.hpp" -#include "../mmap.hpp" -#include "../util.hpp" -#include "../memorytype.hpp" - -using namespace kernelns; - -extern int _kernelEnd; - -extern "C" -int startPaging(uint32_t* directory, uint32_t* table, uint32_t* identityTable) -{ - for(int i = 0; i < 1024; i++) - { - uint32_t pte = i * 4096 + 3; - table[i] = pte; - identityTable[i] = pte; - } - directory[0] = ((uint32_t) identityTable) + 3; - directory[1022] = ((uint32_t) table) + 3; - directory[1023] = ((uint32_t) directory) + 3; - asm("mov %0, %%cr3" - : - : "r" (directory)); - asm("mov %%cr0, %%eax \n" - "or $0x80010000, %%eax \n" - "mov %%eax, %%cr0" - : - : - : "eax"); - return 0; -} - -extern "C" -int initialize(void* multibootInfo) -{ - size_t heapSize = 0xFFC00000 - (size_t) &_kernelEnd; - int log = 0; - for(; heapSize > 1; log++) - heapSize >>= 1; - heapSize <<= log; - //new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64); - Multiboot2Info bootInfo(multibootInfo); - if(!bootInfo.isValid()) - return 1; - bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, (unsigned int) MemoryType::Unavailable); - //new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine()); - TTY tty((char*) 0xFF8B8000); - tty << "Type\t\tLocation\t\tSize\n"; - for(size_t i = 0; i < bootInfo.getMemoryMap().size() && bootInfo.getMemoryMap()[i].getSize() > 0; i++) - { - tty << (int) bootInfo.getMemoryMap()[i].getType() << "\t\t\t"; - tty << (void*) bootInfo.getMemoryMap()[i].getLocation() << "\t\t"; - tty << (int) bootInfo.getMemoryMap()[i].getSize() << "\n"; - } - // TODO: Initialize page allocator - // TODO: Initialize process queue, add entry for each module - return 0; -} From 48e6f907a1486fe266bac6fb54550b0b4245bf47 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 00:08:38 -0500 Subject: [PATCH 055/109] Committing old file deletion --- src/interrupts.hpp | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/interrupts.hpp diff --git a/src/interrupts.hpp b/src/interrupts.hpp deleted file mode 100644 index f8c99aa..0000000 --- a/src/interrupts.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef INTERRUPTS_H -#define INTERRUPTS_H - -namespace kernelns -{ - class Interrupts - { - public: - - static const unsigned int MAX_SYSCALL_ID = 31; - - Interrupts(); - - void enable(); - - void disable(); - - void addSyscall(unsigned int id, void* function); - - private: - - void* syscalls[MAX_SYSCALL_ID + 1]; - - }; -} - -#endif \ No newline at end of file From 41d21bd636472ff80201b0f2ce0cc8e3f64e6069 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 00:09:23 -0500 Subject: [PATCH 056/109] Added function to construct page stack from membory map --- include/pageallocator.h | 9 +++++++++ src/pageallocator.c | 25 ++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/pageallocator.h b/include/pageallocator.h index bccca63..5b52d54 100644 --- a/include/pageallocator.h +++ b/include/pageallocator.h @@ -1,5 +1,6 @@ #pragma once +#include "memorymap.h" #include "types/physaddr.h" #include @@ -64,3 +65,11 @@ int free_page(struct page_stack_t *stack, physaddr_t location); * @return size_t */ size_t free_page_count(struct page_stack_t *stack); + +/** + * @brief Push all available pages in `map` onto the stack + * + * @param stack + * @param map + */ +int initialize_page_stack(struct page_stack_t *stack, struct memory_map_t *map, size_t page_size); diff --git a/src/pageallocator.c b/src/pageallocator.c index 631e578..488fa33 100644 --- a/src/pageallocator.c +++ b/src/pageallocator.c @@ -1,4 +1,5 @@ #include "pageallocator.h" +#include "types/memorytype.h" #include "types/status.h" physaddr_t reserve_page(struct page_stack_t *stack) @@ -27,4 +28,26 @@ int free_page(struct page_stack_t *stack, physaddr_t location) size_t free_page_count(struct page_stack_t *stack) { return stack->base_pointer - stack->stack_pointer; -} \ No newline at end of file +} + +int initialize_page_stack(struct page_stack_t *stack, struct memory_map_t *map, size_t page_size) +{ + stack->total_pages = 0; + for(int i = 0; i < map->size; i++) + { + if(map->array[i].type != M_AVAILABLE) + { + continue; + } + size_t location = (map->array[i].location + page_size - 1) & ~(page_size - 1); + while(location + page_size <= map->array[i].location + map->array[i].size) + { + if(free_page(stack, location) != S_OK) + { + return S_OUT_OF_MEMORY; + } + stack->total_pages++; + location += page_size; + } + } +} From 7888c9df30f678075371cf1b74e316b97d9b0f95 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 00:34:43 -0500 Subject: [PATCH 057/109] Added header for module struct --- include/module.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 include/module.h diff --git a/include/module.h b/include/module.h new file mode 100644 index 0000000..eebad45 --- /dev/null +++ b/include/module.h @@ -0,0 +1,10 @@ +#pragma once + +#include "types/physaddr.h" + +struct module_t +{ + physaddr_t start; + physaddr_t end; + char string[64 - 2 * sizeof(physaddr_t)]; +}; \ No newline at end of file From 4a0f8e4f78d88f664616b4855de373b9315d22f8 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 00:58:46 -0500 Subject: [PATCH 058/109] Implemented multiboot2 in initialize.c Removed multiboot2 C++ code --- src/x86/initialize.c | 169 ++++++++++++++++++++++++++++++++++++----- src/x86/multiboot2.cpp | 83 -------------------- src/x86/multiboot2.hpp | 112 --------------------------- 3 files changed, 152 insertions(+), 212 deletions(-) delete mode 100644 src/x86/multiboot2.cpp delete mode 100644 src/x86/multiboot2.hpp diff --git a/src/x86/initialize.c b/src/x86/initialize.c index 6522232..0f97830 100644 --- a/src/x86/initialize.c +++ b/src/x86/initialize.c @@ -1,5 +1,9 @@ +#include "kernel.h" +#include "pageallocator.h" #include "memorymap.h" #include "tty.h" +#include "string.h" +#include "module.h" #include "types/memorytype.h" #include #include @@ -16,22 +20,95 @@ struct interrupt_descriptor_t uint16_t m_offset2; }; +struct idt_info_t +{ + uint16_t size; + void *location; +}; + +enum multiboot2_tag_types +{ + MB_END_TAG = 0, + MB_BOOT_COMMAND = 1, + MB_BOOTLOADER = 2, + MB_MODULE = 3, + MB_MEMORY_INFO = 4, + MB_BIOS_BOOT_DEVICE = 5, + MB_MEMORY_MAP = 6, + MB_VBE = 7, + MB_FRAMEBUFFER = 8, + MB_ELF_SYMBOLS = 9, + MB_APM = 10, + MB_EFI32_SYSTEM_TABLE = 11, + MB_EFI64_SYSTEM_TABLE = 12, + MB_SMBIOS = 13, + MB_ACPI10_RSDP = 14, + MB_ACPT20_RSDP = 15, + MB_NETOWRK = 16, + MB_EFI_MEMORY_MAP = 17, + MB_EFI_BOOT_SERVICES = 18, + MB_EFI32_IMAGE = 19, + MB_EFI64_IMAGE = 20, + MB_LOAD_ADDRESS = 21 +}; + +enum multiboot2_memory_types +{ + MB_AVAILABLE = 1, + MB_ACPI = 3, + MB_DEFECTIVE = 5 +}; + +struct multiboot2_string_t +{ + uint32_t type; + uint32_t size; + char str; +}; + +struct multiboot2_module_t +{ + uint32_t type; + uint32_t size; + uint32_t start; + uint32_t end; + char str; +}; + +struct multiboot2_map_entry_t +{ + uint64_t base; + uint64_t length; + uint32_t type; +}; + +struct multiboot2_memory_map_t +{ + uint32_t type; + uint32_t size; + uint32_t entry_size; + uint32_t entry_version; + struct multiboot2_map_entry_t entries; +}; + +const size_t module_limit = 8; + struct boot_info_t { - struct memory_map_t map; char *bootloader; char *parameters; + size_t module_count; + struct memory_map_t map; + struct module_t modules[module_limit]; }; extern int _kernelEnd; struct interrupt_descriptor_t idt[256]; -struct idt_info_t -{ - uint16_t size; - void *location; -}; +struct page_stack_t page_stack; + +struct kernel_t kernel; void lidt() { @@ -68,21 +145,71 @@ int startPaging(uint32_t *directory, uint32_t *table, uint32_t *identityTable) void *read_multiboot_table(struct boot_info_t *boot_info, void *table) { + uint32_t *int_table = (uint32_t *)table; + switch (*int_table) + { + case MB_END_TAG: + return NULL; + case MB_MEMORY_MAP: + unsigned int tag_size = ((struct multiboot2_memory_map_t*) table)->size - 16; + unsigned int entry_size = ((struct multiboot2_memory_map_t*) table)->entry_size; + struct multiboot2_map_entry_t *entry = &((struct multiboot2_memory_map_t*) table)->entries; + while(tag_size) + { + unsigned int entry_type = + entry->type == MB_AVAILABLE ? M_AVAILABLE + : (entry->type == MB_DEFECTIVE ? M_DEFECTIVE + : M_UNAVAILABLE); + insert_region(&boot_info->map, entry->base, entry->length, entry_type); + entry = (struct multiboot2_map_entry_t*) ((void*) entry + entry_size); + tag_size -= entry_size; + } + break; + case MB_MODULE: + if(boot_info->module_count < 8) + { + boot_info->modules[boot_info->module_count].start = ((struct multiboot2_module_t*) table)->start; + boot_info->modules[boot_info->module_count].end = ((struct multiboot2_module_t*) table)->end; + strcpy(boot_info->modules[boot_info->module_count].str, ((struct multiboot2_module_t*) table)->str); + insert_region(&boot_info->map, + ((struct multiboot2_module_t*) table)->start, + ((struct multiboot2_module_t*) table)->end - ((struct multiboot2_module_t*) table)->start, + M_UNAVAILABLE); + boot_info->module_count++; + } + else + { + printf("WARNING: Too many modules, must skip one.\n"); + } + break; + case MB_BOOT_COMMAND: + strcpy(boot_info->parameters, &((struct multiboot2_string_t*) table)->str); + break; + case MB_BOOTLOADER: + strcpy(boot_info->bootloader, &((struct multiboot2_string_t*) table)->str); + break; + default: + break; + } + size_t size = (int_table[1] + 7) - ((int_table[1] + 7) % 8); + return table + size; } int initialize(void *multiboot_info) { struct memory_region_t map_array[16]; + char bootloader_name[64]; + char kernel_parameters[64]; struct boot_info_t boot_info = { + .bootloader = bootloader_name, + .parameters = kernel_parameters, + .module_count = 0, .map = { - .array = map_array, - .size = 0, - .capacity = 16 - }, - .bootloader = NULL, - .parameters = NULL - }; - while(multiboot_info != NULL) + .array = map_array, + .size = 0, + .capacity = 16}}; + multiboot_info += 8; + while (multiboot_info != NULL) { multiboot_info = read_multiboot_table(&boot_info, multiboot_info); } @@ -92,7 +219,15 @@ int initialize(void *multiboot_info) { printf("%i\t\t\t%08X\t\t%i\n", boot_info.map.array[i].type, boot_info.map.array[i].location, boot_info.map.array[i].size); } - // TODO: Initialize page allocator - // TODO: Initialize process queue, add entry for each module - return 0; + page_stack.base_pointer = 0xFFC00000; + page_stack.stack_pointer = 0xFFC00000; + page_stack.limit_pointer = 0xFF900000; + initialize_page_stack(&page_stack, &boot_info.map, 4096); + + // TODO: Initialize process queue + for(int i = 0; i < boot_info.module_count; i++) + { + load_module(&kernel, &boot_info.modules[i]); + } + // TODO: enter first process } diff --git a/src/x86/multiboot2.cpp b/src/x86/multiboot2.cpp deleted file mode 100644 index ba745b5..0000000 --- a/src/x86/multiboot2.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "multiboot2.hpp" -#include "../memorytype.hpp" - -using namespace kernelns; - -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 == (uint32_t) Tag::BootCommand) - { - m_commandLine = &reinterpret_cast(ptr)->str; - } - else if(*ptr == (uint32_t) Tag::Bootloader) - { - m_bootloader = &reinterpret_cast(ptr)->str; - } - else if(*ptr == (uint32_t) Tag::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) - { - unsigned int regionType = - (entry->type == (unsigned int) Multiboot2MemoryType::Available) ? (unsigned int) MemoryType::Available - : ((entry->type == (unsigned int) Multiboot2MemoryType::Defective) ? (unsigned int) MemoryType::Defective - : (unsigned int) MemoryType::Unavailable); - m_memmap.insertEntry(entry->base, entry->length, entry->type); - entry = (MemoryMapEntry*) (reinterpret_cast(entry) + entrySize); - tagSize -= entrySize; - } - } - else if(*ptr == (uint32_t) Tag::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, (unsigned int) MemoryType::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 deleted file mode 100644 index 73962e1..0000000 --- a/src/x86/multiboot2.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef MULTIBOOT2_H -#define MULTIBOOT2_H - -#include "../memorymap.hpp" -#include "../module.hpp" - -namespace kernelns -{ - -class Multiboot2Info -{ -public: - - enum class Tag - { - BootCommand = 1, - Bootloader = 2, - Module = 3, - MemoryInfo = 4, - BIOSBootDevice = 5, - MemoryMap = 6, - VBE = 7, - Framebuffer = 8, - ELFSymbols = 9, - APM = 10, - EFI32SystemTable = 11, - EFI64SystemTable = 12, - SMBIOS = 13, - ACPI10RSDP = 14, - ACPT20RSDP = 15, - Network = 16, - EFIMemoryMap = 17, - EFIBootServices = 18, - EFI32Image = 19, - EFI64Image = 20, - LoadAddress = 21 - }; - - enum class Multiboot2MemoryType - { - Available = 1, - ACPI = 3, - Defective = 5 - }; - - 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 From 558874b5edf8ba0958752c57ebf1e7900e30f4c6 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 00:59:14 -0500 Subject: [PATCH 059/109] Added stdarg include to tty.h --- include/tty.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/tty.h b/include/tty.h index 9f577aa..6ec7d33 100644 --- a/include/tty.h +++ b/include/tty.h @@ -1,6 +1,7 @@ #pragma once #include +#include int putchar(int c); From bde2725b8feac8ae1f3dc689b1a4013437f0efc1 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:01:39 -0500 Subject: [PATCH 060/109] Removed old syscall WIP --- src/syscalls.cpp | 93 ------------------------------------------------ src/syscalls.hpp | 28 --------------- 2 files changed, 121 deletions(-) delete mode 100644 src/syscalls.cpp delete mode 100644 src/syscalls.hpp diff --git a/src/syscalls.cpp b/src/syscalls.cpp deleted file mode 100644 index 30e3918..0000000 --- a/src/syscalls.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "syscalls.hpp" -#include "kernel.hpp" -#include "memorytype.hpp" - -int mmap(void* location, size_t length, int flags) -{ - if(kernel.getActiveProcess().map(location, length)) - { - if(kernel.allocateRegion(location, length, flags)) - return 0; - else if(kernel.getActiveProcess().unmap(location, length)) - return 1; - kernel.terminateActiveProcess(); - } - return kernel.allocateRegion(location, length, flags); -} - -int munmap(void* location, size_t length) -{ - if(kernel.getActiveProcess().unmap(location, length)) - { - kernel.freeRegion(location, length); - return 0; - } - return 1; -} - -unsigned int createSharedBlock(void* location, size_t length, int flags) -{ - unsigned int blockID = kernel.createSharedBlock(length, flags); - if(blockID > 0) - { - const SharedBlock& block = kernel.getSharedBlock(blockID); - kernel.mapRegion(location, block.getLocation(), length, flags); - // TODO: add block to current process - // TODO: perform safety checks - } - return blockID; -} - -int aquireSharedBlock(void* location, unsigned int id) -{ - const SharedBlock& block = kernel.getSharedBlock(id); - kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getFlags()); - // TODO: (somehow) handle invalid ids -- possibly hard while using references - // TODO: add block to current process - // TODO: perform safety checks - return 0; -} - -int releaseSharedBlock(int id) -{ - // (0) Check that process actually posesses block - // (1) Get virtual address of block - // (2) Unmap block - // (3) Delete block if no one posesses it anymore - return 0; -} - -int querySharedBlock(void* info, int id) -{ - // TODO: define struct for block info -} - -int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t length) -{ - return 0; -} - -int releasePhysicalBlock(int id) -{ - return 0; -} - -int sendMessage(unsigned int recipient, const Message* message) -{ - Message* copy = new Message(*message); - copy->m_sender = kernel.getActiveProcess().getID(); - kernel.getProcess(recipient).pushMessage(copy); - return 0; -} - -int receiveMessage(Message* buffer) -{ - if(buffer == nullptr) - return 1; - Message* message = kernel.getActiveProcess().popMessage(); - if(message == nullptr) - return 1; - *buffer = *message; - delete message; - return 0; -} \ No newline at end of file diff --git a/src/syscalls.hpp b/src/syscalls.hpp deleted file mode 100644 index 5364426..0000000 --- a/src/syscalls.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SYSCALLS_H -#define SYSCALLS_H - -#include -#include "systypes.hpp" -#include "message.hpp" - -int mmap(void* location, size_t length, int flags); - -int munmap(void* location, size_t length); - -unsigned int createSharedBlock(void* location, size_t length, int flags); - -int aquireSharedBlock(void* location, unsigned int id); - -int releaseSharedBlock(int id); - -int querySharedBlock(void* info, int id); - -int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t length); - -int releasePhysicalBlock(int id); - -int sendMessage(unsigned int recipient, const Message* message); - -int receiveMessage(Message* buffer); - -#endif \ No newline at end of file From 2d1d6574afaa58243badcb323d6225cf4964cb5f Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:02:53 -0500 Subject: [PATCH 061/109] Removed old C++ screen printing code --- src/x86/tty.cpp | 125 ------------------------------------------------ src/x86/tty.hpp | 60 ----------------------- 2 files changed, 185 deletions(-) delete mode 100644 src/x86/tty.cpp delete mode 100644 src/x86/tty.hpp diff --git a/src/x86/tty.cpp b/src/x86/tty.cpp deleted file mode 100644 index 8ee9929..0000000 --- a/src/x86/tty.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include "tty.hpp" - -kernelns::TTY::TTY(char* vga) -{ - this->vga = vga; - this->cursor = 0; - this->width = 0; - this->base = 10; -} - -kernelns::TTY& kernelns::TTY::operator<<(kernelns::TTY::Format fmt) -{ - switch(fmt) - { - case Binary: - base = 2; - break; - case Decimal: - base = 10; - break; - case Hex: - base = 16; - break; - } -} - -kernelns::TTY& kernelns::TTY::operator<<(const char* str) -{ - return printString(str); -} - -kernelns::TTY& kernelns::TTY::operator<<(unsigned int n) -{ - return printNumber(n, base, width); -} - -kernelns::TTY& kernelns::TTY::operator<<(int n) -{ - return printNumber((unsigned int) n, base, width); -} - -kernelns::TTY& kernelns::TTY::operator<<(void* n) -{ - return printNumber((unsigned int) n, 16, 8); -} - -kernelns::TTY& kernelns::TTY::operator<<(char c) -{ - return putChar(c); -} - -void kernelns::TTY::setWidth(size_t width) -{ - this->width = width; -} - -size_t kernelns::TTY::getWidth() -{ - return width; -} - -void kernelns::TTY::clear() -{ - for(int i = 0; i < 80*25; i++) - { - vga[i * 2] = ' '; - } - cursor = 0; -} - -kernelns::TTY& kernelns::TTY::printNumber(unsigned int n, size_t base, - size_t width) -{ - const char* digits = "0123456789ABCDEF"; - char str[33]; - size_t i = 1; - do - { - str[i] = digits[n % base]; - n /= base; - i++; - } while(n > 0); - while(i <= width) - { - str[i] = '0'; - i++; - } - str[0] = '\0'; - for(char* s = str + (i - 1); *s; s--) - { - putChar(*s); - } - return *this; -} - -kernelns::TTY& kernelns::TTY::printString(const char* str) -{ - while(*str) - { - putChar(*str); - str++; - } - return *this; -} - -kernelns::TTY& kernelns::TTY::putChar(char c) -{ - switch(c) - { - case '\n': - cursor = (cursor + 80) - (cursor % 80); - break; - case '\t': - cursor = (cursor + 4) - (cursor % 4); - break; - case '\r': - cursor -= cursor % 160; - break; - default: - vga[cursor * 2] = c; - cursor++; - } - return *this; -} diff --git a/src/x86/tty.hpp b/src/x86/tty.hpp deleted file mode 100644 index 72bacf7..0000000 --- a/src/x86/tty.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef TTY_H_ -#define TTY_H_ - -#include - -namespace kernelns -{ - -class TTY -{ -public: - - enum Format - { - Binary, - Decimal, - Hex - }; - - TTY(char* vga); - - TTY& operator<<(Format fmt); - - TTY& operator<<(const char* str); - - TTY& operator<<(unsigned int n); - - TTY& operator<<(int n); - - TTY& operator<<(void* n); - - TTY& operator<<(char c); - - void setWidth(size_t width); - - size_t getWidth(); - - void clear(); - -private: - - TTY& printNumber(unsigned int n, size_t base, size_t width); - - TTY& printString(const char* str); - - TTY& putChar(char c); - - char* vga; - - int cursor; - - size_t width; - - size_t base; - -}; - -} - -#endif From 781a1151282f6265cc0464e7fe2c08c192de41c3 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:04:32 -0500 Subject: [PATCH 062/109] Renamed initialize.c to quark_x86.x --- src/x86/{initialize.c => quark_x86.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/x86/{initialize.c => quark_x86.c} (100%) diff --git a/src/x86/initialize.c b/src/x86/quark_x86.c similarity index 100% rename from src/x86/initialize.c rename to src/x86/quark_x86.c From 7255f89646c6cd4be38750ef6412f0509406ca99 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:05:26 -0500 Subject: [PATCH 063/109] Removed old kernel C++ files --- src/kernel.cpp | 31 ---------- src/kernel.hpp | 156 ------------------------------------------------ src/process.hpp | 54 ----------------- 3 files changed, 241 deletions(-) delete mode 100644 src/kernel.cpp delete mode 100644 src/kernel.hpp delete mode 100644 src/process.hpp diff --git a/src/kernel.cpp b/src/kernel.cpp deleted file mode 100644 index 98795ff..0000000 --- a/src/kernel.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "kernel.hpp" - -int Kernel::allocateRegion(void* page, size_t length, int flags) -{ - char* ptr = (char*) page; - for(int i = (int) length; i > 0; i -= mmgr.getPageSize()) - { - physaddr_t frame = pageAllocator.allocate(mmgr.getPageSize()); - if(frame != 0) - mmgr.mapPage(page, reserveFrame(), flags); - else - return -1; - ptr += mmgr.getPageSize(); - } - return 0; -} - -void Kernel::freeRegion(void* page, size_t length) -{ - char* ptr = (char*) page; - for(int i = (int) length; i > 0; i -= mmgr.getPageSize()) - { - pageAllocator.free(mmgr.unmapPage((void*) ptr), mmgr.getPageSize()); - ptr += mmgr.getPageSize(); - } -} - -int Kernel::mapRegion(void* page, physaddr_t frame, size_t length, int flags) -{ - -} \ No newline at end of file diff --git a/src/kernel.hpp b/src/kernel.hpp deleted file mode 100644 index 700989a..0000000 --- a/src/kernel.hpp +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef KERNEL_H -#define KERNEL_H - -#include "pageallocator.hpp" -#include "memorymanager.hpp" -#include "memorymap.hpp" -#include "sharedblock.hpp" -#include "process.hpp" -#include "systypes.hpp" - -using namespace kernelns; - -class Kernel -{ -public: - - void* malloc(size_t size); - - void free(void* ptr); - - /** - * @brief Maps a region of pages starting at virtual address 'page' with - * length 'length'. Allocates each mapped frame and any necessary page - * tables. This method does not perform any checks before overwriting page - * tables; it is the responsibility of the caller to ensure that the - * operation is safe to perform. - * - * @param page The virtual address of the first page to map - * @param length The size in bytes of the region to map - * @param flags The flags to apply to each page - * - * @returns zero upon success, nonzero on failure - */ - int allocateRegion(void* page, size_t length, int flags); - - /** - * @brief Unmaps and frees a region of mapped pages starting at virtual - * address 'page' with length 'length'. Does not free any page tables - * that are made redundant by this operation. It is the responsibility - * of the caller to ensure that all pages in the specified region are - * mapped and should be returned to the page allocator. - * - * @param page The virtual address of the first page to free - * @param length The size in bytes of the region to free - */ - void freeRegion(void* page, size_t length); - - /** - * @brief Maps a contiguous region of pages to a contiguous region of - * frames. Allocates new page tables as needed. All pages will share - * the same flags. - * - * @param page The virtual address of the first page to map - * @param frame The physical address of the first frame to map to - * @param length The size in bytes of the region to map - * @param flags The flags to apply to each page - * - * @returns zero upon success, nonzero on failure - */ - int mapRegion(void* page, physaddr_t frame, size_t length, int flags); - - /** - * @brief Unmaps a region of pages; does not return them to the page - * allocator. - * - * @param page The virtual address of the first page to unmap - * @param length The size in bytes of the region to unmap - */ - void unmapRegion(void* page, size_t length); - - /** - * @brief Create a Shared Block object - * - * @param length - * @param flags - * @returns The ID of the - */ - unsigned int createSharedBlock(size_t length, int flags); - - /** - * @brief Get the shared memory block referred to by 'id' - * - * @param id - * @returns a reference - */ - const SharedBlock& getSharedBlock(unsigned int id); - - /** - * @brief Create a new process - * - * @param imageBlockID - * @return Process& - */ - Process& createProcess(unsigned int imageBlockID); - - /** - * @brief Get the process object corresponsing to 'pid' - * - * @param pid id of the process to fetch - * @returns a reference to the requested process - */ - Process& getProcess(unsigned int pid); - - /** - * @brief Get the current active process object. - * - * @returns a reference to the active process - */ - Process& getActiveProcess(); - - /** - * @brief Puts the current active process back on the run queue, and sets - * the active process to the next one selected by the scheduler. - * - * @returns a reference to the new active process - */ - Process& yieldActiveProcess(); - - /** - * @brief Puts the current active process to sleep, and sets the active - * process to the next one selected by the scheduler. - * - * @returns a reference to the new active process - */ - Process& sleepActiveProcess(); - - /** - * @brief Terminates the current active process, freeing all its resources, - * and activates the next process selected by the scheduler. - * - * @return Process& - */ - Process& terminateActiveProcess(); - - /** - * @brief Terminates the process with id 'pid', freeing all its resources. - * If it holds any shared blocks which are not held by any other process, - * those blocks will be freed. - * - * @param pid id of the process to terminate - */ - void terminateProcess(unsigned int pid); - -private: - - PageAllocator& pageAllocator; - - MemoryManager& mmgr; - - MemoryMap& memoryMap; - -}; - -extern Kernel kernel; - -#endif \ No newline at end of file diff --git a/src/process.hpp b/src/process.hpp deleted file mode 100644 index b25238f..0000000 --- a/src/process.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef PROCESS_H -#define PROCESS_H - -#include - -#include "message.hpp" - -namespace kernelns -{ - -class Process -{ -public: - - size_t priority; - - void* stack; - - Process(); - - unsigned int getID() const; - - bool map(void* location, size_t size); - - /** - * @brief If the specified region is mapped and does not overlap a shared - * or private block, or the kernel, removes that region from the process's - * internal memory map. If the specified region overlaps an unmapped region, - * a shared or private block, or the kernel, the object goes unmodified. - * This method does not affect the page tables in any way, only the process's - * internal bookkeeping. - * - * @param location - * @param size - * @return true if the memory map was sucessfully updated - * @return false if the memory map was not modified - */ - bool unmap(void* location, size_t size); - - bool hasSharedBlock(unsigned int blockID) const; - - bool hasPhysicalBlock(unsigned int blockID) const; - - void pushMessage(Message* message); - - Message* popMessage(); - -private: - -}; - -} - -#endif \ No newline at end of file From e235e9bad23c59915b59a2fceff0f25f98119eb0 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:21:18 -0500 Subject: [PATCH 064/109] Moved memory type enum to memorymap.h Deleted memorytype.h --- include/memorymap.h | 9 ++++++++- include/types/memorytype.h | 8 -------- src/pageallocator.c | 1 - src/x86/quark_x86.c | 1 - 4 files changed, 8 insertions(+), 11 deletions(-) delete mode 100644 include/types/memorytype.h diff --git a/include/memorymap.h b/include/memorymap.h index e33eb40..a1d9d8c 100644 --- a/include/memorymap.h +++ b/include/memorymap.h @@ -3,6 +3,13 @@ #include "types/physaddr.h" #include +enum memory_type_t +{ + M_AVAILABLE = 1, + M_UNAVAILABLE = 1, + M_DEFECTIVE = 3 +}; + struct memory_region_t { physaddr_t location; @@ -17,4 +24,4 @@ struct memory_map_t size_t capacity; }; -void insert_region(struct memory_map_t *map, physaddr_t location, size_t size, unsigned int type); \ No newline at end of file +void insert_region(struct memory_map_t *map, physaddr_t location, size_t size, enum memory_type_t type); \ No newline at end of file diff --git a/include/types/memorytype.h b/include/types/memorytype.h deleted file mode 100644 index ddb018d..0000000 --- a/include/types/memorytype.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -enum memory_type -{ - M_AVAILABLE = 1, - M_UNAVAILABLE = 1, - M_DEFECTIVE = 3 -}; \ No newline at end of file diff --git a/src/pageallocator.c b/src/pageallocator.c index 488fa33..6289809 100644 --- a/src/pageallocator.c +++ b/src/pageallocator.c @@ -1,5 +1,4 @@ #include "pageallocator.h" -#include "types/memorytype.h" #include "types/status.h" physaddr_t reserve_page(struct page_stack_t *stack) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 0f97830..70beb88 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -4,7 +4,6 @@ #include "tty.h" #include "string.h" #include "module.h" -#include "types/memorytype.h" #include #include From 74fe6e1a58359cfd081ee19d844c61b4f86202ef Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:21:59 -0500 Subject: [PATCH 065/109] Moved ELF structures to C header --- include/elf.h | 119 ++++++++++++++++++++++++++++++++++++++++++ src/elf.cpp | 44 ---------------- src/elf.hpp | 142 -------------------------------------------------- 3 files changed, 119 insertions(+), 186 deletions(-) create mode 100644 include/elf.h delete mode 100644 src/elf.cpp delete mode 100644 src/elf.hpp diff --git a/include/elf.h b/include/elf.h new file mode 100644 index 0000000..1161305 --- /dev/null +++ b/include/elf.h @@ -0,0 +1,119 @@ +#pragma once + +#include "types/physaddr.h" +#include + +const uint32_t elf_magic_number = 0x464c457f; + +enum elf_endianness_t +{ + ELF_LITTLE_ENDIAN = 1, + ELF_BIG_ENDIAN = 2 +}; + +enum elf_isa_t +{ + ELF_ISA_NA = 0x00, + ELF_ISA_x86 = 0x03, + ELF_ISA_MIPS = 0x08, + ELF_ISA_PPC = 0x14, + ELF_ISA_PPC64 = 0x15, + ELF_ISA_ARM = 0x28, + ELF_ISA_x86_64 = 0x3E, + ELF_ISA_AARCH64 = 0xB7 +}; + +enum elf_segment_type_t +{ + ELF_UNUSED = 0, + ELF_LOAD = 1, + ELF_DYNAMIC = 2 +}; + +struct elf_file_header_t +{ + uint32_t magic; + char size; + char endianness; + char version; + char abi; + char abi_version; + 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 header_size; + uint16_t phsize; + uint16_t phcount; + uint16_t shsize; + uint16_t shcount; + uint16_t shstrndx; +}; + +struct elf_program_header_t +{ + 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 elf_section_header_t +{ + 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 entry_size; +#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 entry_size; +#endif +}; + +#if defined __i386__ + static const elf_isa_t HOST_ISA = ELF_ISA_x86; +#elif defined __x86_64__ + static const elf_isa_t HOST_ISA = ELF_ISA_x86_64; +#elif defined __arm__ + static const elf_isa_t HOST_ISA = ELF_ISA_ARM; +#elif defined __aarch64__ + static const elf_isa_t HOST_ISA = ELF_ISA_AARCH64; +#endif + +int load_elf_executable(void *file); diff --git a/src/elf.cpp b/src/elf.cpp deleted file mode 100644 index 503da94..0000000 --- a/src/elf.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "elf.hpp" -#include "util.hpp" - -kernelns::ELF::ELF() -{ - this->m_fileLocation = (void*) NULL; -} - -kernelns::ELF::ELF(void* location) -{ - this->m_fileLocation = location; -} - -void* kernelns::ELF::entry() -{ - Header* fileHeader = (Header*) m_fileLocation; - return fileHeader->entry; -} - -int kernelns::ELF::validate() -{ - 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; -} - -int kernelns::ELF::load() -{ - 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; -} \ No newline at end of file diff --git a/src/elf.hpp b/src/elf.hpp deleted file mode 100644 index be986e6..0000000 --- a/src/elf.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef ELF_H -#define ELF_H - -#include "systypes.hpp" - -namespace kernelns -{ - -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; - -}; - -} - -#endif \ No newline at end of file From 1f7ef81149582ac98803426903a16533831431e7 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:22:31 -0500 Subject: [PATCH 066/109] Renamed module_t::string to module_t::str --- include/module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/module.h b/include/module.h index eebad45..4e0cc1a 100644 --- a/include/module.h +++ b/include/module.h @@ -6,5 +6,5 @@ struct module_t { physaddr_t start; physaddr_t end; - char string[64 - 2 * sizeof(physaddr_t)]; + char str[64 - 2 * sizeof(physaddr_t)]; }; \ No newline at end of file From b3b2921b7e3be8b7a947541c44a9ad246c9a76cb Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:41:52 -0500 Subject: [PATCH 067/109] Renamed tty.h to stdio.h Added puts() declaration --- include/{tty.h => stdio.h} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename include/{tty.h => stdio.h} (83%) diff --git a/include/tty.h b/include/stdio.h similarity index 83% rename from include/tty.h rename to include/stdio.h index 6ec7d33..3c086ee 100644 --- a/include/tty.h +++ b/include/stdio.h @@ -1,10 +1,11 @@ #pragma once -#include #include int putchar(int c); +int puts(const char *str); + int printf(const char *format, ...); int sprintf(char *str, const char *format, ...); \ No newline at end of file From e84a2fadd343f15293a16a3acbacd05c41e5cbea Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:42:53 -0500 Subject: [PATCH 068/109] Added stubs for stdio.h functions putchar() and puts() are platform-dependent --- src/stdio.c | 11 +++++++++++ src/x86/putc.c | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/stdio.c create mode 100644 src/x86/putc.c diff --git a/src/stdio.c b/src/stdio.c new file mode 100644 index 0000000..4a95c3c --- /dev/null +++ b/src/stdio.c @@ -0,0 +1,11 @@ +#include "stdio.h" + +int printf(const char *format, ...) +{ + +} + +int sprintf(char *str, const char *format, ...) +{ + +} \ No newline at end of file diff --git a/src/x86/putc.c b/src/x86/putc.c new file mode 100644 index 0000000..9fdeaaf --- /dev/null +++ b/src/x86/putc.c @@ -0,0 +1,11 @@ +#include "stdio.h" + +int putchar(int c) +{ + +} + +int puts(const char *str) +{ + +} \ No newline at end of file From ca0d09d9b55623430d5ba45b39a6c4d14020164a Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:43:14 -0500 Subject: [PATCH 069/109] Removed load_elf_executable() declaration --- include/elf.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/elf.h b/include/elf.h index 1161305..6605add 100644 --- a/include/elf.h +++ b/include/elf.h @@ -115,5 +115,3 @@ struct elf_section_header_t #elif defined __aarch64__ static const elf_isa_t HOST_ISA = ELF_ISA_AARCH64; #endif - -int load_elf_executable(void *file); From 0b302c57593d5c5ebf00c453fce37cdf6690b292 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:43:47 -0500 Subject: [PATCH 070/109] Started main kernel functions --- include/kernel.h | 12 +++++++++++- src/kernel.c | 11 +++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/kernel.c diff --git a/include/kernel.h b/include/kernel.h index 1ca0240..86c89a9 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -1,6 +1,16 @@ #pragma once +#include "priorityqueue.h" +#include "module.h" +#include + struct kernel_t { + struct priority_queue_t *priority_queue; +}; -}; \ No newline at end of file +extern struct kernel_t kernel; + +int do_syscall(struct kernel_t *kernel, size_t id, size_t arg1, size_t arg2, size_t arg3); + +int load_module(struct kernel_t *kernel, struct module_t *module); diff --git a/src/kernel.c b/src/kernel.c new file mode 100644 index 0000000..cf049dc --- /dev/null +++ b/src/kernel.c @@ -0,0 +1,11 @@ +#include "kernel.h" + +int do_syscall(struct kernel_t *kernel, size_t id, size_t arg1, size_t arg2, size_t arg3) +{ + +} + +int load_module(struct kernel_t *kernel, struct module_t *module) +{ + +} \ No newline at end of file From dc4d3c01658100cfadc53e8d3f307b20cc603891 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:44:17 -0500 Subject: [PATCH 071/109] Added isr type enum to quark_x86.c --- src/x86/quark_x86.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 70beb88..b8d5339 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -7,6 +7,15 @@ #include #include +enum isr_type_t +{ + INTERRPUT_TASK32 = 5, + INTERRPUT_TRAP32 = 15, + INTERRPUT_INT32 = 14, + INTERRPUT_TRAP16 = 7, + INTERRPUT_INT16 = 6 +}; + struct interrupt_descriptor_t { uint16_t m_offset1; From 470f6b2d9908e8f4e1dc2884e88be01ea08f1784 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:44:38 -0500 Subject: [PATCH 072/109] Updated autotools config --- configure.ac | 5 ++--- src/Makefile.am | 12 +++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 5739739..6ed9f7e 100644 --- a/configure.ac +++ b/configure.ac @@ -4,18 +4,17 @@ AC_PREREQ([2.69]) AC_INIT([quark-kernel], [pre-alpha]) AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) -AC_CONFIG_SRCDIR([src/allocator.cpp]) +AC_CONFIG_SRCDIR([src/kernel.c]) AC_CONFIG_HEADERS([src/config.h]) # Checks for programs. -AC_PROG_CXX AC_PROG_CC AM_PROG_AS AM_PROG_AR AC_PROG_RANLIB # Checks for header files. -AC_CHECK_HEADERS([stddef.h stdint.h]) +AC_CHECK_HEADERS([stddef.h stdint.h stdarg.h]) # Checks for typedefs, structures, and compiler characteristics. AC_CHECK_HEADER_STDBOOL diff --git a/src/Makefile.am b/src/Makefile.am index b4709fc..ef5ae17 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,15 +1,13 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = module.cpp util.cpp memorymap.cpp memoryregion.cpp pageallocator.cpp allocator.cpp scheduler.cpp +quark_kernel_SOURCES = kernel.c memorymap.c pageallocator.c priorityqueue.c stdio.c string.c quark_kernel_LDADD = -lgcc -quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb +quark_kernel_CFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -ggdb quark_kernel_LDFLAGS = -nostdlib if x86 -quark_kernel_SOURCES += x86/mmap.cpp \ - x86/tty.cpp \ - x86/interrupts.cpp \ - x86/multiboot2.cpp \ - x86/initialize.cpp \ +quark_kernel_SOURCES += x86/mmgr.c \ + x86/putc.c \ + x86/quark_x86.c \ x86/entry.S quark_kernel_LDFLAGS += -T x86/linker.ld quark_kernel_DEPENDENCIES = x86/linker.ld From d415fb232e87c2d14ad1ddbe96880354f90bc523 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:49:45 -0500 Subject: [PATCH 073/109] Added missing stdint.h include to physaddr.h --- include/types/physaddr.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/types/physaddr.h b/include/types/physaddr.h index 9cf0725..fb00318 100644 --- a/include/types/physaddr.h +++ b/include/types/physaddr.h @@ -1,5 +1,7 @@ #pragma once +#include + #if defined __i386__ || __arm__ typedef uint32_t physaddr_t; #elif defined __x86_64__ || __aarch64__ From 47a591fe7c54bd4027f66406314590b32f9f1b78 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:50:08 -0500 Subject: [PATCH 074/109] Fixed missing include search path in Makefile.am --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index ef5ae17..1832fa8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ noinst_PROGRAMS = quark-kernel quark_kernel_SOURCES = kernel.c memorymap.c pageallocator.c priorityqueue.c stdio.c string.c quark_kernel_LDADD = -lgcc -quark_kernel_CFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -ggdb +quark_kernel_CFLAGS = -I$(top_srcdir)/include -ffreestanding -mgeneral-regs-only -O0 -Wall -ggdb quark_kernel_LDFLAGS = -nostdlib if x86 From 5006addfb540bb0418d07a986b9f1936dbe6f111 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 01:52:33 -0500 Subject: [PATCH 075/109] Fixed formatting in mmgr.c --- src/x86/mmgr.c | 70 ++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/x86/mmgr.c b/src/x86/mmgr.c index 80ce59e..6801c2f 100644 --- a/src/x86/mmgr.c +++ b/src/x86/mmgr.c @@ -12,71 +12,73 @@ struct page_table_entry_t { uint32_t present : 1; - uint32_t rw : 1; + uint32_t rw : 1; - uint32_t usermode : 1; + uint32_t usermode : 1; - uint32_t writeThrough : 1; + uint32_t writeThrough : 1; - uint32_t cacheDisable : 1; + uint32_t cacheDisable : 1; - uint32_t accessed : 1; + uint32_t accessed : 1; - uint32_t dirty : 1; + uint32_t dirty : 1; - uint32_t pat : 1; + uint32_t pat : 1; - uint32_t global : 1; - - uint32_t shared : 1; + uint32_t global : 1; - uint32_t ignored : 2; + uint32_t shared : 1; - uint32_t physicalAddress : 20; + uint32_t ignored : 2; + + uint32_t physicalAddress : 20; }; -struct page_table_entry_t *page_tables = (struct page_table_entry_t*) 0xFFC00000; +struct page_table_entry_t *page_tables = (struct page_table_entry_t *)0xFFC00000; -struct page_table_entry_t *page_directory = (struct page_table_entry_t*) 0xFFFFF000; +struct page_table_entry_t *page_directory = (struct page_table_entry_t *)0xFFFFF000; physaddr_t create_address_space(struct page_stack_t *page_stack) { physaddr_t table = reserve_page(page_stack); - if(table == S_OUT_OF_MEMORY) + if (table == S_OUT_OF_MEMORY) { return S_OUT_OF_MEMORY; } struct page_table_entry_t buffer = page_directory[0]; page_directory[0] = table; - asm volatile("invlpg $0xFFC00000" ::: "memory"); - memset((void*) page_tables, 0, 1022 * 4); + asm volatile("invlpg $0xFFC00000" :: + : "memory"); + memset((void *)page_tables, 0, 1022 * 4); page_tables[1022] = page_directory[1022]; page_tables[1023] = page_directory[1023]; page_directory[0] = buffer; - asm volatile("invlpg $0xFFC00000" ::: "memory"); + asm volatile("invlpg $0xFFC00000" :: + : "memory"); return table; } void load_address_space(physaddr_t table) { asm volatile("mov %0, %%cr3" - : - : "r" (table) - : "memory"); + : + : "r"(table) + : "memory"); } int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int flags) { - if((size_t) page % page_size != 0 || frame % page_size != 0) + if ((size_t)page % page_size != 0 || frame % page_size != 0) { return S_OUT_OF_BOUNDS; } - size_t table_index = (size_t) page / page_size; + size_t table_index = (size_t)page / page_size; size_t directory_index = table_index / (page_size / sizeof(struct page_table_entry_t)); - if(!page_directory[directory_index].present) + if (!page_directory[directory_index].present) { physaddr_t new_table = reserve_page(page_stack); - if(new_table == S_OUT_OF_MEMORY) + if (new_table == S_OUT_OF_MEMORY) { return S_OUT_OF_MEMORY; } @@ -90,21 +92,21 @@ int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int page_tables[table_index].usermode = 1; page_tables[table_index].rw = 1; asm volatile("invlpg (%0)" - : - : "r" (page) - : "memory"); + : + : "r"(page) + : "memory"); return S_OK; } physaddr_t unmap_page(void *page) { - if((size_t) page % page_size != 0) + if ((size_t)page % page_size != 0) { return S_OUT_OF_BOUNDS; } - size_t table_index = (size_t) page / page_size; + size_t table_index = (size_t)page / page_size; size_t directory_index = table_index / (page_size / sizeof(struct page_table_entry_t)); - if(!page_directory[directory_index].present || !page_tables[table_index].present) + if (!page_directory[directory_index].present || !page_tables[table_index].present) { return S_OUT_OF_BOUNDS; } @@ -113,9 +115,9 @@ physaddr_t unmap_page(void *page) physaddr_t frame = page_tables[table_index].physicalAddress << page_bits; memset(&page_tables[table_index], 0, sizeof(struct page_table_entry_t)); asm volatile("invlpg (%0)" - : - : "r" (page) - : "memory"); + : + : "r"(page) + : "memory"); return frame; } } \ No newline at end of file From e2562c9a4eba12d496873263e4890d79f1d3f1cd Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 02:21:29 -0500 Subject: [PATCH 076/109] Fixed invlpg instruction in create_address_space() --- src/x86/mmgr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/x86/mmgr.c b/src/x86/mmgr.c index 6801c2f..a12be9f 100644 --- a/src/x86/mmgr.c +++ b/src/x86/mmgr.c @@ -47,14 +47,14 @@ physaddr_t create_address_space(struct page_stack_t *page_stack) return S_OUT_OF_MEMORY; } struct page_table_entry_t buffer = page_directory[0]; - page_directory[0] = table; - asm volatile("invlpg $0xFFC00000" :: + page_directory[0].physicalAddress = table >> page_bits; + asm volatile("invlpg 0xFFC00000" :: : "memory"); memset((void *)page_tables, 0, 1022 * 4); page_tables[1022] = page_directory[1022]; page_tables[1023] = page_directory[1023]; page_directory[0] = buffer; - asm volatile("invlpg $0xFFC00000" :: + asm volatile("invlpg 0xFFC00000" :: : "memory"); return table; } @@ -82,12 +82,12 @@ int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int { return S_OUT_OF_MEMORY; } - page_directory[directory_index] = new_table >> page_bits; + page_directory[directory_index].physicalAddress = new_table >> page_bits; page_directory[directory_index].present = 1; page_directory[directory_index].usermode = 0; page_directory[directory_index].rw = 1; } - page_tables[table_index] = frame >> 12; + page_tables[table_index].physicalAddress = frame >> 12; page_tables[table_index].present = 1; page_tables[table_index].usermode = 1; page_tables[table_index].rw = 1; From c94a4a692b7f32f0ef0d3523b6a35939c4d84c4d Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 02:22:06 -0500 Subject: [PATCH 077/109] Updated stdio.h include in quark_x86.c --- src/x86/quark_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index b8d5339..6f50f1f 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -1,7 +1,7 @@ #include "kernel.h" #include "pageallocator.h" #include "memorymap.h" -#include "tty.h" +#include "stdio.h" #include "string.h" #include "module.h" #include From 20b718c9353ff929fa909cd763afd277ca9a6524 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 15:28:03 -0500 Subject: [PATCH 078/109] Implemented bare-bones putchar() and puts() --- src/x86/putc.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/x86/putc.c b/src/x86/putc.c index 9fdeaaf..84891f4 100644 --- a/src/x86/putc.c +++ b/src/x86/putc.c @@ -1,11 +1,65 @@ #include "stdio.h" +#include + +enum vga_color_t { + VGA_COLOR_BLACK = 0, + VGA_COLOR_BLUE = 1, + VGA_COLOR_GREEN = 2, + VGA_COLOR_CYAN = 3, + VGA_COLOR_RED = 4, + VGA_COLOR_MAGENTA = 5, + VGA_COLOR_BROWN = 6, + VGA_COLOR_LIGHT_GREY = 7, + VGA_COLOR_DARK_GREY = 8, + VGA_COLOR_LIGHT_BLUE = 9, + VGA_COLOR_LIGHT_GREEN = 10, + VGA_COLOR_LIGHT_CYAN = 11, + VGA_COLOR_LIGHT_RED = 12, + VGA_COLOR_LIGHT_MAGENTA = 13, + VGA_COLOR_LIGHT_BROWN = 14, + VGA_COLOR_WHITE = 15, +}; + +__attribute__ ((packed)) +struct cell_t +{ + char c; + char fg : 4; + char bg : 4; +}; + +struct cell_t *screen = 0xFFCB8000; + +const size_t tab_width = 4; +const size_t line_width = 80; int putchar(int c) { - + switch(c) + { + case '\n': + screen += line_width; + screen -= (size_t) screen % line_width; + break; + case '\t': + screen += (tab_width) & ~(tab_width); + break; + case '\r': + screen -= line_width - 1; + screen += line_width - ((size_t) screen % line_width); + break; + default: + screen->c = (char) c; + screen++; + } + return c; } int puts(const char *str) { - + while(*str) + { + putchar(*str); + } + return 0; } \ No newline at end of file From f2c19bd4c46e09c8cbc34b423bfc6aa5a3b2372c Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 15:28:37 -0500 Subject: [PATCH 079/109] Turned module_limit into a macro --- src/x86/quark_x86.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 6f50f1f..84f1c55 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -7,6 +7,8 @@ #include #include +#define module_limit 8 + enum isr_type_t { INTERRPUT_TASK32 = 5, @@ -99,8 +101,6 @@ struct multiboot2_memory_map_t struct multiboot2_map_entry_t entries; }; -const size_t module_limit = 8; - struct boot_info_t { char *bootloader; @@ -158,7 +158,7 @@ void *read_multiboot_table(struct boot_info_t *boot_info, void *table) { case MB_END_TAG: return NULL; - case MB_MEMORY_MAP: + case MB_MEMORY_MAP: ; unsigned int tag_size = ((struct multiboot2_memory_map_t*) table)->size - 16; unsigned int entry_size = ((struct multiboot2_memory_map_t*) table)->entry_size; struct multiboot2_map_entry_t *entry = &((struct multiboot2_memory_map_t*) table)->entries; From 2f7300fbf850560dd6768bccb980a06c6126ff04 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 15:51:25 -0500 Subject: [PATCH 080/109] Fixed infinite loop when interting into memory map --- src/memorymap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memorymap.c b/src/memorymap.c index 5bc6864..543e89a 100644 --- a/src/memorymap.c +++ b/src/memorymap.c @@ -123,7 +123,7 @@ int trim_map(struct memory_map_t *map, int index) void insert_region(struct memory_map_t *map, physaddr_t location, size_t size, unsigned int type) { insert_map_entry(map, location, size, type); - unsigned int i = 0; + int i = 0; while(i >= 0) { i = trim_map(map, i); From 8d784364f8eb3f4a3d048f5bdffcc3240368540e Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 15:52:03 -0500 Subject: [PATCH 081/109] Fixed value of pointer to video memory --- src/x86/putc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86/putc.c b/src/x86/putc.c index 84891f4..cac04ab 100644 --- a/src/x86/putc.c +++ b/src/x86/putc.c @@ -28,7 +28,7 @@ struct cell_t char bg : 4; }; -struct cell_t *screen = 0xFFCB8000; +struct cell_t *screen = (struct cell_t*)0xFF8B8000; const size_t tab_width = 4; const size_t line_width = 80; From cb7df05625d1168fb5e272b4a6640334c6ab2652 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Mon, 12 Apr 2021 15:52:32 -0500 Subject: [PATCH 082/109] Added line to print character to screen after initializing --- src/x86/quark_x86.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 84f1c55..9d5207c 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -238,4 +238,5 @@ int initialize(void *multiboot_info) load_module(&kernel, &boot_info.modules[i]); } // TODO: enter first process + putchar('&'); } From e9ffd9d85c8cf797a46a4a6b566e523496099d14 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Tue, 13 Apr 2021 00:20:19 -0500 Subject: [PATCH 083/109] Fixed incorrect memory type enum --- include/memorymap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/memorymap.h b/include/memorymap.h index a1d9d8c..933b641 100644 --- a/include/memorymap.h +++ b/include/memorymap.h @@ -6,7 +6,7 @@ enum memory_type_t { M_AVAILABLE = 1, - M_UNAVAILABLE = 1, + M_UNAVAILABLE = 2, M_DEFECTIVE = 3 }; From c6467e20d84987852e06863e91cc4c8794a2db47 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Tue, 13 Apr 2021 00:20:45 -0500 Subject: [PATCH 084/109] Wrote partial printf implementation --- src/stdio.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/src/stdio.c b/src/stdio.c index 4a95c3c..1e2165d 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -1,11 +1,100 @@ #include "stdio.h" +#include +#include + +enum format_flags_t +{ + FORMAT_PADDING = '0', + FORMAT_WIDTH = '*', + + FORMAT_SIGNED_DECIMAL = 'i', + FORMAT_UNSIGNED_DECIMAL = 'u', + FORMAT_UNSIGNED_OCTAL = 'o', + FORMAT_UNSIGNED_HEX = 'x', + FORMAT_STRING = 's', + FORMAT_COUNT = 'n', + FORMAT_PERCENT = '%' + +}; + +char *itoa(unsigned int n, unsigned int base, unsigned int width) +{ + if (base < 2 || base > 16) + { + return NULL; + } + static const char *digits = "0123456789abcdef"; + static char buffer[65]; + char *s = &buffer[64]; + unsigned int count = 0; + do + { + *--s = digits[n % base]; + n /= base; + count++; + } while (count < width || n != 0); + return s; +} int printf(const char *format, ...) { - + va_list valist; + va_start(valist, format); + while (*format) + { + if (*format == '%') + { + size_t width = 0; + bool padding = false; + switch (*++format) + { + case FORMAT_PADDING: + padding = true; + format++; + break; + } + while (*format >= '0' && *format <= '9') + { + width = (width * 10) + *format - '0'; + format++; + } + switch (*format) + { + case FORMAT_SIGNED_DECIMAL:; + int n = va_arg(valist, int); + if (n < 0) + { + putchar('-'); + n *= -1; + } + puts(itoa((unsigned int)n, 10, width)); + break; + case FORMAT_UNSIGNED_DECIMAL: + puts(itoa(va_arg(valist, unsigned int), 10, width)); + break; + case FORMAT_UNSIGNED_OCTAL: + puts(itoa(va_arg(valist, unsigned int), 8, width)); + case FORMAT_UNSIGNED_HEX: + puts(itoa(va_arg(valist, unsigned int), 16, width)); + break; + case FORMAT_STRING: + puts(va_arg(valist, const char *)); + break; + case FORMAT_PERCENT: + putchar('%'); + break; + } + } + else + { + putchar(*format); + } + format++; + } + va_end(valist); + return 0; } int sprintf(char *str, const char *format, ...) { - } \ No newline at end of file From 302ed3b816e8b155c43aace2a17496250bff2e98 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Tue, 13 Apr 2021 00:21:08 -0500 Subject: [PATCH 085/109] Fixed issues with tabs and newlines in putchar() --- src/x86/putc.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/x86/putc.c b/src/x86/putc.c index cac04ab..854751f 100644 --- a/src/x86/putc.c +++ b/src/x86/putc.c @@ -29,6 +29,7 @@ struct cell_t }; struct cell_t *screen = (struct cell_t*)0xFF8B8000; +size_t cursor = 0; const size_t tab_width = 4; const size_t line_width = 80; @@ -38,19 +39,20 @@ int putchar(int c) switch(c) { case '\n': - screen += line_width; - screen -= (size_t) screen % line_width; + cursor += line_width; + cursor -= cursor % line_width; break; case '\t': - screen += (tab_width) & ~(tab_width); + cursor += tab_width; + cursor -= cursor % tab_width; break; case '\r': - screen -= line_width - 1; - screen += line_width - ((size_t) screen % line_width); + cursor -= line_width - 1; + cursor += line_width - (cursor % line_width); break; default: - screen->c = (char) c; - screen++; + screen[cursor].c = (char) c; + cursor++; } return c; } @@ -60,6 +62,7 @@ int puts(const char *str) while(*str) { putchar(*str); + str++; } return 0; } \ No newline at end of file From e6a417c82234c5caae185b35091c3e94658f6a77 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Tue, 13 Apr 2021 00:21:36 -0500 Subject: [PATCH 086/109] Changed formatting flag used to print memory map --- src/x86/quark_x86.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 9d5207c..20258cd 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -225,7 +225,7 @@ int initialize(void *multiboot_info) printf("Type\t\tLocation\t\tSize\n"); for (size_t i = 0; i < boot_info.map.size && boot_info.map.array[i].size > 0; i++) { - printf("%i\t\t\t%08X\t\t%i\n", boot_info.map.array[i].type, boot_info.map.array[i].location, boot_info.map.array[i].size); + printf("%i\t\t\t%08x\t\t%u\n", boot_info.map.array[i].type, boot_info.map.array[i].location, boot_info.map.array[i].size); } page_stack.base_pointer = 0xFFC00000; page_stack.stack_pointer = 0xFFC00000; @@ -238,5 +238,4 @@ int initialize(void *multiboot_info) load_module(&kernel, &boot_info.modules[i]); } // TODO: enter first process - putchar('&'); } From 4900febfd91ec310a80673783c2022a22c856a66 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Tue, 13 Apr 2021 00:25:34 -0500 Subject: [PATCH 087/109] Fixed wraparound problem in compare_regions() --- src/memorymap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/memorymap.c b/src/memorymap.c index 543e89a..e484360 100644 --- a/src/memorymap.c +++ b/src/memorymap.c @@ -5,11 +5,13 @@ int compare_regions(struct memory_region_t *lhs, struct memory_region_t *rhs) { if(lhs->location == rhs->location) { - return lhs->size - rhs->size; + return lhs->size > rhs->size ? 1 + : (lhs->size == rhs->size ? 0 + : -1); } else { - return lhs->location - rhs->location; + return lhs->location > rhs->location ? 1 : -1; } } From dd188132b9dfb9428532e0f3f4b25b10f1144a78 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Tue, 13 Apr 2021 00:26:59 -0500 Subject: [PATCH 088/109] Moved x86 ISR stubs to quark_x86.c --- src/x86/quark_x86.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 20258cd..1b04961 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -118,6 +118,42 @@ struct page_stack_t page_stack; struct kernel_t kernel; +__attribute__ ((interrupt)) +void genericISR(void* frame) +{ + +} + +__attribute__ ((interrupt)) +void divisionByZero(void* frame) +{ + +} + +__attribute__ ((interrupt)) +void gpFaultHandler(void* frame, unsigned int error) +{ + +} + +__attribute__ ((interrupt)) +void pageFaultHandler(void* frame, unsigned int error) +{ + +} + +__attribute__ ((interrupt)) +void doubleFaultHandler(void* frame, unsigned int error) +{ + asm("hlt"); +} + +__attribute__ ((interrupt)) +void syscallHandler(void* frame) +{ + +} + void lidt() { struct idt_info_t idt_info; From 4e6f487a0acd09f51a4c0e85b16347b3ff8adedb Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 00:11:44 -0500 Subject: [PATCH 089/109] Moved ISRs and multiboot2 code to separate files --- src/x86/isr.c | 37 +++++++++ src/x86/isr.h | 19 +++++ src/x86/multiboot2.c | 53 +++++++++++++ src/x86/multiboot2.h | 83 ++++++++++++++++++++ src/x86/quark_x86.c | 176 ++----------------------------------------- 5 files changed, 199 insertions(+), 169 deletions(-) create mode 100644 src/x86/isr.c create mode 100644 src/x86/isr.h create mode 100644 src/x86/multiboot2.c create mode 100644 src/x86/multiboot2.h diff --git a/src/x86/isr.c b/src/x86/isr.c new file mode 100644 index 0000000..91942ca --- /dev/null +++ b/src/x86/isr.c @@ -0,0 +1,37 @@ +#include "isr.h" + +__attribute__ ((interrupt)) +void genericISR(void* frame) +{ + +} + +__attribute__ ((interrupt)) +void divisionByZero(void* frame) +{ + +} + +__attribute__ ((interrupt)) +void gpFaultHandler(void* frame, unsigned int error) +{ + +} + +__attribute__ ((interrupt)) +void pageFaultHandler(void* frame, unsigned int error) +{ + +} + +__attribute__ ((interrupt)) +void doubleFaultHandler(void* frame, unsigned int error) +{ + asm("hlt"); +} + +__attribute__ ((interrupt)) +void syscallHandler(void* frame) +{ + +} \ No newline at end of file diff --git a/src/x86/isr.h b/src/x86/isr.h new file mode 100644 index 0000000..00c1723 --- /dev/null +++ b/src/x86/isr.h @@ -0,0 +1,19 @@ +#pragma once + +__attribute__ ((interrupt)) +void genericISR(void* frame); + +__attribute__ ((interrupt)) +void divisionByZero(void* frame); + +__attribute__ ((interrupt)) +void gpFaultHandler(void* frame, unsigned int error); + +__attribute__ ((interrupt)) +void pageFaultHandler(void* frame, unsigned int error); + +__attribute__ ((interrupt)) +void doubleFaultHandler(void* frame, unsigned int error); + +__attribute__ ((interrupt)) +void syscallHandler(void* frame); \ No newline at end of file diff --git a/src/x86/multiboot2.c b/src/x86/multiboot2.c new file mode 100644 index 0000000..bb7fc4e --- /dev/null +++ b/src/x86/multiboot2.c @@ -0,0 +1,53 @@ +#include "multiboot2.h" + +void *read_multiboot_table(struct boot_info_t *boot_info, void *table) +{ + uint32_t *int_table = (uint32_t *)table; + switch (*int_table) + { + case MB_END_TAG: + return NULL; + case MB_MEMORY_MAP: ; + unsigned int tag_size = ((struct multiboot2_memory_map_t*) table)->size - 16; + unsigned int entry_size = ((struct multiboot2_memory_map_t*) table)->entry_size; + struct multiboot2_map_entry_t *entry = &((struct multiboot2_memory_map_t*) table)->entries; + while(tag_size) + { + unsigned int entry_type = + entry->type == MB_AVAILABLE ? M_AVAILABLE + : (entry->type == MB_DEFECTIVE ? M_DEFECTIVE + : M_UNAVAILABLE); + insert_region(&boot_info->map, entry->base, entry->length, entry_type); + entry = (struct multiboot2_map_entry_t*) ((void*) entry + entry_size); + tag_size -= entry_size; + } + break; + case MB_MODULE: + if(boot_info->module_count < 8) + { + boot_info->modules[boot_info->module_count].start = ((struct multiboot2_module_t*) table)->start; + boot_info->modules[boot_info->module_count].end = ((struct multiboot2_module_t*) table)->end; + strcpy(boot_info->modules[boot_info->module_count].str, ((struct multiboot2_module_t*) table)->str); + insert_region(&boot_info->map, + ((struct multiboot2_module_t*) table)->start, + ((struct multiboot2_module_t*) table)->end - ((struct multiboot2_module_t*) table)->start, + M_UNAVAILABLE); + boot_info->module_count++; + } + else + { + printf("WARNING: Too many modules, must skip one.\n"); + } + break; + case MB_BOOT_COMMAND: + strcpy(boot_info->parameters, &((struct multiboot2_string_t*) table)->str); + break; + case MB_BOOTLOADER: + strcpy(boot_info->bootloader, &((struct multiboot2_string_t*) table)->str); + break; + default: + break; + } + size_t size = (int_table[1] + 7) - ((int_table[1] + 7) % 8); + return table + size; +} diff --git a/src/x86/multiboot2.h b/src/x86/multiboot2.h new file mode 100644 index 0000000..b417ca4 --- /dev/null +++ b/src/x86/multiboot2.h @@ -0,0 +1,83 @@ +#pragma once + +#include "memorymap.h" +#include +#include + +#define module_limit 8 + +enum multiboot2_tag_types +{ + MB_END_TAG = 0, + MB_BOOT_COMMAND = 1, + MB_BOOTLOADER = 2, + MB_MODULE = 3, + MB_MEMORY_INFO = 4, + MB_BIOS_BOOT_DEVICE = 5, + MB_MEMORY_MAP = 6, + MB_VBE = 7, + MB_FRAMEBUFFER = 8, + MB_ELF_SYMBOLS = 9, + MB_APM = 10, + MB_EFI32_SYSTEM_TABLE = 11, + MB_EFI64_SYSTEM_TABLE = 12, + MB_SMBIOS = 13, + MB_ACPI10_RSDP = 14, + MB_ACPT20_RSDP = 15, + MB_NETOWRK = 16, + MB_EFI_MEMORY_MAP = 17, + MB_EFI_BOOT_SERVICES = 18, + MB_EFI32_IMAGE = 19, + MB_EFI64_IMAGE = 20, + MB_LOAD_ADDRESS = 21 +}; + +enum multiboot2_memory_types +{ + MB_AVAILABLE = 1, + MB_ACPI = 3, + MB_DEFECTIVE = 5 +}; + +struct multiboot2_string_t +{ + uint32_t type; + uint32_t size; + char str; +}; + +struct multiboot2_module_t +{ + uint32_t type; + uint32_t size; + uint32_t start; + uint32_t end; + char str; +}; + +struct multiboot2_map_entry_t +{ + uint64_t base; + uint64_t length; + uint32_t type; +}; + +struct multiboot2_memory_map_t +{ + uint32_t type; + uint32_t size; + uint32_t entry_size; + uint32_t entry_version; + struct multiboot2_map_entry_t entries; +}; + +struct boot_info_t +{ + char *bootloader; + char *parameters; + size_t module_count; + struct memory_map_t map; + struct module_t modules[module_limit]; +}; + +void *read_multiboot_table(struct boot_info_t *boot_info, void *table); diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 1b04961..9ac084d 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -1,5 +1,6 @@ #include "kernel.h" #include "pageallocator.h" +#include "multiboot2.h" #include "memorymap.h" #include "stdio.h" #include "string.h" @@ -7,8 +8,6 @@ #include #include -#define module_limit 8 - enum isr_type_t { INTERRPUT_TASK32 = 5, @@ -36,125 +35,11 @@ struct idt_info_t void *location; }; -enum multiboot2_tag_types -{ - MB_END_TAG = 0, - MB_BOOT_COMMAND = 1, - MB_BOOTLOADER = 2, - MB_MODULE = 3, - MB_MEMORY_INFO = 4, - MB_BIOS_BOOT_DEVICE = 5, - MB_MEMORY_MAP = 6, - MB_VBE = 7, - MB_FRAMEBUFFER = 8, - MB_ELF_SYMBOLS = 9, - MB_APM = 10, - MB_EFI32_SYSTEM_TABLE = 11, - MB_EFI64_SYSTEM_TABLE = 12, - MB_SMBIOS = 13, - MB_ACPI10_RSDP = 14, - MB_ACPT20_RSDP = 15, - MB_NETOWRK = 16, - MB_EFI_MEMORY_MAP = 17, - MB_EFI_BOOT_SERVICES = 18, - MB_EFI32_IMAGE = 19, - MB_EFI64_IMAGE = 20, - MB_LOAD_ADDRESS = 21 -}; -enum multiboot2_memory_types -{ - MB_AVAILABLE = 1, - MB_ACPI = 3, - MB_DEFECTIVE = 5 -}; - -struct multiboot2_string_t -{ - uint32_t type; - uint32_t size; - char str; -}; - -struct multiboot2_module_t -{ - uint32_t type; - uint32_t size; - uint32_t start; - uint32_t end; - char str; -}; - -struct multiboot2_map_entry_t -{ - uint64_t base; - uint64_t length; - uint32_t type; -}; - -struct multiboot2_memory_map_t -{ - uint32_t type; - uint32_t size; - uint32_t entry_size; - uint32_t entry_version; - struct multiboot2_map_entry_t entries; -}; - -struct boot_info_t -{ - char *bootloader; - char *parameters; - size_t module_count; - struct memory_map_t map; - struct module_t modules[module_limit]; -}; extern int _kernelEnd; -struct interrupt_descriptor_t idt[256]; - -struct page_stack_t page_stack; - -struct kernel_t kernel; - -__attribute__ ((interrupt)) -void genericISR(void* frame) -{ - -} - -__attribute__ ((interrupt)) -void divisionByZero(void* frame) -{ - -} - -__attribute__ ((interrupt)) -void gpFaultHandler(void* frame, unsigned int error) -{ - -} - -__attribute__ ((interrupt)) -void pageFaultHandler(void* frame, unsigned int error) -{ - -} - -__attribute__ ((interrupt)) -void doubleFaultHandler(void* frame, unsigned int error) -{ - asm("hlt"); -} - -__attribute__ ((interrupt)) -void syscallHandler(void* frame) -{ - -} - -void lidt() +void lidt(struct interrupt_descriptor_t *idt) { struct idt_info_t idt_info; idt_info.size = sizeof(idt) - 1; @@ -187,60 +72,11 @@ int startPaging(uint32_t *directory, uint32_t *table, uint32_t *identityTable) return 0; } -void *read_multiboot_table(struct boot_info_t *boot_info, void *table) -{ - uint32_t *int_table = (uint32_t *)table; - switch (*int_table) - { - case MB_END_TAG: - return NULL; - case MB_MEMORY_MAP: ; - unsigned int tag_size = ((struct multiboot2_memory_map_t*) table)->size - 16; - unsigned int entry_size = ((struct multiboot2_memory_map_t*) table)->entry_size; - struct multiboot2_map_entry_t *entry = &((struct multiboot2_memory_map_t*) table)->entries; - while(tag_size) - { - unsigned int entry_type = - entry->type == MB_AVAILABLE ? M_AVAILABLE - : (entry->type == MB_DEFECTIVE ? M_DEFECTIVE - : M_UNAVAILABLE); - insert_region(&boot_info->map, entry->base, entry->length, entry_type); - entry = (struct multiboot2_map_entry_t*) ((void*) entry + entry_size); - tag_size -= entry_size; - } - break; - case MB_MODULE: - if(boot_info->module_count < 8) - { - boot_info->modules[boot_info->module_count].start = ((struct multiboot2_module_t*) table)->start; - boot_info->modules[boot_info->module_count].end = ((struct multiboot2_module_t*) table)->end; - strcpy(boot_info->modules[boot_info->module_count].str, ((struct multiboot2_module_t*) table)->str); - insert_region(&boot_info->map, - ((struct multiboot2_module_t*) table)->start, - ((struct multiboot2_module_t*) table)->end - ((struct multiboot2_module_t*) table)->start, - M_UNAVAILABLE); - boot_info->module_count++; - } - else - { - printf("WARNING: Too many modules, must skip one.\n"); - } - break; - case MB_BOOT_COMMAND: - strcpy(boot_info->parameters, &((struct multiboot2_string_t*) table)->str); - break; - case MB_BOOTLOADER: - strcpy(boot_info->bootloader, &((struct multiboot2_string_t*) table)->str); - break; - default: - break; - } - size_t size = (int_table[1] + 7) - ((int_table[1] + 7) % 8); - return table + size; -} - int initialize(void *multiboot_info) { + static struct interrupt_descriptor_t idt[256]; + static struct page_stack_t page_stack; + static struct kernel_t kernel; struct memory_region_t map_array[16]; char bootloader_name[64]; char kernel_parameters[64]; @@ -273,5 +109,7 @@ int initialize(void *multiboot_info) { load_module(&kernel, &boot_info.modules[i]); } + // TODO: setup IDT + // TODO: enter first process } From 61a50fef10c405664c41e3f3e79443f3044b4509 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 00:12:02 -0500 Subject: [PATCH 090/109] Inproved formatting on struct initializer --- src/memorymap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/memorymap.c b/src/memorymap.c index e484360..2adef20 100644 --- a/src/memorymap.c +++ b/src/memorymap.c @@ -90,7 +90,10 @@ int trim_map(struct memory_map_t *map, int index) } else { - struct memory_region_t new_right = {.location = right.location + right.size, .size = (left.location + left.size) - (right.location + right.size), .type = left.type}; + struct memory_region_t new_right = { + .location = right.location + right.size, + .size = (left.location + left.size) - (right.location + right.size), + .type = left.type}; left.size = (right.location > left.location) ? right.location - left.location : 0; if(left.size == 0) remove_map_entry(map, index); From 4c2ded8676817c996765647922472fe03aa18c98 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 00:52:12 -0500 Subject: [PATCH 091/109] Fixed missing includes for multiboot2 files --- src/x86/multiboot2.c | 2 ++ src/x86/multiboot2.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/x86/multiboot2.c b/src/x86/multiboot2.c index bb7fc4e..c692b5f 100644 --- a/src/x86/multiboot2.c +++ b/src/x86/multiboot2.c @@ -1,4 +1,6 @@ #include "multiboot2.h" +#include "stdio.h" +#include "string.h" void *read_multiboot_table(struct boot_info_t *boot_info, void *table) { diff --git a/src/x86/multiboot2.h b/src/x86/multiboot2.h index b417ca4..ce65ddb 100644 --- a/src/x86/multiboot2.h +++ b/src/x86/multiboot2.h @@ -1,6 +1,7 @@ #pragma once #include "memorymap.h" +#include "module.h" #include #include From 6f625451caa8b11121820f5ca58e10005d017345 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 00:52:29 -0500 Subject: [PATCH 092/109] Added new source files to Makefile.am --- src/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index 1832fa8..f602e69 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,8 @@ quark_kernel_LDFLAGS = -nostdlib if x86 quark_kernel_SOURCES += x86/mmgr.c \ x86/putc.c \ + x86/multiboot2.c \ + x86/isr.c \ x86/quark_x86.c \ x86/entry.S quark_kernel_LDFLAGS += -T x86/linker.ld From 9f0867393f702e943cb680028dafec4886d3ba63 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 00:52:56 -0500 Subject: [PATCH 093/109] Some cleanup in quark_x86.c --- src/x86/quark_x86.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 9ac084d..8a29541 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -35,8 +35,6 @@ struct idt_info_t void *location; }; - - extern int _kernelEnd; void lidt(struct interrupt_descriptor_t *idt) @@ -103,8 +101,6 @@ int initialize(void *multiboot_info) page_stack.stack_pointer = 0xFFC00000; page_stack.limit_pointer = 0xFF900000; initialize_page_stack(&page_stack, &boot_info.map, 4096); - - // TODO: Initialize process queue for(int i = 0; i < boot_info.module_count; i++) { load_module(&kernel, &boot_info.modules[i]); From 4a8ca81a10301ce054251bf8b80819214156f19a Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 02:25:57 -0500 Subject: [PATCH 094/109] Started header for APIC structures --- src/x86/apic.h | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 src/x86/apic.h diff --git a/src/x86/apic.h b/src/x86/apic.h new file mode 100644 index 0000000..80d688f --- /dev/null +++ b/src/x86/apic.h @@ -0,0 +1,154 @@ +#pragma once + +#include + +enum apic_delivery_mode_t +{ + APIC_DELIVERY_MODE_FIXED = 0b000, + APIC_DELIVERY_MODE_LOWEST_PRIORITY = 0b001, + APIC_DELIVERY_MODE_SMI = 0b010, + APIC_DELIVERY_MODE_NMI = 0b100, + APIC_DELIVERY_MODE_INIT = 0b101, + APIC_DELIVERY_MODE_SIPI = 0b110, + APIV_DELIVERY_MODE_EXTINIT = 0b111 +}; + +enum apic_destination_mode_t +{ + APIC_DESTINATION_MODE_PHYSICAL = 0, + APIC_DESTINATION_MODE_LOGICAL = 1 +}; + +enum apic_level_t +{ + APIC_LEVEL_DEASSERT = 0, + APIC_LEVEL_ASSERT = 1 +}; +enum apic_trigger_mode_t +{ + APIC_TRIGGER_MODE_EDGE = 0, + APIC_TRIGGER_MODE_LEVEL = 1 +}; + +enum apic_destination_shorthand_t +{ + APIC_DEST_SHORTHAND_NONE = 0, + APIC_DEST_SHORTHAND_SELF = 1, + APIC_DEST_SHORTHAND_ALL = 2, + APIC_DEST_SHORTHAND_OTHERS = 3 +}; + +enum apic_divide_mode_t +{ + APIC_DIVIDE_1 = 0b1011, + APIC_DIVIDE_2 = 0b0000, + APIC_DIVIDE_4 = 0b0001, + APIC_DIVIDE_8 = 0b0010, + APIC_DIVIDE_16 = 0b0011, + APIC_DIVIDE_32 = 0b1000, + APIC_DIVIDE_64 = 0b1001, + APIC_DIVIDE_128 = 0b1011 +}; + +enum apic_timer_mode_t +{ + APIC_TIMER_ONESHOT = 0, + APIC_TIMER_PERIODIC = 1, + APIC_TIMER_TSCDEADLINE = 2 +}; + +struct apic_register_t +{ + uint32_t value; + uint32_t padding[3]; +}; + +struct apic_lapic_version_t +{ + uint32_t version : 8; + uint32_t reserved_1 : 8; + uint32_t max_lvt_entry : 8; + uint32_t suppress_eoi_broadcast : 1; + uint32_t reserved_2 : 7; + uint32_t padding[3]; +}; + +struct apic_lvt_t +{ + uint32_t vector: 8; + uint32_t delivery_mode : 3; + uint32_t reserved_1 : 1; + uint32_t delivery_status : 1; + uint32_t pin_polarity : 1; + uint32_t remote_irr : 1; + uint32_t trigger_mode : 1; + uint32_t mask : 1; + uint32_t timer_mode : 2; + uint32_t reserved_2 : 13; + uint32_t padding[3]; +}; + +struct apic_icr_t +{ + uint32_t vector : 8; + uint32_t delivery_mode : 3; + uint32_t destination_mode : 1; + uint32_t delivery_status : 1; + uint32_t reserved_1 : 1; + uint32_t level : 1; + uint32_t trigger_mode : 1; + uint32_t reserved_2 : 2; + uint32_t destination_shorthand : 2; + uint32_t reserved_3 : 12; + uint32_t padding_1[3]; + uint32_t reserved : 24; + uint32_t destination : 8; + uint32_t padding_2[3]; +}; + +struct apic_registers_t +{ + struct apic_register_t reserved_1[2]; + struct apic_register_t lapic_id; + struct apic_lapic_version_t lapic_version; + struct apic_register_t reserved_2[4]; + struct apic_register_t task_priority; + struct apic_register_t arbitration_priority; + struct apic_register_t processor_priority; + struct apic_register_t eoi; + struct apic_register_t remote_read; + struct apic_register_t logical_destination; + struct apic_register_t destination_format; + struct apic_register_t spurious_iv; + struct apic_register_t in_service[8]; + struct apic_register_t trigger_mode[8]; + struct apic_register_t interrupt_request[8]; + struct apic_register_t error_status; + struct apic_register_t reserved_3[6]; + struct apic_lvt_t lvt_cmci; + struct apic_icr_t interrput_command; + struct apic_lvt_t lvt_timer; + struct apic_lvt_t lvt_thermal_sensor; + struct apic_lvt_t lvt_performance_counters; + struct apic_lvt_t lvt_lint0; + struct apic_lvt_t lvt_lint1; + struct apic_lvt_t lvt_error; + struct apic_register_t initial_count; + struct apic_register_t current_count; + struct apic_register_t reserved_4[4]; + struct apic_register_t divide_config; + struct apic_register_t reserved_5; +}; + +void apic_enable(struct apic_registers_t volatile *apic_registers); + +void apic_eoi(struct apic_registers_t volatile *apic_registers); + +void apic_send_ipi(struct apic_registers_t volatile *apic_registers, + uint32_t vector, + enum apic_delivery_mode_t delivery_mode, + enum apic_destination_mode_t destination_mode, + enum apic_level_t level, + enum apic_trigger_mode_t trigger_mode, + enum apic_destination_shorthand_t shorthand, + uint32_t destination); From 29544b0eb82b0d0906dbc0811d3c0100e89466e4 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 02:46:04 -0500 Subject: [PATCH 095/109] Moved interrupt code to separate file. Added new source file to Makefile.am --- src/Makefile.am | 1 + src/x86/interrupts.c | 29 +++++++++++++++++++++++++++++ src/x86/interrupts.h | 28 ++++++++++++++++++++++++++++ src/x86/quark_x86.c | 41 ++--------------------------------------- 4 files changed, 60 insertions(+), 39 deletions(-) create mode 100644 src/x86/interrupts.c create mode 100644 src/x86/interrupts.h diff --git a/src/Makefile.am b/src/Makefile.am index f602e69..b50d3eb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,7 @@ if x86 quark_kernel_SOURCES += x86/mmgr.c \ x86/putc.c \ x86/multiboot2.c \ + x86/interrupts.c \ x86/isr.c \ x86/quark_x86.c \ x86/entry.S diff --git a/src/x86/interrupts.c b/src/x86/interrupts.c new file mode 100644 index 0000000..d8fb7df --- /dev/null +++ b/src/x86/interrupts.c @@ -0,0 +1,29 @@ +#include "interrupts.h" + +struct idt_info_t +{ + uint16_t size; + void *location; +}; + +void lidt(struct interrupt_descriptor_t *idt) +{ + struct idt_info_t idt_info; + idt_info.size = sizeof(idt) - 1; + idt_info.location = (void *)&idt; + asm("lidt (%0)" + : + : "r"(&idt_info)); +} + +void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage) +{ + descriptor->offset_1 = (uint32_t) isr & 0xFFFF; + descriptor->offset_2 = (uint32_t) isr >> 16; + descriptor->selector = 8; + descriptor->zero = 0; + descriptor->type = type; + descriptor->storage = 0; + descriptor->dpl = privilage; + descriptor->present = 1; +} diff --git a/src/x86/interrupts.h b/src/x86/interrupts.h new file mode 100644 index 0000000..7a9a8be --- /dev/null +++ b/src/x86/interrupts.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +enum isr_type_t +{ + INTERRPUT_TASK32 = 5, + INTERRPUT_TRAP32 = 15, + INTERRPUT_INT32 = 14, + INTERRPUT_TRAP16 = 7, + INTERRPUT_INT16 = 6 +}; + +struct interrupt_descriptor_t +{ + uint16_t offset_1; + uint16_t selector; + uint16_t zero : 8; + uint16_t type : 4; + uint16_t storage : 1; + uint16_t dpl : 2; + uint16_t present : 1; + uint16_t offset_2; +}; + +void lidt(struct interrupt_descriptor_t *idt); + +void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage); diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 8a29541..2f6fef7 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -2,51 +2,14 @@ #include "pageallocator.h" #include "multiboot2.h" #include "memorymap.h" +#include "interrupts.h" #include "stdio.h" -#include "string.h" #include "module.h" #include #include -enum isr_type_t -{ - INTERRPUT_TASK32 = 5, - INTERRPUT_TRAP32 = 15, - INTERRPUT_INT32 = 14, - INTERRPUT_TRAP16 = 7, - INTERRPUT_INT16 = 6 -}; - -struct interrupt_descriptor_t -{ - uint16_t m_offset1; - uint16_t m_selector; - uint16_t m_zero : 8; - uint16_t m_type : 4; - uint16_t m_storage : 1; - uint16_t m_dpl : 2; - uint16_t m_present : 1; - uint16_t m_offset2; -}; - -struct idt_info_t -{ - uint16_t size; - void *location; -}; - extern int _kernelEnd; -void lidt(struct interrupt_descriptor_t *idt) -{ - struct idt_info_t idt_info; - idt_info.size = sizeof(idt) - 1; - idt_info.location = (void *)&idt; - asm("lidt (%0)" - : - : "r"(&idt_info)); -} - int startPaging(uint32_t *directory, uint32_t *table, uint32_t *identityTable) { for (int i = 0; i < 1024; i++) @@ -106,6 +69,6 @@ int initialize(void *multiboot_info) load_module(&kernel, &boot_info.modules[i]); } // TODO: setup IDT - + // TODO: enter first process } From eef1741e16081ff3c9dca2407be1c1ce8aef2e29 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 03:25:21 -0500 Subject: [PATCH 096/109] Added enum listing x86 exception codes --- src/x86/interrupts.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/x86/interrupts.h b/src/x86/interrupts.h index 7a9a8be..fa2ffc5 100644 --- a/src/x86/interrupts.h +++ b/src/x86/interrupts.h @@ -2,6 +2,30 @@ #include +enum exception_code_t +{ + EXCEPTION_DIV_BY_0 = 0, + EXCEPTION_DEBUG = 1, + EXCEPTION_NMI = 2, + EXCEPTION_BREAKPOINT = 3, + EXCEPTION_OVERFLOW = 4, + EXCEPTION_OUT_OF_BOUNDS = 5, + EXCEPTION_INVALID_OPCODE = 6, + EXCEPTION_DEVICE_NOT_AVAILABLE = 7, + EXCEPTION_DOUBLE_FAULT = 8, + EXCEPTION_INVALID_TSS = 10, + EXCEPTION_SEGMENT_NOT_PRESENT = 11, + EXCEPTION_STACK_SEGMENT_FAULT = 12, + EXCEPTION_GPF = 13, + EXCEPTION_PAGE_FAULT = 14, + EXCEPTION_x87_FLOATING_POINT = 16, + EXCEPTION_ALIGNMENT_CHECK = 17, + EXCEPTION_MACHINE_CHECK = 18, + EXCEPTION_SIMD_FLOATING_POINT = 19, + EXCEPTION_VIRTUALIZATION = 20, + EXCEPTION_SECURITY = 30 +}; + enum isr_type_t { INTERRPUT_TASK32 = 5, From 507b0fa53e853183dc7c3c083097b83896c586be Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 03:25:55 -0500 Subject: [PATCH 097/109] Renamed ISR functions to fit convention --- src/x86/isr.c | 12 ++++++------ src/x86/isr.h | 13 +++++-------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/x86/isr.c b/src/x86/isr.c index 91942ca..34642c4 100644 --- a/src/x86/isr.c +++ b/src/x86/isr.c @@ -1,37 +1,37 @@ #include "isr.h" __attribute__ ((interrupt)) -void genericISR(void* frame) +void generic_isr(void* frame) { } __attribute__ ((interrupt)) -void divisionByZero(void* frame) +void isr_division_by_zero(void* frame) { } __attribute__ ((interrupt)) -void gpFaultHandler(void* frame, unsigned int error) +void isr_gp_fault(void* frame, unsigned int error) { } __attribute__ ((interrupt)) -void pageFaultHandler(void* frame, unsigned int error) +void isr_page_fault(void* frame, unsigned int error) { } __attribute__ ((interrupt)) -void doubleFaultHandler(void* frame, unsigned int error) +void isr_double_fault(void* frame, unsigned int error) { asm("hlt"); } __attribute__ ((interrupt)) -void syscallHandler(void* frame) +void isr_syscall(void* frame) { } \ No newline at end of file diff --git a/src/x86/isr.h b/src/x86/isr.h index 00c1723..0940f61 100644 --- a/src/x86/isr.h +++ b/src/x86/isr.h @@ -1,19 +1,16 @@ #pragma once __attribute__ ((interrupt)) -void genericISR(void* frame); +void isr_division_by_zero(void* frame); __attribute__ ((interrupt)) -void divisionByZero(void* frame); +void isr_gp_fault(void* frame, unsigned int error); __attribute__ ((interrupt)) -void gpFaultHandler(void* frame, unsigned int error); +void isr_page_fault(void* frame, unsigned int error); __attribute__ ((interrupt)) -void pageFaultHandler(void* frame, unsigned int error); +void isr_double_fault(void* frame, unsigned int error); __attribute__ ((interrupt)) -void doubleFaultHandler(void* frame, unsigned int error); - -__attribute__ ((interrupt)) -void syscallHandler(void* frame); \ No newline at end of file +void isr_syscall(void* frame); \ No newline at end of file From 48c042ca5f9d0f4fcf5df38bc5d33324104524ec Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 03:39:07 -0500 Subject: [PATCH 098/109] Added declaration for panic() function --- include/kernel.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/kernel.h b/include/kernel.h index 86c89a9..9f6da99 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -14,3 +14,5 @@ extern struct kernel_t kernel; int do_syscall(struct kernel_t *kernel, size_t id, size_t arg1, size_t arg2, size_t arg3); int load_module(struct kernel_t *kernel, struct module_t *module); + +void panic(const char *message) __attribute__ ((noreturn)); From 3130b07fd1c1ff283b5ca9a064f32620ad47fdea Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 03:39:25 -0500 Subject: [PATCH 099/109] Removed generic_isr() definition --- src/x86/isr.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/x86/isr.c b/src/x86/isr.c index 34642c4..d5094bf 100644 --- a/src/x86/isr.c +++ b/src/x86/isr.c @@ -1,11 +1,5 @@ #include "isr.h" -__attribute__ ((interrupt)) -void generic_isr(void* frame) -{ - -} - __attribute__ ((interrupt)) void isr_division_by_zero(void* frame) { From 8851243f19bec9dfb8ed7113f7cc66e27ce36bc7 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 20:23:13 -0500 Subject: [PATCH 100/109] Wrote empty definitions for some APIC functions Started x86 interrupt setup code --- src/x86/apic.c | 23 +++++++++++++++++++++++ src/x86/apic.h | 8 +++++--- src/x86/quark_x86.c | 27 +++++++++++++++++++++++---- 3 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 src/x86/apic.c diff --git a/src/x86/apic.c b/src/x86/apic.c new file mode 100644 index 0000000..1d677e7 --- /dev/null +++ b/src/x86/apic.c @@ -0,0 +1,23 @@ +#include "apic.h" + +void apic_enable() +{ + +} + +void apic_eoi() +{ + +} + +void apic_send_ipi( + uint32_t vector, + enum apic_delivery_mode_t delivery_mode, + enum apic_destination_mode_t destination_mode, + enum apic_level_t level, + enum apic_trigger_mode_t trigger_mode, + enum apic_destination_shorthand_t shorthand, + uint32_t destination) +{ + +} \ No newline at end of file diff --git a/src/x86/apic.h b/src/x86/apic.h index 80d688f..65e7739 100644 --- a/src/x86/apic.h +++ b/src/x86/apic.h @@ -140,11 +140,13 @@ struct apic_registers_t struct apic_register_t reserved_5; }; -void apic_enable(struct apic_registers_t volatile *apic_registers); +extern struct apic_registers_t volatile *apic_registers; -void apic_eoi(struct apic_registers_t volatile *apic_registers); +void apic_enable(); -void apic_send_ipi(struct apic_registers_t volatile *apic_registers, +void apic_eoi(); + +void apic_send_ipi( uint32_t vector, enum apic_delivery_mode_t delivery_mode, enum apic_destination_mode_t destination_mode, diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 2f6fef7..aa66c09 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -2,14 +2,19 @@ #include "pageallocator.h" #include "multiboot2.h" #include "memorymap.h" +#include "apic.h" #include "interrupts.h" #include "stdio.h" +#include "string.h" #include "module.h" +#include "isr.h" #include #include extern int _kernelEnd; +struct apic_registers_t volatile *apic_registers; + int startPaging(uint32_t *directory, uint32_t *table, uint32_t *identityTable) { for (int i = 0; i < 1024; i++) @@ -60,15 +65,29 @@ int initialize(void *multiboot_info) { printf("%i\t\t\t%08x\t\t%u\n", boot_info.map.array[i].type, boot_info.map.array[i].location, boot_info.map.array[i].size); } - page_stack.base_pointer = 0xFFC00000; - page_stack.stack_pointer = 0xFFC00000; - page_stack.limit_pointer = 0xFF900000; + page_stack.base_pointer = (physaddr_t*)0xFFC00000; + page_stack.stack_pointer = (physaddr_t*)0xFFC00000; + page_stack.limit_pointer = (physaddr_t*)0xFF900000; initialize_page_stack(&page_stack, &boot_info.map, 4096); for(int i = 0; i < boot_info.module_count; i++) { load_module(&kernel, &boot_info.modules[i]); } // TODO: setup IDT - + memset(idt, 0, sizeof(struct interrupt_descriptor_t) * 256); + create_interrupt_descriptor(&idt[EXCEPTION_DIV_BY_0], (void*)isr_division_by_zero, INTERRPUT_INT32, 3); + create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_INT32, 3); + create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_INT32, 3); + create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_INT32, 3); + create_interrupt_descriptor(&idt[0x80], (void*)isr_syscall, INTERRPUT_INT32, 3); + + // TODO: setup APIC + asm volatile( + "mov $0xFF, %%al;" + "outb %%al, $0xA1;" + "outb %%al, $0x21;" + ::: "al" + ); + apic_enable(); // TODO: enter first process } From c47a3dd73b294ed363bc2f6d780f6dc7594e8838 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Wed, 14 Apr 2021 20:23:30 -0500 Subject: [PATCH 101/109] Added apic.c to Makefile.am --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index b50d3eb..b5d9d20 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,6 +9,7 @@ quark_kernel_SOURCES += x86/mmgr.c \ x86/putc.c \ x86/multiboot2.c \ x86/interrupts.c \ + x86/apic.c \ x86/isr.c \ x86/quark_x86.c \ x86/entry.S From 8eafcf899b7ee9550aa0473791058998f4880f41 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Thu, 15 Apr 2021 04:44:41 -0500 Subject: [PATCH 102/109] Wrote some simple MSR code --- src/x86/msr.c | 17 +++++++++++++++++ src/x86/msr.h | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/x86/msr.c create mode 100644 src/x86/msr.h diff --git a/src/x86/msr.c b/src/x86/msr.c new file mode 100644 index 0000000..4182a2d --- /dev/null +++ b/src/x86/msr.c @@ -0,0 +1,17 @@ +#include "msr.h" + +void read_msr(enum msr_id_t msr_addr, uint64_t *value) +{ + uint64_t v; + asm volatile("rdmsr" + : "=edx:eax" (v) + : "ecx" (msr_addr)); + *value = v; +} + +void write_msr(enum msr_id_t msr_addr, uint64_t *value) +{ + uint64_t v = *value; + asm volatile("wrmsr" + :: "ecx"(msr_addr), "A"(v)); +} diff --git a/src/x86/msr.h b/src/x86/msr.h new file mode 100644 index 0000000..ea09f03 --- /dev/null +++ b/src/x86/msr.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +enum msr_id_t +{ + MSR_APIC_BASE = 0x1B +}; + +struct msr_apic_base_t +{ + uint64_t reserved_1 : 8; + uint64_t bsp : 1; + uint64_t reserved_2 : 1; + uint64_t x2apic_enable : 1; + uint64_t apic_global_enable : 1; + uint64_t apic_base : 52; +}; + +void read_msr(enum msr_id_t msr_addr, uint64_t *value); + +void write_msr(enum msr_id_t msr_addr, uint64_t *value); From d2617e44883fc0195a5df1634e09446317775dfc Mon Sep 17 00:00:00 2001 From: ngiddings Date: Thu, 15 Apr 2021 04:51:23 -0500 Subject: [PATCH 103/109] Wrote new ISR for AP entry --- src/x86/interrupts.h | 6 ++++-- src/x86/isr.c | 9 +++++++++ src/x86/isr.h | 3 +++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/x86/interrupts.h b/src/x86/interrupts.h index fa2ffc5..d8ff3b9 100644 --- a/src/x86/interrupts.h +++ b/src/x86/interrupts.h @@ -2,7 +2,7 @@ #include -enum exception_code_t +enum interrupt_code_t { EXCEPTION_DIV_BY_0 = 0, EXCEPTION_DEBUG = 1, @@ -23,7 +23,9 @@ enum exception_code_t EXCEPTION_MACHINE_CHECK = 18, EXCEPTION_SIMD_FLOATING_POINT = 19, EXCEPTION_VIRTUALIZATION = 20, - EXCEPTION_SECURITY = 30 + EXCEPTION_SECURITY = 30, + ISR_AP_START = 127, + ISR_SYSCALL = 128 }; enum isr_type_t diff --git a/src/x86/isr.c b/src/x86/isr.c index d5094bf..0148ec1 100644 --- a/src/x86/isr.c +++ b/src/x86/isr.c @@ -24,6 +24,15 @@ void isr_double_fault(void* frame, unsigned int error) asm("hlt"); } +__attribute__ ((interrupt, naked)) +void isr_ap_start(void* frame) +{ + asm(".code16"); + //... + asm(".code32"); + // do something useful +} + __attribute__ ((interrupt)) void isr_syscall(void* frame) { diff --git a/src/x86/isr.h b/src/x86/isr.h index 0940f61..ab1c80f 100644 --- a/src/x86/isr.h +++ b/src/x86/isr.h @@ -12,5 +12,8 @@ void isr_page_fault(void* frame, unsigned int error); __attribute__ ((interrupt)) void isr_double_fault(void* frame, unsigned int error); +__attribute__ ((interrupt, naked)) +void isr_ap_start(void* frame); + __attribute__ ((interrupt)) void isr_syscall(void* frame); \ No newline at end of file From 1e6b8885152188dae1b119b5d6ee00f96277f277 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Thu, 15 Apr 2021 04:51:37 -0500 Subject: [PATCH 104/109] Added msr.c to Makefile.am --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index b5d9d20..e696654 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,7 @@ quark_kernel_SOURCES += x86/mmgr.c \ x86/interrupts.c \ x86/apic.c \ x86/isr.c \ + x86/msr.c \ x86/quark_x86.c \ x86/entry.S quark_kernel_LDFLAGS += -T x86/linker.ld From ac0e5261ba0de119d4553da44040382d54035b7e Mon Sep 17 00:00:00 2001 From: ngiddings Date: Thu, 15 Apr 2021 04:51:57 -0500 Subject: [PATCH 105/109] Implemented apic_send_ipi() --- src/x86/apic.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/x86/apic.c b/src/x86/apic.c index 1d677e7..9d6d113 100644 --- a/src/x86/apic.c +++ b/src/x86/apic.c @@ -7,7 +7,7 @@ void apic_enable() void apic_eoi() { - + apic_registers->eoi.value = 0; } void apic_send_ipi( @@ -19,5 +19,17 @@ void apic_send_ipi( enum apic_destination_shorthand_t shorthand, uint32_t destination) { - + struct apic_icr_t value = { + .vector = vector, + .delivery_mode = delivery_mode, + .destination_mode = destination_mode, + .level = level, + .trigger_mode = trigger_mode, + .destination_shorthand = shorthand, + .destination = destination + }; + uint32_t *value_addr = (uint32_t*) &value; + uint32_t *icr_addr = (uint32_t*)&apic_registers->interrput_command; + icr_addr[4] = value_addr[4]; + icr_addr[0] = value_addr[0]; } \ No newline at end of file From 923057ee1cdfbad90da51d1ab30f8a9b8ec9989d Mon Sep 17 00:00:00 2001 From: ngiddings Date: Thu, 15 Apr 2021 04:55:28 -0500 Subject: [PATCH 106/109] Removed 'interrupt' attribute from isr_ap_start() Added message to division by 0 exception --- src/x86/isr.c | 5 +++-- src/x86/isr.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/x86/isr.c b/src/x86/isr.c index 0148ec1..8d36841 100644 --- a/src/x86/isr.c +++ b/src/x86/isr.c @@ -1,9 +1,10 @@ #include "isr.h" +#include "stdio.h" __attribute__ ((interrupt)) void isr_division_by_zero(void* frame) { - + printf("Exception: Division by zero\n"); } __attribute__ ((interrupt)) @@ -24,7 +25,7 @@ void isr_double_fault(void* frame, unsigned int error) asm("hlt"); } -__attribute__ ((interrupt, naked)) +__attribute__ ((naked)) void isr_ap_start(void* frame) { asm(".code16"); diff --git a/src/x86/isr.h b/src/x86/isr.h index ab1c80f..1725d53 100644 --- a/src/x86/isr.h +++ b/src/x86/isr.h @@ -12,7 +12,7 @@ void isr_page_fault(void* frame, unsigned int error); __attribute__ ((interrupt)) void isr_double_fault(void* frame, unsigned int error); -__attribute__ ((interrupt, naked)) +__attribute__ ((naked)) void isr_ap_start(void* frame); __attribute__ ((interrupt)) From c5e38801f3b63538b29f2e50e39670eb09ddae1a Mon Sep 17 00:00:00 2001 From: ngiddings Date: Thu, 15 Apr 2021 05:49:11 -0500 Subject: [PATCH 107/109] Fixed the idt_info_t struct and lidt() Info was not loaded properly, causing crash --- src/x86/interrupts.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/x86/interrupts.c b/src/x86/interrupts.c index d8fb7df..aadce4a 100644 --- a/src/x86/interrupts.c +++ b/src/x86/interrupts.c @@ -4,13 +4,13 @@ struct idt_info_t { uint16_t size; void *location; -}; +} __attribute__ ((packed)); void lidt(struct interrupt_descriptor_t *idt) { struct idt_info_t idt_info; - idt_info.size = sizeof(idt) - 1; - idt_info.location = (void *)&idt; + idt_info.size = sizeof(struct interrupt_descriptor_t) * 256 - 1; + idt_info.location = (void *)idt; asm("lidt (%0)" : : "r"(&idt_info)); From 3229f55164af2e78963921bd9751eae36c4983d0 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Thu, 15 Apr 2021 05:49:40 -0500 Subject: [PATCH 108/109] Added some code in initialize() to test interrupts --- src/x86/linker.ld | 2 +- src/x86/quark_x86.c | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/x86/linker.ld b/src/x86/linker.ld index df4267a..bf01f37 100755 --- a/src/x86/linker.ld +++ b/src/x86/linker.ld @@ -38,5 +38,5 @@ SECTIONS _heapLocation = 0xFFB00000; _heapSize = 0x100000; _kernelStart = VIRTUAL_BASE; - _kernelEnd = VIRTUAL_BASE + (4096 * IMAGE_SIZE); + _kernel_end = VIRTUAL_BASE + (4096 * IMAGE_SIZE); } diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index aa66c09..0b6ec8c 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -4,6 +4,7 @@ #include "memorymap.h" #include "apic.h" #include "interrupts.h" +#include "msr.h" #include "stdio.h" #include "string.h" #include "module.h" @@ -11,7 +12,7 @@ #include #include -extern int _kernelEnd; +extern int _kernel_end; struct apic_registers_t volatile *apic_registers; @@ -75,11 +76,13 @@ int initialize(void *multiboot_info) } // TODO: setup IDT memset(idt, 0, sizeof(struct interrupt_descriptor_t) * 256); - create_interrupt_descriptor(&idt[EXCEPTION_DIV_BY_0], (void*)isr_division_by_zero, INTERRPUT_INT32, 3); - create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_INT32, 3); - create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_INT32, 3); - create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_INT32, 3); - create_interrupt_descriptor(&idt[0x80], (void*)isr_syscall, INTERRPUT_INT32, 3); + create_interrupt_descriptor(&idt[EXCEPTION_DIV_BY_0], (void*)isr_division_by_zero, INTERRPUT_INT32, 0); + create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_INT32, 0); + create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_INT32, 0); + create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_INT32, 0); + create_interrupt_descriptor(&idt[ISR_AP_START], (void*)isr_ap_start, INTERRPUT_INT32, 0); + create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0); + lidt(idt); // TODO: setup APIC asm volatile( @@ -89,5 +92,11 @@ int initialize(void *multiboot_info) ::: "al" ); apic_enable(); + struct msr_apic_base_t msr; + read_msr(MSR_APIC_BASE, (uint64_t*)&msr); + msr.apic_base = (size_t) &_kernel_end >> 12; + write_msr(MSR_APIC_BASE, (uint64_t*)&msr); + printf("MSR_APIC_BASE: %016x\n", *((uint32_t*)&msr)); + apic_registers = (struct apic_registers_t*) (msr.apic_base << 12); // TODO: enter first process } From 83abc11b09560552accea2247206556adb339c75 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Thu, 15 Apr 2021 05:54:57 -0500 Subject: [PATCH 109/109] Formatted header in README.md properly --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3c84d7..616b6f2 100755 --- a/README.md +++ b/README.md @@ -1 +1 @@ -===Quark Kernel=== \ No newline at end of file +# Quark Kernel \ No newline at end of file