Re-wrote boot code, moved to x86 folder
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
noinst_PROGRAMS = quark-kernel
|
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_LDADD = -lgcc
|
||||||
quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb
|
quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb
|
||||||
quark_kernel_LDFLAGS = -nostdlib
|
quark_kernel_LDFLAGS = -nostdlib
|
||||||
|
|
||||||
if x86
|
if x86
|
||||||
quark_kernel_SOURCES += x86/mmap.cpp \
|
quark_kernel_SOURCES += x86/mmap.cpp \
|
||||||
|
x86/tty.cpp \
|
||||||
x86/interrupts.cpp \
|
x86/interrupts.cpp \
|
||||||
|
x86/multiboot2.cpp \
|
||||||
|
x86/initialize.cpp \
|
||||||
x86/entry.S
|
x86/entry.S
|
||||||
quark_kernel_LDFLAGS += -T x86/linker.ld
|
quark_kernel_LDFLAGS += -T x86/linker.ld
|
||||||
quark_kernel_DEPENDENCIES = x86/linker.ld
|
quark_kernel_DEPENDENCIES = x86/linker.ld
|
||||||
|
|||||||
9
src/kernelstate.cpp
Normal file
9
src/kernelstate.cpp
Normal file
@@ -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;
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "allocator.hpp"
|
#include "allocator.hpp"
|
||||||
#include "interrupts.hpp"
|
#include "interrupts.hpp"
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
|
#include "systeminfo.hpp"
|
||||||
|
|
||||||
namespace kernel
|
namespace kernel
|
||||||
{
|
{
|
||||||
@@ -23,6 +24,8 @@ public:
|
|||||||
|
|
||||||
static ProcessQueue processQueue;
|
static ProcessQueue processQueue;
|
||||||
|
|
||||||
|
static SystemInfo config;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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";
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,25 @@
|
|||||||
#include "systeminfo.hpp"
|
#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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "systypes.hpp"
|
#include "systypes.hpp"
|
||||||
|
#include "memorymap.hpp"
|
||||||
|
|
||||||
namespace kernel
|
namespace kernel
|
||||||
{
|
{
|
||||||
@@ -12,21 +13,19 @@ class SystemInfo
|
|||||||
{
|
{
|
||||||
public:
|
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:
|
private:
|
||||||
|
|
||||||
size_t lowMemory;
|
|
||||||
|
|
||||||
size_t highMemory;
|
MemoryMap m_memmap;
|
||||||
|
|
||||||
physaddr_t kernelBase;
|
char commandLine[128];
|
||||||
|
|
||||||
physaddr_t kernelEnd;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
203
src/x86/entry.S
203
src/x86/entry.S
@@ -143,181 +143,54 @@ memory_map:
|
|||||||
.global _start
|
.global _start
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
_start:
|
_start:
|
||||||
|
# This platform reqires a Multiboot2 bootloader.
|
||||||
cmp $0x36d76289, %eax
|
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
|
# Push physical address of identity map
|
||||||
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
|
|
||||||
mov $_tempIdentityMap, %eax
|
mov $_tempIdentityMap, %eax
|
||||||
sub $BASE_DIFF, %eax
|
sub $BASE_DIFF, %eax
|
||||||
or $3, %eax
|
push %eax
|
||||||
|
|
||||||
# Load the physical address of the page directory
|
# Push physical address of page table
|
||||||
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
|
|
||||||
mov $_tempPgTable, %eax
|
mov $_tempPgTable, %eax
|
||||||
sub $BASE_DIFF, %eax
|
sub $BASE_DIFF, %eax
|
||||||
or $3, %eax
|
push %eax
|
||||||
|
|
||||||
# Save the PDE to the entry corresponding to 0xC0000000
|
# Push physical address of page directory
|
||||||
mov %eax, 4088(%edi)
|
mov $_tempPgDir, %eax
|
||||||
|
sub $BASE_DIFF, %eax
|
||||||
# Set the last entry in the page directory to point to the page directory itself
|
push %eax
|
||||||
mov %edi, %eax
|
|
||||||
or $3, %eax
|
|
||||||
mov %eax, 4092(%edi)
|
|
||||||
|
|
||||||
# Load the physical address of the page directory into CR3
|
# Load physical address of startPaging()
|
||||||
mov $_tempPgDir, %edi
|
mov $startPaging, %eax
|
||||||
sub $BASE_DIFF, %edi
|
sub $BASE_DIFF, %eax
|
||||||
mov %edi, %cr3
|
|
||||||
|
# Initialize paging
|
||||||
# Enable paging
|
call *%eax
|
||||||
mov %cr0, %eax
|
|
||||||
or $0x80010000, %eax
|
|
||||||
mov %eax, %cr0
|
|
||||||
|
|
||||||
# Jump into mapped kernel binary
|
# Jump into mapped kernel binary
|
||||||
lea 2f, %eax
|
lea 1f, %eax
|
||||||
jmp *%eax
|
jmp *%eax
|
||||||
2:
|
1:
|
||||||
# Delete PDE corresponding to identity map. We shouldn't need it anymore.
|
# Delete PDE corresponding to identity map. We shouldn't need it anymore.
|
||||||
movl $0, (_tempIdentityMap)
|
movl $0, (_tempIdentityMap)
|
||||||
|
|
||||||
# Reload page tables
|
# Flush TLB
|
||||||
mov %cr3, %eax
|
mov %cr3, %eax
|
||||||
mov %eax, %cr3
|
mov %eax, %cr3
|
||||||
|
|
||||||
# Initialize stack
|
# Initialize stack in virtual memory
|
||||||
mov $stackTop, %esp
|
mov $stackTop, %esp
|
||||||
|
|
||||||
|
# Load GPT
|
||||||
lgdt gdt_info
|
lgdt gdt_info
|
||||||
|
|
||||||
|
# Load segment registers
|
||||||
jmp $8, $.ldcs
|
jmp $8, $.ldcs
|
||||||
.ldcs:
|
.ldcs:
|
||||||
mov $16, %ax
|
mov $16, %ax
|
||||||
@@ -327,15 +200,27 @@ s_end:
|
|||||||
mov %ax, %fs
|
mov %ax, %fs
|
||||||
mov %ax, %ss
|
mov %ax, %ss
|
||||||
|
|
||||||
mov $_bootCmdLine, %eax
|
# Change EBX to point to the virtual address of the multiboot info
|
||||||
push %eax
|
# 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 function
|
||||||
call main
|
# call main
|
||||||
|
|
||||||
_err:
|
.err:
|
||||||
cli
|
cli
|
||||||
3: hlt
|
2: hlt
|
||||||
jmp 3b
|
jmp 2b
|
||||||
|
|
||||||
.size _start, . - _start
|
.size _start, . - _start
|
||||||
|
|||||||
77
src/x86/initialize.cpp
Normal file
77
src/x86/initialize.cpp
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ ENTRY(_start)
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
|
||||||
. = 0xFF900000;
|
. = 0xFF900000;
|
||||||
VIRTUAL_BASE = .;
|
VIRTUAL_BASE = .;
|
||||||
PHYSICAL_BASE = 0x100000;
|
PHYSICAL_BASE = 0x100000;
|
||||||
|
|||||||
Reference in New Issue
Block a user