diff --git a/src/Makefile.am b/src/Makefile.am index 718ad10..aad19a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,15 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = startup.cpp module.cpp tty.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp +quark_kernel_SOURCES = kernelstate.cpp module.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp quark_kernel_LDADD = -lgcc quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -nostdlib if x86 quark_kernel_SOURCES += x86/mmap.cpp \ + x86/tty.cpp \ x86/interrupts.cpp \ + x86/multiboot2.cpp \ + x86/initialize.cpp \ x86/entry.S quark_kernel_LDFLAGS += -T x86/linker.ld quark_kernel_DEPENDENCIES = x86/linker.ld diff --git a/src/kernelstate.cpp b/src/kernelstate.cpp new file mode 100644 index 0000000..561ba16 --- /dev/null +++ b/src/kernelstate.cpp @@ -0,0 +1,9 @@ +#include "kernelstate.hpp" + +using namespace kernel; + +BuddyAllocator State::pageAllocator; +Allocator State::allocator; +Interrupts State::interrupts; +ProcessQueue State::processQueue; +SystemInfo State::config; \ No newline at end of file diff --git a/src/kernelstate.hpp b/src/kernelstate.hpp index b7ea052..77a3cb8 100644 --- a/src/kernelstate.hpp +++ b/src/kernelstate.hpp @@ -5,6 +5,7 @@ #include "allocator.hpp" #include "interrupts.hpp" #include "scheduler.hpp" +#include "systeminfo.hpp" namespace kernel { @@ -23,6 +24,8 @@ public: static ProcessQueue processQueue; + static SystemInfo config; + }; } diff --git a/src/startup.cpp b/src/startup.cpp deleted file mode 100755 index fa6da1c..0000000 --- a/src/startup.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include - -#include "systypes.hpp" -#include "systeminfo.hpp" -#include "mmgr.hpp" -#include "tty.hpp" -#include "util.hpp" -#include "kernelstate.hpp" -#include "config.h" - -using namespace kernel; - -BuddyAllocator State::pageAllocator; -Allocator State::allocator; -Interrupts State::interrupts; -ProcessQueue State::processQueue; - -extern int _pageMapLocation; -extern int _heapLocation; -extern int _heapSize; - -extern SystemInfo system_info; -extern MemoryMap::Region memory_map; - -void main(char* cmdline) -{ - MemoryMap memmap(&memory_map, 16); - State::pageAllocator = BuddyAllocator(memmap, (char*) &_pageMapLocation, system_info.getHighMemory() / 4 + 256, 6); - mmap((void*) &_heapLocation, 0x100000, MMAP_RW); - State::allocator = Allocator((void*) 0xFFB00000, 0x100000, 256); - - TTY tty((char*) 0xFF8B8000); - tty << PACKAGE_STRING << "\n\n"; - tty << "Low memory: \t" << (int) system_info.getLowMemory() << " KiB\n"; - tty << "High memory:\t" << (int) system_info.getHighMemory() << " KiB\n"; - tty << "Type\t\tLocation\t\tSize\n"; - for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++) - { - tty << (int) memmap[i].getType() << "\t\t\t"; - tty << (void*) memmap[i].getLocation() << "\t\t"; - tty << (int) memmap[i].getSize() << "\n"; - } - mmap((void*) 0, 4096, MMAP_RW); - tty << "Nothing left to do. Hanging.\n"; -} diff --git a/src/systeminfo.cpp b/src/systeminfo.cpp index 0ed92e4..1151de1 100644 --- a/src/systeminfo.cpp +++ b/src/systeminfo.cpp @@ -1,16 +1,25 @@ #include "systeminfo.hpp" +#include "util.hpp" -size_t kernel::SystemInfo::getLowMemory() +using namespace kernel; + +SystemInfo::SystemInfo() { - return lowMemory; + } -size_t kernel::SystemInfo::getHighMemory() +SystemInfo::SystemInfo(MemoryMap& memoryMap, const char* commandLine) + : m_memmap(memoryMap) { - return highMemory; + strcpy(this->commandLine, commandLine); } -physaddr_t kernel::SystemInfo::getKernelBase() +const MemoryMap& SystemInfo::getMemoryMap() const { - return kernelBase; + return m_memmap; +} + +const char* SystemInfo::getCommandLine() const +{ + return commandLine; } diff --git a/src/systeminfo.hpp b/src/systeminfo.hpp index 9632f65..81727cd 100644 --- a/src/systeminfo.hpp +++ b/src/systeminfo.hpp @@ -4,6 +4,7 @@ #include #include "systypes.hpp" +#include "memorymap.hpp" namespace kernel { @@ -12,21 +13,19 @@ class SystemInfo { public: - size_t getLowMemory(); + SystemInfo(); - size_t getHighMemory(); + SystemInfo(MemoryMap& memoryMap, const char* commandLine); - physaddr_t getKernelBase(); + const MemoryMap& getMemoryMap() const; + + const char* getCommandLine() const; private: - - size_t lowMemory; - size_t highMemory; + MemoryMap m_memmap; - physaddr_t kernelBase; - - physaddr_t kernelEnd; + char commandLine[128]; }; diff --git a/src/x86/entry.S b/src/x86/entry.S index 7a68f9d..fd6c079 100755 --- a/src/x86/entry.S +++ b/src/x86/entry.S @@ -143,181 +143,54 @@ memory_map: .global _start .type _start, @function _start: + # This platform reqires a Multiboot2 bootloader. cmp $0x36d76289, %eax - jne _err + jne .err - movb $64, 0xB8000 + # Initialize stack in physical address space + mov $stackTop, %esp + sub $BASE_DIFF, %esp - mov $system_info, %edi - sub $BASE_DIFF, %edi - add $8, %ebx - -switch: - mov (%ebx), %eax - cmp $0, %eax - je s_end - cmp $1, %eax - je tag_1 - cmp $3, %eax - je tag_3 - cmp $4, %eax - je tag_4 - cmp $6, %eax - je tag_6 - cmp $21, %eax - je tag_21 - jmp def - -# Boot command line -tag_1: - mov 4(%ebx), %ecx - sub $8, %ecx - mov %ebx, %esi - add $8, %esi - mov $_bootCmdLine, %edi - sub $BASE_DIFF, %edi - rep movsb - mov $system_info, %edi - sub $BASE_DIFF, %edi - jmp def - -tag_3: - mov 8(%ebx), %esi - mov (%esi), %eax - mov %al, (0xB8004) - mov %ah, (0xB8006) - shr $16, %eax - mov %al, (0xB8008) - mov %ah, (0xB800a) - jmp def - -# Basic memory info -tag_4: - mov 8(%ebx), %eax - mov %eax, (%edi) - mov 12(%ebx), %eax - mov %eax, 4(%edi) - jmp def - -# Memory map -tag_6: - mov $memory_map, %esi - sub $BASE_DIFF, %esi # set esi to point to the table in the kernel image - mov 4(%ebx), %ecx - sub $16, %ecx # set ecx to store the size of the table provided by the bootloader - mov 8(%ebx), %edx # set edx to store the size of each table entry - add $16, %ebx # move ebx up to the first entry -1: mov (%ebx), %eax - mov %eax, (%esi) # save the address of that region in memory - mov 8(%ebx), %eax - mov %eax, 4(%esi) # save the size of that region in memory - mov 16(%ebx), %eax - mov %eax, 8(%esi) # save the type of memory in that region - add $12, %esi # move esi to the next entry in the kernel's array - add %edx, %ebx # move ebx to the next entry in the bootloader's array - sub %edx, %ecx # subtract the size of an entry from ecx. - jnz 1b # loop if there are entries left - mov $0, %eax - mov %eax, (%esi) - mov %eax, 4(%esi) - mov %eax, 8(%esi) - jmp switch - -# Program image location -tag_21: - mov 8(%ebx), %eax - mov %eax, 8(%edi) - jmp def - -def: - mov 4(%ebx), %eax - add $7, %eax - and $0xFFFFFFF8, %eax - add %eax, %ebx - jmp switch -s_end: - - movb $64, 0xB8002 - - mov $0, %ecx -1: - # Generate a page table entry pointing to a page in the kernel binary - mov %ecx, %eax - mov $4096, %edx - mul %edx - or $3, %eax - - # Load the address of the temporary page table and translate it to a physical address - mov $_tempPgTable, %edi - sub $BASE_DIFF, %edi - - # Save the PTE into an entry in the temporary page table - mov %eax, (%edi, %ecx, 4) - - # Load the address of the identity map and translate it to a physical address - mov $_tempIdentityMap, %edi - sub $BASE_DIFF, %edi - - # Save the PTE into an entry in the identity map - mov %eax, (%edi, %ecx, 4) - - # Increment count and loop - inc %ecx - mov $IMAGE_SIZE, %edx - add $256, %edx - cmp %edx, %ecx - jne 1b - - # Load the physical address of the identity map, and generate a PDE + # Push physical address of identity map mov $_tempIdentityMap, %eax sub $BASE_DIFF, %eax - or $3, %eax + push %eax - # Load the physical address of the page directory - mov $_tempPgDir, %edi - sub $BASE_DIFF, %edi - - # Save the PDE to the first element in the page directory - mov %eax, (%edi) - - # Load the physical address of the temporary page table, and generate a PDE + # Push physical address of page table mov $_tempPgTable, %eax sub $BASE_DIFF, %eax - or $3, %eax + push %eax - # Save the PDE to the entry corresponding to 0xC0000000 - mov %eax, 4088(%edi) - - # Set the last entry in the page directory to point to the page directory itself - mov %edi, %eax - or $3, %eax - mov %eax, 4092(%edi) + # Push physical address of page directory + mov $_tempPgDir, %eax + sub $BASE_DIFF, %eax + push %eax - # Load the physical address of the page directory into CR3 - mov $_tempPgDir, %edi - sub $BASE_DIFF, %edi - mov %edi, %cr3 - - # Enable paging - mov %cr0, %eax - or $0x80010000, %eax - mov %eax, %cr0 + # Load physical address of startPaging() + mov $startPaging, %eax + sub $BASE_DIFF, %eax + + # Initialize paging + call *%eax # Jump into mapped kernel binary - lea 2f, %eax + lea 1f, %eax jmp *%eax -2: +1: # Delete PDE corresponding to identity map. We shouldn't need it anymore. movl $0, (_tempIdentityMap) - # Reload page tables + # Flush TLB mov %cr3, %eax mov %eax, %cr3 - # Initialize stack + # Initialize stack in virtual memory mov $stackTop, %esp + + # Load GPT lgdt gdt_info + # Load segment registers jmp $8, $.ldcs .ldcs: mov $16, %ax @@ -327,15 +200,27 @@ s_end: mov %ax, %fs mov %ax, %ss - mov $_bootCmdLine, %eax - push %eax + # Change EBX to point to the virtual address of the multiboot info + # If the new pointer is out-of-bounds, error + add $0xFF800000, %ebx + cmp $0xFF800000, %ebx + jl .err + cmp $0xFFC00000, %ebx + jge .err + + # Call initialize(void* multibootInfo) + push %ebx + call initialize + + # mov $_bootCmdLine, %eax + # push %eax # Call main function - call main + # call main -_err: +.err: cli -3: hlt - jmp 3b +2: hlt + jmp 2b .size _start, . - _start diff --git a/src/x86/initialize.cpp b/src/x86/initialize.cpp new file mode 100644 index 0000000..17dcdf0 --- /dev/null +++ b/src/x86/initialize.cpp @@ -0,0 +1,77 @@ +#include +#include "multiboot2.hpp" +#include "tty.hpp" +#include "../kernelstate.hpp" +#include "../systeminfo.hpp" +#include "../mmap.hpp" +#include "../util.hpp" + +using namespace kernel; + +extern int _kernelEnd; + +enum BootInfoType +{ + Terminate = 0, + CommandLine = 1, + BootLoader = 2, + Module = 3, + MemoryInfo = 4, + BootDevice = 5, + MMap = 6, + VBEInfo = 7, + FramebufferInfo = 8, + ELFSymbols = 9, + APMTable = 10 +}; + +extern "C" +int startPaging(uint32_t* directory, uint32_t* table, uint32_t* identityTable) +{ + for(int i = 0; i < 1024; i++) + { + uint32_t pte = i * 4096 + 3; + table[i] = pte; + identityTable[i] = pte; + } + directory[0] = ((uint32_t) identityTable) + 3; + directory[1022] = ((uint32_t) table) + 3; + directory[1023] = ((uint32_t) directory) + 3; + asm("mov %0, %%cr3" + : + : "r" (directory)); + asm("mov %%cr0, %%eax \n" + "or $0x80010000, %%eax \n" + "mov %%eax, %%cr0" + : + : + : "eax"); + return 0; +} + +extern "C" +int initialize(void* multibootInfo) +{ + size_t heapSize = 0xFFC00000 - (size_t) &_kernelEnd; + int log = 0; + for(; heapSize > 1; log++) + heapSize >>= 1; + heapSize <<= log; + new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64); + Multiboot2Info bootInfo(multibootInfo); + if(!bootInfo.isValid()) + return 1; + bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, MemoryMap::UNAVAILABLE); + new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine()); + TTY tty((char*) 0xFF8B8000); + tty << "Type\t\tLocation\t\tSize\n"; + for(size_t i = 0; i < bootInfo.getMemoryMap().size() && bootInfo.getMemoryMap()[i].getSize() > 0; i++) + { + tty << (int) bootInfo.getMemoryMap()[i].getType() << "\t\t\t"; + tty << (void*) bootInfo.getMemoryMap()[i].getLocation() << "\t\t"; + tty << (int) bootInfo.getMemoryMap()[i].getSize() << "\n"; + } + // TODO: Initialize page allocator + // TODO: Initialize process queue, add entry for each module + return 0; +} diff --git a/src/x86/linker.ld b/src/x86/linker.ld index 55d5651..df4267a 100755 --- a/src/x86/linker.ld +++ b/src/x86/linker.ld @@ -2,7 +2,6 @@ ENTRY(_start) SECTIONS { - . = 0xFF900000; VIRTUAL_BASE = .; PHYSICAL_BASE = 0x100000; diff --git a/src/tty.cpp b/src/x86/tty.cpp similarity index 100% rename from src/tty.cpp rename to src/x86/tty.cpp diff --git a/src/tty.hpp b/src/x86/tty.hpp similarity index 100% rename from src/tty.hpp rename to src/x86/tty.hpp