From 505213b7dcbc1abecf0e3db6c96561dd2be44332 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 10 Apr 2021 17:37:05 -0500 Subject: [PATCH 01/71] 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 02/71] 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 03/71] 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 04/71] 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 05/71] 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 06/71] 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 07/71] 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 08/71] 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 09/71] 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 10/71] 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 11/71] 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 12/71] 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 13/71] 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 14/71] 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 15/71] 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 16/71] 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 17/71] 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 18/71] 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 19/71] 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 20/71] 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 21/71] 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 22/71] 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 23/71] 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 24/71] 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 25/71] 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 26/71] 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 27/71] 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 28/71] 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 29/71] 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 30/71] 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 31/71] 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 32/71] 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 33/71] 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 34/71] 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 35/71] 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 36/71] 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 37/71] 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 38/71] 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 39/71] 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 40/71] 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 41/71] 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 42/71] 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 43/71] 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 44/71] 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 45/71] 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 46/71] 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 47/71] 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 48/71] 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 49/71] 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 50/71] 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 51/71] 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 52/71] 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 53/71] 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 54/71] 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 55/71] 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 56/71] 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 57/71] 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 58/71] 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 59/71] 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 60/71] 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 61/71] 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 62/71] 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 63/71] 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 64/71] 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 65/71] 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 66/71] 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 67/71] 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 68/71] 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 69/71] 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 70/71] 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 71/71] 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 }