Rework of project structure.
This commit is contained in:
parent
28bad4c5ac
commit
b873c662c8
41 changed files with 1825 additions and 0 deletions
27
prototypes-rework/Makefile
Normal file
27
prototypes-rework/Makefile
Normal file
|
@ -0,0 +1,27 @@
|
|||
##
|
||||
# Build all projects
|
||||
##
|
||||
|
||||
PROJECTS = $(shell ls --file-type --ignore=libs --ignore=kernels --ignore=include | grep / | sed "s|/||")
|
||||
|
||||
all: $(PROJECTS) boot.img
|
||||
|
||||
.PHONY: $(PROJECTS)
|
||||
$(PROJECTS):
|
||||
make -C $@ $(ARGS)
|
||||
|
||||
boot.img: $(PROJECTS)
|
||||
mformat -C -f 1440 -v VIDEO -i boot.img ::
|
||||
mcopy -i boot.img \
|
||||
kernels/* \
|
||||
syslinux.cfg \
|
||||
/boot/syslinux/libcom32.c32 \
|
||||
/boot/syslinux/libutil.c32 \
|
||||
/boot/syslinux/menu.c32 \
|
||||
/boot/syslinux/mboot.c32 \
|
||||
::
|
||||
syslinux boot.img
|
||||
mdir -i boot.img ::
|
||||
|
||||
run: boot.img
|
||||
qemu-system-i386 boot.img
|
BIN
prototypes-rework/boot.img
Normal file
BIN
prototypes-rework/boot.img
Normal file
Binary file not shown.
36
prototypes-rework/common.mk
Normal file
36
prototypes-rework/common.mk
Normal file
|
@ -0,0 +1,36 @@
|
|||
##
|
||||
# DasOS common Makefile targets
|
||||
##
|
||||
|
||||
INCLUDE_DIRS += ../include/ /opt/lib/gcc/i686-elf/6.1.0/include/
|
||||
|
||||
FLAGS = -ffreestanding -mno-sse -Werror -Wall -iquote include $(addprefix -I, $(INCLUDE_DIRS)) -O3 -g
|
||||
ASFLAGS = $(FLAGS)
|
||||
CFLAGS = $(FLAGS)
|
||||
CXXFLAGS = $(FLAGS) -std=c++14 -fno-rtti -fno-exceptions -fno-leading-underscore -fno-use-cxa-atexit -nostdlib -fno-builtin
|
||||
LDFLAGS = -L../libs/
|
||||
|
||||
SRCS = $(shell find -regextype egrep -regex '.*/.*\.(cpp|S|c)')
|
||||
OBJS = $(addsuffix .o, $(notdir $(basename $(SRCS))))
|
||||
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(ASFLAGS) -c -o obj/$@ $<
|
||||
|
||||
%.o: %.S
|
||||
$(AS) $(CFLAGS) -c -o obj/$@ $<
|
||||
|
||||
%.o: src/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
|
||||
|
||||
%.o: src/%.c
|
||||
$(CC) $(ASFLAGS) -c -o obj/$@ $<
|
||||
|
||||
%.o: src/%.S
|
||||
$(AS) $(CFLAGS) -c -o obj/$@ $<
|
||||
|
||||
builddir:
|
||||
mkdir -p ./obj/
|
10
prototypes-rework/config.mk
Normal file
10
prototypes-rework/config.mk
Normal file
|
@ -0,0 +1,10 @@
|
|||
##
|
||||
# DasOS Makefile configuration
|
||||
##
|
||||
|
||||
# Configure for target platform
|
||||
CC=/opt/bin/i686-elf-gcc
|
||||
CXX=/opt/bin/i686-elf-g++
|
||||
LD=/opt/i686-elf/bin/ld
|
||||
AR=/opt/i686-elf/bin/ar
|
||||
AS=/opt/bin/i686-elf-gcc
|
50
prototypes-rework/include/asm.hpp
Normal file
50
prototypes-rework/include/asm.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ASM_READ_REG(reg, var) asm volatile("mov %%" #reg ", %0" : "=r" (var));
|
||||
#define ASM_WRITE_REG(reg, var) asm volatile("mov %0, %%" #reg : : "r" (var));
|
||||
|
||||
namespace ASM
|
||||
{
|
||||
static inline void sti()
|
||||
{
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
static inline void cli()
|
||||
{
|
||||
__asm__ volatile ("cli");
|
||||
}
|
||||
|
||||
static inline void outb(uint16_t port, uint8_t data)
|
||||
{
|
||||
asm volatile ("outb %0, %1" : : "a" (data), "Nd" (port));
|
||||
}
|
||||
|
||||
static inline uint8_t inb(uint16_t port)
|
||||
{
|
||||
uint8_t data;
|
||||
asm volatile ("inb %1, %0" : "=a" (data) : "d" (port));
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline void invlpg(void* m)
|
||||
{
|
||||
/* Clobber memory to avoid optimizer re-ordering access before invlpg, which may cause nasty bugs. */
|
||||
asm volatile ( "invlpg (%0)" : : "b"(m) : "memory" );
|
||||
}
|
||||
|
||||
static inline void lidt(void *idt, size_t length)
|
||||
{
|
||||
struct {
|
||||
uint16_t limit;
|
||||
void* pointer;
|
||||
} __attribute__((packed)) idtp = {
|
||||
.limit = uint16_t(length * 8 - 1),
|
||||
.pointer = idt,
|
||||
};
|
||||
asm volatile("lidt %0" : : "m" (idtp));
|
||||
}
|
||||
}
|
13
prototypes-rework/include/compat.h
Normal file
13
prototypes-rework/include/compat.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void compat_call_ctors();
|
||||
|
||||
void compat_call_dtors();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
188
prototypes-rework/include/console.hpp
Normal file
188
prototypes-rework/include/console.hpp
Normal file
|
@ -0,0 +1,188 @@
|
|||
#pragma once
|
||||
|
||||
#include "screen.hpp"
|
||||
#include "pointer.hpp"
|
||||
|
||||
struct FColor
|
||||
{
|
||||
FColor() : color(Color::White) { }
|
||||
FColor(Color color) : color(color) { }
|
||||
Color color;
|
||||
};
|
||||
|
||||
struct BColor
|
||||
{
|
||||
BColor() : color(Color::Black) { }
|
||||
BColor(Color color) : color(color) { }
|
||||
Color color;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct NumericFormat
|
||||
{
|
||||
T value;
|
||||
uint32_t base;
|
||||
|
||||
/**
|
||||
* Applies a padding to the number.
|
||||
* A positive number will apply padding the right side,
|
||||
* a negative number will pad the left side.
|
||||
*/
|
||||
int32_t padding = 0;
|
||||
|
||||
char padchar = ' ';
|
||||
|
||||
NumericFormat(T value) : value(value), base(10) { }
|
||||
NumericFormat(T value, uint32_t base) : value(value), base(base) { }
|
||||
};
|
||||
|
||||
namespace console_tools
|
||||
{
|
||||
template<typename T>
|
||||
auto hex(T value) { return NumericFormat<T>(value, 16); }
|
||||
|
||||
template<typename T>
|
||||
auto dec(T value) { return NumericFormat<T>(value, 10); }
|
||||
|
||||
template<typename T>
|
||||
auto oct(T value) { return NumericFormat<T>(value, 8); }
|
||||
|
||||
template<typename T>
|
||||
auto bin(T value) { return NumericFormat<T>(value, 2); }
|
||||
|
||||
template<typename T>
|
||||
auto nbase(T value, uint32_t base) { return NumericFormat<T>(value, base); }
|
||||
|
||||
template<typename T>
|
||||
auto pad(NumericFormat<T> value, int32_t padding, char c = ' ') {
|
||||
value.padding = padding;
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto pad(T value, int32_t padding, char c = ' ') {
|
||||
return pad(NumericFormat<T>(value), padding, c);
|
||||
}
|
||||
}
|
||||
|
||||
class Console
|
||||
{
|
||||
public:
|
||||
static Console main;
|
||||
private:
|
||||
Screen * const screen;
|
||||
int x;
|
||||
int y;
|
||||
Color fg, bg;
|
||||
bool caretEnabled;
|
||||
private:
|
||||
/**
|
||||
* Moves the hardware caret.
|
||||
*/
|
||||
void updateCaret();
|
||||
|
||||
/**
|
||||
* Prints the prefix for a given numeric base.
|
||||
* @returns the prefix length.
|
||||
*/
|
||||
uint32_t printNumericPrefix(uint32_t base);
|
||||
|
||||
/**
|
||||
* Prints a character several times.
|
||||
*/
|
||||
void putrep(char c, uint32_t repetitions);
|
||||
public:
|
||||
Console(Screen *screen);
|
||||
|
||||
/**
|
||||
* Clears the console.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Puts a character on the screen.
|
||||
*/
|
||||
void put(char c);
|
||||
|
||||
/**
|
||||
* Inserts a line break and returns the cursor to the start.
|
||||
*/
|
||||
void newline();
|
||||
|
||||
/**
|
||||
* Scrolls screen a line upwards
|
||||
*/
|
||||
void scroll();
|
||||
|
||||
/**
|
||||
* Moves the cursor to the given position
|
||||
*/
|
||||
void setCursor(int x, int y);
|
||||
|
||||
/**
|
||||
* Sets the visibility of the caret.
|
||||
*/
|
||||
void setCaretVisible(bool visible = true);
|
||||
|
||||
/**
|
||||
* Sets the text foreground color
|
||||
*/
|
||||
void setForeground(Color c) {
|
||||
this->fg = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text background color
|
||||
*/
|
||||
void setBackground(Color c) {
|
||||
this->bg = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text colors.
|
||||
*/
|
||||
void setColors(Color bg, Color fg) {
|
||||
this->fg = fg;
|
||||
this->bg = bg;
|
||||
}
|
||||
|
||||
inline Console & operator << (char c)
|
||||
{
|
||||
this->put(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Console & operator << (const char *str)
|
||||
{
|
||||
while(*str) {
|
||||
*this << *str++;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Console & operator << (const FColor &color)
|
||||
{
|
||||
this->fg = color.color;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Console & operator << (const BColor &color)
|
||||
{
|
||||
this->bg = color.color;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Console & operator << (uint32_t value);
|
||||
|
||||
Console & operator << (int32_t value);
|
||||
|
||||
Console & operator << (void *value);
|
||||
|
||||
Console & operator << (bool value);
|
||||
|
||||
template<typename T>
|
||||
Console & operator << (pointer<T> ptr);
|
||||
|
||||
template<typename T>
|
||||
Console & operator << (const NumericFormat<T> &fmt);
|
||||
};
|
25
prototypes-rework/include/cpustate.hpp
Normal file
25
prototypes-rework/include/cpustate.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct CpuState
|
||||
{
|
||||
uint32_t eax;
|
||||
uint32_t ebx;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint32_t ebp;
|
||||
|
||||
uint32_t interrupt;
|
||||
uint32_t error;
|
||||
|
||||
uint32_t eip;
|
||||
uint32_t cs;
|
||||
uint32_t eflags;
|
||||
uint32_t esp;
|
||||
uint32_t ss;
|
||||
} __attribute__((packed));
|
||||
|
||||
static_assert(sizeof(CpuState) == 56, "CpuState must be 56 bytes large.");
|
28
prototypes-rework/include/driver/pic.hpp
Normal file
28
prototypes-rework/include/driver/pic.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class PIC
|
||||
{
|
||||
private:
|
||||
uint16_t port;
|
||||
public:
|
||||
PIC(uint16_t port);
|
||||
|
||||
/**
|
||||
* Sends an initialization code to the PIC.s
|
||||
*/
|
||||
void initialize(uint16_t irqBase, uint16_t icw3, uint16_t icw4);
|
||||
|
||||
/**
|
||||
* Disables all interrupts where the corresponding bit in mask is set.
|
||||
*/
|
||||
void maskInterrupts(uint8_t mask);
|
||||
|
||||
/**
|
||||
* Sends an end-of-interrupt to the PIC.
|
||||
*/
|
||||
void sendEndOfInterrupt();
|
||||
};
|
||||
|
||||
extern PIC masterPIC, slavePIC;
|
36
prototypes-rework/include/elf.hpp
Normal file
36
prototypes-rework/include/elf.hpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace elf
|
||||
{
|
||||
static const uint32_t MAGIC = 0x464C457F;
|
||||
|
||||
struct Header {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint64_t reserved;
|
||||
uint64_t version2;
|
||||
uint32_t entry;
|
||||
uint32_t ph_offset;
|
||||
uint32_t sh_offset;
|
||||
uint32_t flags;
|
||||
uint16_t header_size;
|
||||
uint16_t ph_entry_size;
|
||||
uint16_t ph_entry_count;
|
||||
uint16_t sh_entry_size;
|
||||
uint16_t sh_entry_count;
|
||||
uint16_t sh_str_table_index;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ProgramHeader {
|
||||
uint32_t type;
|
||||
uint32_t offset;
|
||||
uint32_t virt_addr;
|
||||
uint32_t phys_addr;
|
||||
uint32_t file_size;
|
||||
uint32_t mem_size;
|
||||
uint32_t flags;
|
||||
uint32_t alignment;
|
||||
} __attribute__((packed));
|
||||
}
|
18
prototypes-rework/include/enums.hpp
Normal file
18
prototypes-rework/include/enums.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#define ENUM_CLASS_OPERATORS(type) static inline type operator | (type lhs, type rhs) { \
|
||||
return static_cast<type>(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs)); \
|
||||
} \
|
||||
static inline type operator & (type lhs, type rhs) { \
|
||||
return static_cast<type>(static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)); \
|
||||
} \
|
||||
static inline bool operator * (type lhs, type rhs) { \
|
||||
return (static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)) != 0; \
|
||||
} \
|
||||
static inline type & operator |=(type & lhs, type rhs) { \
|
||||
reinterpret_cast<uint32_t&>(lhs) |= static_cast<uint32_t>(rhs); \
|
||||
return lhs; \
|
||||
}
|
||||
|
||||
|
||||
|
8
prototypes-rework/include/errors.hpp
Normal file
8
prototypes-rework/include/errors.hpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
enum class Error
|
||||
{
|
||||
#define ERROR(num, ident, desc) ident = num,
|
||||
#include "errors.lst"
|
||||
#undef ERROR
|
||||
};
|
10
prototypes-rework/include/exceptions.hpp
Normal file
10
prototypes-rework/include/exceptions.hpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include "enums.hpp"
|
||||
|
||||
enum class Exception
|
||||
{
|
||||
#define EXCEPTION(num, shorthand, ident, desc, type) ident = num,
|
||||
#include "exceptions.lst"
|
||||
#undef EXCEPTION
|
||||
};
|
7
prototypes-rework/include/io.hpp
Normal file
7
prototypes-rework/include/io.hpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "asm.hpp"
|
||||
|
||||
// Import functions into global namespace
|
||||
using ASM::inb;
|
||||
using ASM::outb;
|
26
prototypes-rework/include/kernel/bsod.hpp
Normal file
26
prototypes-rework/include/kernel/bsod.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "errors.hpp"
|
||||
#include "cpustate.hpp"
|
||||
|
||||
/**
|
||||
* This class provides the blue screen of death.
|
||||
* Discaimer: Color may vary!
|
||||
*/
|
||||
class BSOD
|
||||
{
|
||||
private:
|
||||
BSOD() = delete;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Dies with a simple message and error code display.
|
||||
*/
|
||||
static void die(Error code, const char *msg);
|
||||
|
||||
/**
|
||||
* Dies with a simple message and error code display.
|
||||
*/
|
||||
static void die(Error code, const char *msg, CpuState *cpu);
|
||||
|
||||
};
|
118
prototypes-rework/include/kernel/gdt.hpp
Normal file
118
prototypes-rework/include/kernel/gdt.hpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "enums.hpp"
|
||||
|
||||
enum class SegmentAccess : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
Accessed = (1<<0),
|
||||
Readable = (1<<1),
|
||||
Writeable = (1<<1),
|
||||
Direction = (1<<2),
|
||||
Conforming = (1<<2),
|
||||
Executable = (1<<3),
|
||||
Segment = (1<<4),
|
||||
Ring0 = 0,
|
||||
Ring1 = (1<<5),
|
||||
Ring2 = (1<<6),
|
||||
Ring3 = (1<<5) | (1<<6),
|
||||
Present = (1<<7),
|
||||
};
|
||||
|
||||
ENUM_CLASS_OPERATORS(SegmentAccess)
|
||||
|
||||
enum class SegmentFlags : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
Available = (1<<0),
|
||||
LongMode = (1<<1),
|
||||
Use32Bit = (1<<2),
|
||||
Use4KSize = (1<<3),
|
||||
};
|
||||
|
||||
ENUM_CLASS_OPERATORS(SegmentFlags)
|
||||
|
||||
struct SegmentDescriptor
|
||||
{
|
||||
uint16_t limit0;
|
||||
uint16_t base0;
|
||||
uint8_t base1;
|
||||
SegmentAccess access;
|
||||
uint8_t limit1 : 4;
|
||||
uint8_t flags0 : 4;
|
||||
uint8_t base2;
|
||||
|
||||
SegmentDescriptor() :
|
||||
limit0(0), base0(0), base1(0),
|
||||
access(SegmentAccess::None),
|
||||
limit1(0), flags0(0), base2(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SegmentDescriptor(
|
||||
uint32_t base,
|
||||
uint32_t length,
|
||||
SegmentAccess access,
|
||||
SegmentFlags flags) :
|
||||
access(access)
|
||||
{
|
||||
this->setBase(base);
|
||||
this->setFlags(flags);
|
||||
|
||||
if(this->flags() * SegmentFlags::Use4KSize) {
|
||||
this->setLimit(length >> 12);
|
||||
} else {
|
||||
this->setLimit(length);
|
||||
}
|
||||
}
|
||||
|
||||
void setFlags(SegmentFlags flags)
|
||||
{
|
||||
this->flags0 = static_cast<uint8_t>(flags) & 0x0F;
|
||||
}
|
||||
|
||||
SegmentFlags flags() const
|
||||
{
|
||||
return static_cast<SegmentFlags>(this->flags0);
|
||||
}
|
||||
|
||||
uint32_t limit() const
|
||||
{
|
||||
return this->limit0 | (this->limit1 << 16);
|
||||
}
|
||||
|
||||
void setLimit(uint32_t value)
|
||||
{
|
||||
this->limit0 = (value & 0x0FFFF) >> 0;
|
||||
this->limit1 = (value & 0xFFFFF) >> 16;
|
||||
}
|
||||
|
||||
uint32_t base() const
|
||||
{
|
||||
return this->base0 | (this->base1 << 16) | (this->base2 << 24);
|
||||
}
|
||||
|
||||
void setBase(uint32_t value)
|
||||
{
|
||||
this->base0 = (value & 0x0000FFFF) >> 0;
|
||||
this->base1 = (value & 0x00FF0000) >> 16;
|
||||
this->base2 = (value & 0xFF000000) >> 24;
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
static_assert(sizeof(SegmentDescriptor) == 8, "SegmentDescriptor must be 8 bytes large.");
|
||||
|
||||
class GDT
|
||||
{
|
||||
public:
|
||||
static const uint32_t length = 8;
|
||||
private:
|
||||
static SegmentDescriptor descriptors[length];
|
||||
GDT() = delete;
|
||||
public:
|
||||
static void initialize();
|
||||
|
||||
static SegmentDescriptor & descriptor(uint32_t index);
|
||||
};
|
92
prototypes-rework/include/kernel/idt.hpp
Normal file
92
prototypes-rework/include/kernel/idt.hpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "enums.hpp"
|
||||
#include "cpustate.hpp"
|
||||
|
||||
enum class InterruptFlags : uint8_t
|
||||
{
|
||||
None = 0x00,
|
||||
Interrupt = 0x06,
|
||||
TrapGate = 0x07,
|
||||
TaskGate = 0x05,
|
||||
Use32Bit = 0x08,
|
||||
Ring0 = 0x00,
|
||||
Ring1 = 0x20,
|
||||
Ring2 = 0x40,
|
||||
Ring3 = 0x60,
|
||||
Present = 0x80,
|
||||
};
|
||||
|
||||
ENUM_CLASS_OPERATORS(InterruptFlags)
|
||||
|
||||
struct InterruptDescriptor
|
||||
{
|
||||
uint16_t offset0;
|
||||
uint16_t selector;
|
||||
uint8_t zero;
|
||||
InterruptFlags flags;
|
||||
uint16_t offset1;
|
||||
|
||||
InterruptDescriptor();
|
||||
|
||||
InterruptDescriptor(uint32_t offset, uint32_t selector, InterruptFlags flags);
|
||||
|
||||
uint32_t offset() const;
|
||||
|
||||
void setOffset(uint32_t offset);
|
||||
} __attribute__((packed));
|
||||
|
||||
static_assert(sizeof(InterruptDescriptor) == 8, "InterruptDescriptor must be 8 byte large.");
|
||||
|
||||
/**
|
||||
* An interrupt that specifies
|
||||
* a handler and if the interrupt is
|
||||
* enabled. Any non-enabled interrupt
|
||||
* causes a BSOD.
|
||||
*/
|
||||
class Interrupt
|
||||
{
|
||||
friend class IDT;
|
||||
using Handler = void (*)(CpuState * & cpu);
|
||||
private:
|
||||
bool isEnabled;
|
||||
Handler handler;
|
||||
|
||||
public:
|
||||
Interrupt();
|
||||
explicit Interrupt(Handler handler);
|
||||
};
|
||||
|
||||
|
||||
class IDT
|
||||
{
|
||||
public:
|
||||
static const uint32_t length = 256;
|
||||
|
||||
static Interrupt interrupts[length];
|
||||
|
||||
private:
|
||||
static InterruptDescriptor descriptors[length];
|
||||
IDT() = delete;
|
||||
|
||||
static CpuState * dispatch(CpuState *cpu);
|
||||
static void setupPIC();
|
||||
public:
|
||||
|
||||
/**
|
||||
* Accessor to an interrupt handler.
|
||||
*/
|
||||
static Interrupt & interrupt(uint32_t index);
|
||||
|
||||
/**
|
||||
* Gets an interrupt descriptor
|
||||
*/
|
||||
static InterruptDescriptor & descriptor(uint32_t idx);
|
||||
|
||||
/**
|
||||
* Initializes the interrupt table and sets up the PIC.
|
||||
*/
|
||||
static void initialize();
|
||||
|
||||
};
|
18
prototypes-rework/include/kernel/pagedirectory.hpp
Normal file
18
prototypes-rework/include/kernel/pagedirectory.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "pagetable.hpp"
|
||||
|
||||
class PageDirectory
|
||||
{
|
||||
private:
|
||||
uint32_t tables[1024];
|
||||
public:
|
||||
PageDirectory();
|
||||
~PageDirectory();
|
||||
|
||||
uint32_t & table(uint32_t index) {
|
||||
return this->tables[index];
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(PageDirectory) == 4096, "PageDirectory must be 4096 bytes large");
|
17
prototypes-rework/include/kernel/pagetable.hpp
Normal file
17
prototypes-rework/include/kernel/pagetable.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
class PageTable
|
||||
{
|
||||
private:
|
||||
uint32_t pages[1024];
|
||||
public:
|
||||
PageTable();
|
||||
~PageTable();
|
||||
|
||||
uint32_t & pageDescriptor(uint32_t pageIndex)
|
||||
{
|
||||
return this->pages[pageIndex];
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(PageTable) == 4096, "PageDirectory must be 4096 bytes large");
|
38
prototypes-rework/include/kernel/pmm.hpp
Normal file
38
prototypes-rework/include/kernel/pmm.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "pointer.hpp"
|
||||
|
||||
/**
|
||||
* Physical memory management tool.
|
||||
*/
|
||||
class PMM
|
||||
{
|
||||
private:
|
||||
PMM() = delete;
|
||||
public:
|
||||
/**
|
||||
* Marks a page as free by external memory management.
|
||||
*/
|
||||
static void markFree(physical_t page);
|
||||
|
||||
/**
|
||||
* Marks a page as used by external memory management.
|
||||
*/
|
||||
static void markUsed(physical_t page);
|
||||
|
||||
/**
|
||||
* Allocates a single page.
|
||||
* @remarks This method will either return a valid value or die with a BSOD if out of memory.
|
||||
*/
|
||||
static physical_t alloc();
|
||||
|
||||
/**
|
||||
* Frees a given page by pointer.
|
||||
*/
|
||||
static void free(physical_t page);
|
||||
|
||||
/**
|
||||
* Returns the free memory.
|
||||
*/
|
||||
static uint32_t getFreeMemory();
|
||||
};
|
62
prototypes-rework/include/kernel/vmm.hpp
Normal file
62
prototypes-rework/include/kernel/vmm.hpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
|
||||
#include "pmm.hpp"
|
||||
#include "enums.hpp"
|
||||
#include "pagedirectory.hpp"
|
||||
|
||||
enum class VMMFlags
|
||||
{
|
||||
None = 0,
|
||||
Present = (1<<0),
|
||||
Writable = (1<<1),
|
||||
UserSpace = (1<<2),
|
||||
SystemAllocated = (1<<3),
|
||||
};
|
||||
|
||||
ENUM_CLASS_OPERATORS(VMMFlags)
|
||||
|
||||
class VMMContext
|
||||
{
|
||||
friend class VMM;
|
||||
private:
|
||||
PageDirectory *directory;
|
||||
|
||||
/**
|
||||
* Gets the uint32_t that describes the given virtual address
|
||||
*/
|
||||
uint32_t & getPageDescriptor(virtual_t virt);
|
||||
public:
|
||||
VMMContext();
|
||||
~VMMContext();
|
||||
|
||||
/**
|
||||
* Maps an arbitrary page into the virtual memory.
|
||||
*/
|
||||
void provide(virtual_t virt, VMMFlags flags);
|
||||
|
||||
/**
|
||||
* Maps a given page into the virtual memory.
|
||||
*/
|
||||
void map(virtual_t virt, physical_t phys, VMMFlags flags);
|
||||
|
||||
/**
|
||||
* Unmaps a given page from the virtual memory.
|
||||
*/
|
||||
void unmap(virtual_t virt);
|
||||
};
|
||||
|
||||
class VMM
|
||||
{
|
||||
private:
|
||||
VMM() = delete;
|
||||
public:
|
||||
/**
|
||||
* Enables paging
|
||||
*/
|
||||
static void enable();
|
||||
|
||||
/**
|
||||
* Sets the given context as the current context.
|
||||
*/
|
||||
static void activate(VMMContext & context);
|
||||
};
|
7
prototypes-rework/include/lists/errors.lst
Normal file
7
prototypes-rework/include/lists/errors.lst
Normal file
|
@ -0,0 +1,7 @@
|
|||
ERROR(0, Success, Nothing went wrong. This should never encounter.)
|
||||
ERROR(1, OutOfMemory, The system has run out of memory.)
|
||||
ERROR(2, UnhandledException, An unhandled exception has occurred.)
|
||||
ERROR(3, UnhandledInterrupt, An unhandled interrupt has occurred.)
|
||||
ERROR(4, DriverAlreadyInstalled, A driver was already installed.)
|
||||
ERROR(5, InvalidELFImage, The file beeing loaded is not a valid ELF file.)
|
||||
ERROR(6, VMError, The virtual machine has failed.)
|
32
prototypes-rework/include/lists/exceptions.lst
Normal file
32
prototypes-rework/include/lists/exceptions.lst
Normal file
|
@ -0,0 +1,32 @@
|
|||
EXCEPTION(0x00, DE, DiviceByZero, Divide by Zero, Fault)
|
||||
EXCEPTION(0x01, DB, Debug, Debug, Fault | Trap)
|
||||
EXCEPTION(0x02, NMI, NonMaskableInterrupt, Non Maskable Interrupt, None)
|
||||
EXCEPTION(0x03, BP, Breakpoint, Breakpoint, Trap)
|
||||
EXCEPTION(0x04, OF, Overflow, Overflow, Trap)
|
||||
EXCEPTION(0x05, BR, BoundRange, Bound Range, Fault)
|
||||
EXCEPTION(0x06, UD, InvalidOpcode, Invalid Opcode, Fault)
|
||||
EXCEPTION(0x07, NM, DeviceNotAvailable, Device Not Available, Fault)
|
||||
EXCEPTION(0x08, DF, DoubleFault, Double Fault, Abort)
|
||||
EXCEPTION(0x09, CSO, CoprocessorSegmentOverrun, Coprocessor Segment Overrun, None)
|
||||
EXCEPTION(0x0a, TS, InvalidTSS, Invalid TSS, Fault)
|
||||
EXCEPTION(0x0b, NP, SegmentNotPresent, Segment not Present, Fault)
|
||||
EXCEPTION(0x0c, SS, StackFault, Stack Fault, Fault)
|
||||
EXCEPTION(0x0d, GP, GeneralProtectionFault, General Protection, Fault)
|
||||
EXCEPTION(0x0e, PF, PageFault, Page Fault, Fault)
|
||||
EXCEPTION(0x0f, XX, Reserved0, Reserved, None)
|
||||
EXCEPTION(0x10, MF, x87FloatingPoint, x87 Floating Point, Fault)
|
||||
EXCEPTION(0x11, AC, AlignmentCheck, Alignment Check, Fault)
|
||||
EXCEPTION(0x12, MC, MachineCheck, Machine Check, Abort)
|
||||
EXCEPTION(0x13, XF, SIMDFloatingPoint, SIMD Floating Point, Fault)
|
||||
EXCEPTION(0x14, XX, Reserved1, Reserved, None)
|
||||
EXCEPTION(0x15, XX, Reserved2, Reserved, None)
|
||||
EXCEPTION(0x16, XX, Reserved3, Reserved, None)
|
||||
EXCEPTION(0x17, XX, Reserved4, Reserved, None)
|
||||
EXCEPTION(0x18, XX, Reserved5, Reserved, None)
|
||||
EXCEPTION(0x19, XX, Reserved6, Reserved, None)
|
||||
EXCEPTION(0x1a, XX, Reserved7, Reserved, None)
|
||||
EXCEPTION(0x1b, XX, Reserved8, Reserved, None)
|
||||
EXCEPTION(0x1c, XX, Reserved9, Reserved, None)
|
||||
EXCEPTION(0x1d, XX, Reserved10, Reserved, None)
|
||||
EXCEPTION(0x1e, SX, SecuritySensitive, Security-sensitive event in Host, Fault)
|
||||
EXCEPTION(0x1f, XX, Reserved11, Reserved, None)
|
257
prototypes-rework/include/lists/interrupts.lst
Normal file
257
prototypes-rework/include/lists/interrupts.lst
Normal file
|
@ -0,0 +1,257 @@
|
|||
ISR(0)
|
||||
ISR(1)
|
||||
ISR(2)
|
||||
ISR(3)
|
||||
ISR(4)
|
||||
ISR(5)
|
||||
ISR(6)
|
||||
ISR(7)
|
||||
ISR_ERR(8)
|
||||
ISR(9)
|
||||
ISR_ERR(10)
|
||||
ISR_ERR(11)
|
||||
ISR_ERR(12)
|
||||
ISR_ERR(13)
|
||||
ISR_ERR(14)
|
||||
ISR(15)
|
||||
ISR(16)
|
||||
ISR_ERR(17)
|
||||
ISR(18)
|
||||
|
||||
ISR(19)
|
||||
ISR(20)
|
||||
ISR(21)
|
||||
ISR(22)
|
||||
ISR(23)
|
||||
ISR(24)
|
||||
ISR(25)
|
||||
ISR(26)
|
||||
ISR(27)
|
||||
ISR(28)
|
||||
ISR(29)
|
||||
ISR(30)
|
||||
ISR(31)
|
||||
ISR(32)
|
||||
ISR(33)
|
||||
ISR(34)
|
||||
ISR(35)
|
||||
ISR(36)
|
||||
ISR(37)
|
||||
ISR(38)
|
||||
ISR(39)
|
||||
ISR(40)
|
||||
ISR(41)
|
||||
ISR(42)
|
||||
ISR(43)
|
||||
ISR(44)
|
||||
ISR(45)
|
||||
ISR(46)
|
||||
ISR(47)
|
||||
ISR(48)
|
||||
ISR(49)
|
||||
ISR(50)
|
||||
ISR(51)
|
||||
ISR(52)
|
||||
ISR(53)
|
||||
ISR(54)
|
||||
ISR(55)
|
||||
ISR(56)
|
||||
ISR(57)
|
||||
ISR(58)
|
||||
ISR(59)
|
||||
ISR(60)
|
||||
ISR(61)
|
||||
ISR(62)
|
||||
ISR(63)
|
||||
ISR(64)
|
||||
ISR(65)
|
||||
ISR(66)
|
||||
ISR(67)
|
||||
ISR(68)
|
||||
ISR(69)
|
||||
ISR(70)
|
||||
ISR(71)
|
||||
ISR(72)
|
||||
ISR(73)
|
||||
ISR(74)
|
||||
ISR(75)
|
||||
ISR(76)
|
||||
ISR(77)
|
||||
ISR(78)
|
||||
ISR(79)
|
||||
ISR(80)
|
||||
ISR(81)
|
||||
ISR(82)
|
||||
ISR(83)
|
||||
ISR(84)
|
||||
ISR(85)
|
||||
ISR(86)
|
||||
ISR(87)
|
||||
ISR(88)
|
||||
ISR(89)
|
||||
ISR(90)
|
||||
ISR(91)
|
||||
ISR(92)
|
||||
ISR(93)
|
||||
ISR(94)
|
||||
ISR(95)
|
||||
ISR(96)
|
||||
ISR(97)
|
||||
ISR(98)
|
||||
ISR(99)
|
||||
ISR(100)
|
||||
ISR(101)
|
||||
ISR(102)
|
||||
ISR(103)
|
||||
ISR(104)
|
||||
ISR(105)
|
||||
ISR(106)
|
||||
ISR(107)
|
||||
ISR(108)
|
||||
ISR(109)
|
||||
ISR(110)
|
||||
ISR(111)
|
||||
ISR(112)
|
||||
ISR(113)
|
||||
ISR(114)
|
||||
ISR(115)
|
||||
ISR(116)
|
||||
ISR(117)
|
||||
ISR(118)
|
||||
ISR(119)
|
||||
ISR(120)
|
||||
ISR(121)
|
||||
ISR(122)
|
||||
ISR(123)
|
||||
ISR(124)
|
||||
ISR(125)
|
||||
ISR(126)
|
||||
ISR(127)
|
||||
ISR(128)
|
||||
ISR(129)
|
||||
ISR(130)
|
||||
ISR(131)
|
||||
ISR(132)
|
||||
ISR(133)
|
||||
ISR(134)
|
||||
ISR(135)
|
||||
ISR(136)
|
||||
ISR(137)
|
||||
ISR(138)
|
||||
ISR(139)
|
||||
ISR(140)
|
||||
ISR(141)
|
||||
ISR(142)
|
||||
ISR(143)
|
||||
ISR(144)
|
||||
ISR(145)
|
||||
ISR(146)
|
||||
ISR(147)
|
||||
ISR(148)
|
||||
ISR(149)
|
||||
ISR(150)
|
||||
ISR(151)
|
||||
ISR(152)
|
||||
ISR(153)
|
||||
ISR(154)
|
||||
ISR(155)
|
||||
ISR(156)
|
||||
ISR(157)
|
||||
ISR(158)
|
||||
ISR(159)
|
||||
ISR(160)
|
||||
ISR(161)
|
||||
ISR(162)
|
||||
ISR(163)
|
||||
ISR(164)
|
||||
ISR(165)
|
||||
ISR(166)
|
||||
ISR(167)
|
||||
ISR(168)
|
||||
ISR(169)
|
||||
ISR(170)
|
||||
ISR(171)
|
||||
ISR(172)
|
||||
ISR(173)
|
||||
ISR(174)
|
||||
ISR(175)
|
||||
ISR(176)
|
||||
ISR(177)
|
||||
ISR(178)
|
||||
ISR(179)
|
||||
ISR(180)
|
||||
ISR(181)
|
||||
ISR(182)
|
||||
ISR(183)
|
||||
ISR(184)
|
||||
ISR(185)
|
||||
ISR(186)
|
||||
ISR(187)
|
||||
ISR(188)
|
||||
ISR(189)
|
||||
ISR(190)
|
||||
ISR(191)
|
||||
ISR(192)
|
||||
ISR(193)
|
||||
ISR(194)
|
||||
ISR(195)
|
||||
ISR(196)
|
||||
ISR(197)
|
||||
ISR(198)
|
||||
ISR(199)
|
||||
ISR(200)
|
||||
ISR(201)
|
||||
ISR(202)
|
||||
ISR(203)
|
||||
ISR(204)
|
||||
ISR(205)
|
||||
ISR(206)
|
||||
ISR(207)
|
||||
ISR(208)
|
||||
ISR(209)
|
||||
ISR(210)
|
||||
ISR(211)
|
||||
ISR(212)
|
||||
ISR(213)
|
||||
ISR(214)
|
||||
ISR(215)
|
||||
ISR(216)
|
||||
ISR(217)
|
||||
ISR(218)
|
||||
ISR(219)
|
||||
ISR(220)
|
||||
ISR(221)
|
||||
ISR(222)
|
||||
ISR(223)
|
||||
ISR(224)
|
||||
ISR(225)
|
||||
ISR(226)
|
||||
ISR(227)
|
||||
ISR(228)
|
||||
ISR(229)
|
||||
ISR(230)
|
||||
ISR(231)
|
||||
ISR(232)
|
||||
ISR(233)
|
||||
ISR(234)
|
||||
ISR(235)
|
||||
ISR(236)
|
||||
ISR(237)
|
||||
ISR(238)
|
||||
ISR(239)
|
||||
ISR(240)
|
||||
ISR(241)
|
||||
ISR(242)
|
||||
ISR(243)
|
||||
ISR(244)
|
||||
ISR(245)
|
||||
ISR(246)
|
||||
ISR(247)
|
||||
ISR(248)
|
||||
ISR(249)
|
||||
ISR(250)
|
||||
ISR(251)
|
||||
ISR(252)
|
||||
ISR(253)
|
||||
ISR(254)
|
||||
ISR(255)
|
16
prototypes-rework/include/lists/irqs.lst
Normal file
16
prototypes-rework/include/lists/irqs.lst
Normal file
|
@ -0,0 +1,16 @@
|
|||
IRQ(0, Timer, Programmable Interval Timer)
|
||||
IRQ(1, PrimaryPS2, First PS/2 port / Keyboard Controller)
|
||||
IRQ(2, SecondaryPIC, Connection to secondary PIC)
|
||||
IRQ(3, RS232Even, RS-232 Port 2/4)
|
||||
IRQ(4, RS232Odd, RS-232 Port 1/3)
|
||||
IRQ(5, SecondaryLPT, LPT 2)
|
||||
IRQ(6, Floppy, Floppy Disk Controller)
|
||||
IRQ(7, PrimaryLPT, LPT 1 / Spurious Interrupt)
|
||||
IRQ(8, RTC, RTC (CMOS Real Time Clock))
|
||||
IRQ(9, Free, Free)
|
||||
IRQ(10, FourthIDE, Fourth ATA/ATAPI/(E)IDE)
|
||||
IRQ(11, ThirdIDE, Third ATA/ATAPI/(E)IDE)
|
||||
IRQ(12, SecondaryPS2, Second PS/2 Port / Mouse Controller)
|
||||
IRQ(13, FPU, FPU)
|
||||
IRQ(14, PrimaryIDE, Primary ATA/ATAPI/(E)IDE)
|
||||
IRQ(15, SecondaryIDE, Secundary ATA/ATAPI/(E)IDE / Spurious Interrupt)
|
169
prototypes-rework/include/multiboot.hpp
Normal file
169
prototypes-rework/include/multiboot.hpp
Normal file
|
@ -0,0 +1,169 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "pointer.hpp"
|
||||
|
||||
#define MB_MEMSIZE (1<<0)
|
||||
#define MB_BOOTDEVICE (1<<1)
|
||||
#define MB_COMMANDLINE (1<<2)
|
||||
#define MB_MODULES (1<<3)
|
||||
#define MB_SYMS_AOUT (1<<4)
|
||||
#define MB_SYMS_ELF (1<<5)
|
||||
#define MB_MEMORYMAP (1<<6)
|
||||
#define MB_DRIVES (1<<7)
|
||||
#define MB_CONFIG_TABLE (1<<8)
|
||||
#define MB_BOOTLOADER_NAME (1<<9)
|
||||
#define MB_APS_TABLE (1<<10)
|
||||
#define MB_VBE (1<<11)
|
||||
|
||||
#define MB_ASSERT_SIZE(type, len) static_assert(sizeof(type) == len, "multiboot::" #type " must be " #len " bytes large.")
|
||||
|
||||
namespace multiboot
|
||||
{
|
||||
template<typename T>
|
||||
class mbarray
|
||||
{
|
||||
public:
|
||||
const uint32_t length;
|
||||
private:
|
||||
T *data;
|
||||
|
||||
mbarray() = delete;
|
||||
public:
|
||||
T const & operator [](size_t idx) const {
|
||||
return this->data[idx];
|
||||
}
|
||||
|
||||
const T *begin() const {
|
||||
return &data[0];
|
||||
}
|
||||
const T *end() const {
|
||||
return &data[length];
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
// Make sure the size is not dependend on the template parameter
|
||||
MB_ASSERT_SIZE(mbarray<uint8_t>, 8);
|
||||
MB_ASSERT_SIZE(mbarray<uint32_t>, 8);
|
||||
|
||||
struct MemoryMap
|
||||
{
|
||||
uint32_t entry_size;
|
||||
uint64_t base;
|
||||
uint64_t length;
|
||||
uint32_t type;
|
||||
|
||||
|
||||
bool isFree() const {
|
||||
return this->type == 1;
|
||||
}
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
MB_ASSERT_SIZE(MemoryMap, 24);
|
||||
|
||||
struct Module
|
||||
{
|
||||
physical_t start;
|
||||
physical_t end;
|
||||
const char * name;
|
||||
uint32_t reserved;
|
||||
|
||||
uint32_t size() const {
|
||||
return this->end.numeric() - this->start.numeric();
|
||||
}
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
MB_ASSERT_SIZE(Module, 16);
|
||||
|
||||
struct Drive
|
||||
{
|
||||
uint32_t size;
|
||||
uint8_t number;
|
||||
uint8_t mode;
|
||||
uint16_t cylinders;
|
||||
uint8_t heads;
|
||||
uint8_t sectors;
|
||||
|
||||
// 0x10 size-0x10 drive_ports I/O-Ports, die von diesem Gerät benutzt werden
|
||||
// uint16_t ports[0];
|
||||
|
||||
/**
|
||||
* Gets the number of ports used by this drive.
|
||||
*/
|
||||
uint32_t portCount() const {
|
||||
return (this->size - 0x10) / sizeof(uint16_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the given port.
|
||||
* @return The port #idx or 0 if out of range.
|
||||
*/
|
||||
uint16_t port(size_t idx) const {
|
||||
uint16_t const * ports = reinterpret_cast<uint16_t const *>(reinterpret_cast<uint8_t const *>(this) + 0x10);
|
||||
if(idx >= this->portCount()) {
|
||||
return 0;
|
||||
}
|
||||
return ports[idx];
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
static_assert(sizeof(Drive) >= 10, "multiboot::Drive must be at least 12 bytes large.");
|
||||
|
||||
struct APMTable
|
||||
{
|
||||
uint16_t version;
|
||||
uint16_t cseg;
|
||||
uint32_t offset;
|
||||
uint16_t cseg_16;
|
||||
uint16_t dseg;
|
||||
uint16_t flags;
|
||||
uint16_t cseg_len;
|
||||
uint16_t cseg_16_len;
|
||||
uint16_t dseg_len;
|
||||
} __attribute__((packed));
|
||||
|
||||
MB_ASSERT_SIZE(APMTable, 20);
|
||||
|
||||
struct Structure
|
||||
{
|
||||
uint32_t flags;
|
||||
physical_t memLower;
|
||||
physical_t memUpper;
|
||||
uint32_t bootDevice;
|
||||
const char * commandline;
|
||||
mbarray<Module> modules;
|
||||
union {
|
||||
struct {
|
||||
uint32_t tabsize;
|
||||
uint32_t strsize;
|
||||
uint32_t addr;
|
||||
uint32_t reserved;
|
||||
} __attribute__((packed)) symsAssemblerOut;
|
||||
struct {
|
||||
uint32_t num;
|
||||
uint32_t size;
|
||||
uintptr_t addr;
|
||||
uintptr_t shndx;
|
||||
} __attribute__((packed)) symsELF;
|
||||
};
|
||||
mbarray<MemoryMap> memoryMaps;
|
||||
mbarray<Drive> drives;
|
||||
physical_t configTable;
|
||||
const char * bootLoaderName;
|
||||
const APMTable * apmTable;
|
||||
struct {
|
||||
uint32_t controlInfo;
|
||||
uint32_t modeInfo;
|
||||
uint16_t mode;
|
||||
uint16_t interfaceSegment;
|
||||
uint16_t interfaceOffset;
|
||||
uint16_t interfaceLength;
|
||||
} __attribute__((packed)) vbe;
|
||||
} __attribute__((packed));
|
||||
|
||||
MB_ASSERT_SIZE(Structure, 88);
|
||||
|
||||
}
|
49
prototypes-rework/include/numeric.hpp
Normal file
49
prototypes-rework/include/numeric.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
class Numeric
|
||||
{
|
||||
private:
|
||||
Numeric() = delete;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Converts an unsigned number to a string.
|
||||
* @param buffer The target buffer where the string should be stored.
|
||||
* @param length The length of the buffer.
|
||||
* @param number The number that should be converted.
|
||||
* @param radix The numeric base for the printed number.
|
||||
* @return The length of the converted strings.
|
||||
*/
|
||||
static size_t toString(
|
||||
char *buffer,
|
||||
size_t length,
|
||||
uint32_t number,
|
||||
uint32_t radix = 10);
|
||||
static size_t toString(
|
||||
char *buffer,
|
||||
size_t length,
|
||||
uint64_t number,
|
||||
uint32_t radix = 10);
|
||||
|
||||
/**
|
||||
* Converts a signed number to a string.
|
||||
* @param buffer The target buffer where the string should be stored.
|
||||
* @param length The length of the buffer.
|
||||
* @param number The number that should be converted.
|
||||
* @param radix The numeric base for the printed number.
|
||||
* @return The length of the converted strings.
|
||||
*/
|
||||
static size_t toString(
|
||||
char *buffer,
|
||||
size_t length,
|
||||
int32_t number,
|
||||
uint32_t radix = 10);
|
||||
static size_t toString(
|
||||
char *buffer,
|
||||
size_t length,
|
||||
int64_t number,
|
||||
uint32_t radix = 10);
|
||||
};
|
116
prototypes-rework/include/pointer.hpp
Normal file
116
prototypes-rework/include/pointer.hpp
Normal file
|
@ -0,0 +1,116 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Provides a strong pointer wrapper which can be used to address
|
||||
* different memory types (physical, virtual, ...) and preventing
|
||||
* a wrong assignment.
|
||||
* @remarks The pointer size is fixed to 32 bits.
|
||||
*/
|
||||
template<typename TIdent>
|
||||
class pointer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* A value that declares the pointer invalid.
|
||||
*/
|
||||
static pointer invalid;
|
||||
private:
|
||||
uint32_t ptr;
|
||||
public:
|
||||
/**
|
||||
* Creates the pointer by giving a raw pointer.
|
||||
*/
|
||||
explicit pointer(void *ptr) :
|
||||
ptr(reinterpret_cast<uint32_t>(ptr))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the pointer by giving an integer value.
|
||||
*/
|
||||
explicit pointer(uint32_t value) :
|
||||
ptr(value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pointer(const pointer &) = default;
|
||||
pointer(pointer &&) = default;
|
||||
~pointer() = default;
|
||||
|
||||
pointer & operator = (const pointer & other) {
|
||||
this->ptr = other.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric integer value of the pointer.
|
||||
*/
|
||||
uint32_t numeric() const {
|
||||
return this->ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pointer as a raw pointer.
|
||||
*/
|
||||
void * data() const {
|
||||
return reinterpret_cast<void*>(this->ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pointer as a raw typed pointer.
|
||||
*/
|
||||
template<typename T>
|
||||
T * data () const {
|
||||
return reinterpret_cast<T*>(this->ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow explicit conversion to a raw pointer.
|
||||
*/
|
||||
explicit operator void * () const {
|
||||
return this->data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an aligned version of the pointer.
|
||||
* Rounds the pointer to the memory bottom.
|
||||
*/
|
||||
pointer alignLower(uint32_t alignment) {
|
||||
if(alignment == 0) return pointer::invalid;
|
||||
return pointer(this->ptr & ~(alignment - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an aligned version of the pointer.
|
||||
* Rounds the pointer to the memory top.
|
||||
*/
|
||||
pointer alignUpper(uint32_t alignment) {
|
||||
if(alignment == 0) return pointer::invalid;
|
||||
return pointer((this->ptr + (alignment - 1)) & ~(alignment - 1));
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
template <class T>
|
||||
pointer<T> pointer<T>::invalid(uint32_t(0xFFFFFFFF));
|
||||
|
||||
struct physical_t_ident;
|
||||
struct virtual_t_ident;
|
||||
|
||||
// Add different memory pointer types here....
|
||||
|
||||
/**
|
||||
* A pointer pointing to physical memory.
|
||||
*/
|
||||
using physical_t = pointer<physical_t_ident>;
|
||||
|
||||
/**
|
||||
* A pointer pointing to virtual memory.
|
||||
*/
|
||||
using virtual_t = pointer<virtual_t_ident>;
|
||||
|
||||
|
||||
static_assert(sizeof(physical_t) == 4, "pointer is not 4 byte wide.");
|
64
prototypes-rework/include/screen.hpp
Normal file
64
prototypes-rework/include/screen.hpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum class Color : uint8_t
|
||||
{
|
||||
Black = 0,
|
||||
Blue = 1,
|
||||
Green = 2,
|
||||
Cyan = 3,
|
||||
Red = 4,
|
||||
Magenta = 5,
|
||||
Brown = 6,
|
||||
LightGray = 7,
|
||||
Gray = 8,
|
||||
LightBlue = 9,
|
||||
LightGreen = 10,
|
||||
LightCyan = 11,
|
||||
LightRed = 12,
|
||||
LightMagenta = 13,
|
||||
Yellow = 14,
|
||||
White = 15,
|
||||
};
|
||||
|
||||
using ColorInteger = uint8_t;
|
||||
|
||||
struct ScreenChar
|
||||
{
|
||||
char c;
|
||||
struct {
|
||||
ColorInteger fg : 4;
|
||||
ColorInteger bg : 4;
|
||||
};
|
||||
};
|
||||
|
||||
class Screen
|
||||
{
|
||||
private:
|
||||
static ScreenChar outOfScreen;
|
||||
public:
|
||||
static Screen main;
|
||||
private:
|
||||
ScreenChar * const buffer;
|
||||
public:
|
||||
const int width;
|
||||
const int height;
|
||||
public:
|
||||
Screen(ScreenChar *buffer, int width, int height);
|
||||
|
||||
void clear();
|
||||
|
||||
ScreenChar & operator ()(int x, int y) {
|
||||
if(x < 0 || y < 0 || x >= this->width || y >= this->height) {
|
||||
return Screen::outOfScreen;
|
||||
}
|
||||
return this->buffer[this->width * y + x];
|
||||
}
|
||||
ScreenChar const & operator ()(int x, int y) const {
|
||||
if(x < 0 || y < 0 || x >= this->width || y >= this->height) {
|
||||
return Screen::outOfScreen;
|
||||
}
|
||||
return this->buffer[this->width * y + x];
|
||||
}
|
||||
};
|
7
prototypes-rework/kernel.mk
Normal file
7
prototypes-rework/kernel.mk
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
|
||||
$(KERNEL): $(OBJS)
|
||||
$(LD) -T../linker.ld -o ../kernels/$@ $(addprefix obj/, $^) $(LDFLAGS) $(LIBS)
|
||||
|
||||
deploy: $(KERNEL)
|
||||
cp ../kernels/$(KERNEL) /srv/tftp/$(KERNEL)
|
12
prototypes-rework/libbase/Makefile
Normal file
12
prototypes-rework/libbase/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
##
|
||||
# Build base library parts of the libc.
|
||||
##
|
||||
|
||||
include ../config.mk
|
||||
|
||||
LIBRARY = libbase.a
|
||||
|
||||
all: builddir $(LIBRARY)
|
||||
|
||||
include ../common.mk
|
||||
include ../library.mk
|
19
prototypes-rework/libbase/src/string.c
Normal file
19
prototypes-rework/libbase/src/string.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
|
||||
|
||||
char * strcpy(char * dst, const char *src)
|
||||
{
|
||||
char * tmp = dst;
|
||||
while(((*tmp++) = (*src++)));
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *strcat(char * dst, const char *src)
|
||||
{
|
||||
char * tmp = dst;
|
||||
while(*tmp++);
|
||||
tmp--;
|
||||
while(((*tmp++) = (*src++)));
|
||||
return dst;
|
||||
}
|
12
prototypes-rework/libboot/Makefile
Normal file
12
prototypes-rework/libboot/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
##
|
||||
# Build multiboot entry point library.
|
||||
##
|
||||
|
||||
include ../config.mk
|
||||
|
||||
LIBRARY = libboot.a
|
||||
|
||||
all: builddir $(LIBRARY)
|
||||
|
||||
include ../common.mk
|
||||
include ../library.mk
|
17
prototypes-rework/libboot/compat.c
Normal file
17
prototypes-rework/libboot/compat.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "compat.h"
|
||||
|
||||
typedef void (*constructor)();
|
||||
|
||||
constructor start_ctors;
|
||||
constructor end_ctors;
|
||||
|
||||
void compat_call_ctors()
|
||||
{
|
||||
for (constructor* i = &start_ctors;i != &end_ctors;++i)
|
||||
(*i)();
|
||||
}
|
||||
|
||||
void compat_call_dtors()
|
||||
{
|
||||
|
||||
}
|
23
prototypes-rework/libboot/entrypoint.S
Normal file
23
prototypes-rework/libboot/entrypoint.S
Normal file
|
@ -0,0 +1,23 @@
|
|||
.section .text
|
||||
|
||||
.extern init
|
||||
.extern compat_call_ctors
|
||||
.extern compat_call_dtors
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
mov $kernel_stack, %esp
|
||||
|
||||
push %ebx
|
||||
call compat_call_ctors
|
||||
call init
|
||||
call compat_call_dtors
|
||||
|
||||
_stop:
|
||||
cli
|
||||
hlt
|
||||
jmp _stop
|
||||
|
||||
.section .bss
|
||||
.space 8192
|
||||
kernel_stack:
|
3
prototypes-rework/library.mk
Normal file
3
prototypes-rework/library.mk
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
$(LIBRARY): $(OBJS)
|
||||
$(AR) rcs ../libs/$(LIBRARY) $(addprefix obj/, $^)
|
37
prototypes-rework/linker.ld
Normal file
37
prototypes-rework/linker.ld
Normal file
|
@ -0,0 +1,37 @@
|
|||
ENTRY(_start)
|
||||
OUTPUT_FORMAT(elf32-i386)
|
||||
OUTPUT_ARCH(i386:i386)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x100000;
|
||||
|
||||
kernelStartMarker = .;
|
||||
|
||||
.text : {
|
||||
*(multiboot)
|
||||
*(.text)
|
||||
}
|
||||
.data ALIGN(4096) : {
|
||||
start_ctors = .;
|
||||
KEEP(*( .init_array ));
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
|
||||
end_ctors = .;
|
||||
|
||||
start_dtors = .;
|
||||
KEEP(*( .fini_array ));
|
||||
end_dtors = .;
|
||||
|
||||
*(.data)
|
||||
}
|
||||
.rodata ALIGN(4096) : {
|
||||
*(.rodata)
|
||||
}
|
||||
.bss ALIGN(4096) : {
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
/* Align the end of the kernel to the page size */
|
||||
. = ALIGN(4096);
|
||||
kernelEndMarker = .;
|
||||
}
|
22
prototypes-rework/syslinux.cfg
Normal file
22
prototypes-rework/syslinux.cfg
Normal file
|
@ -0,0 +1,22 @@
|
|||
DEFAULT menu.c32
|
||||
prompt 0
|
||||
|
||||
MENU TITLE DasOS Boot Menu
|
||||
MENU AUTOBOOT Starting DasOS in # seconds
|
||||
TIMEOUT 300
|
||||
TOTALTIMEOUT 9000
|
||||
|
||||
LABEL dasos
|
||||
MENU DEFAULT
|
||||
MENU LABEL DasOS
|
||||
KERNEL mboot.c32
|
||||
APPEND kernel-base.ker
|
||||
|
||||
LABEL video
|
||||
MENU LABEL VBE Video Test
|
||||
KERNEL mboot.c32
|
||||
APPEND video.ker
|
||||
|
||||
LABEL poweroff
|
||||
MENU LABEL Poweroff
|
||||
KERNEL poweroff.c32
|
13
prototypes-rework/video/Makefile
Normal file
13
prototypes-rework/video/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
##
|
||||
# Builds the video test kernel
|
||||
##
|
||||
|
||||
include ../config.mk
|
||||
|
||||
KERNEL = video.ker
|
||||
LIBS = -lboot
|
||||
|
||||
all: builddir $(KERNEL)
|
||||
|
||||
include ../common.mk
|
||||
include ../kernel.mk
|
28
prototypes-rework/video/multiboot.S
Normal file
28
prototypes-rework/video/multiboot.S
Normal file
|
@ -0,0 +1,28 @@
|
|||
.section multiboot
|
||||
|
||||
#define MB_MAGIC 0x1badb002
|
||||
#define MB_FLAGS 0x07
|
||||
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)
|
||||
|
||||
.align 4
|
||||
|
||||
// Offset Type Field Name Note
|
||||
// 0 u32 magic required
|
||||
// 4 u32 flags required
|
||||
// 8 u32 checksum required
|
||||
.int MB_MAGIC
|
||||
.int MB_FLAGS
|
||||
.int MB_CHECKSUM
|
||||
|
||||
// 12 u32 header_addr if flags[16] is set
|
||||
// 16 u32 load_addr if flags[16] is set
|
||||
// 20 u32 load_end_addr if flags[16] is set
|
||||
// 24 u32 bss_end_addr if flags[16] is set
|
||||
// 28 u32 entry_addr if flags[16] is set
|
||||
.int 0, 0, 0, 0, 0
|
||||
|
||||
// 32 u32 mode_type if flags[2] is set
|
||||
// 36 u32 width if flags[2] is set
|
||||
// 40 u32 height if flags[2] is set
|
||||
// 44 u32 depth if flags[2] is set
|
||||
.int 0, 640, 480, 32
|
95
prototypes-rework/video/src/init.cpp
Normal file
95
prototypes-rework/video/src/init.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <multiboot.hpp>
|
||||
#include <io.hpp>
|
||||
|
||||
struct dummy;
|
||||
|
||||
// Symbols generated by linker, no useful content in there...
|
||||
extern dummy kernelStartMarker;
|
||||
extern dummy kernelEndMarker;
|
||||
|
||||
uint16_t * video = (uint16_t*)0xB8000;
|
||||
|
||||
// Prüft, ob man bereits schreiben kann
|
||||
static uint8_t is_transmit_empty(uint16_t base) {
|
||||
return inb(base+5) & 0x20;
|
||||
}
|
||||
|
||||
// Byte senden
|
||||
static void write_com(uint16_t base, uint8_t chr) {
|
||||
while (is_transmit_empty(base)==0);
|
||||
outb(base,chr);
|
||||
}
|
||||
|
||||
#define VBE_FAR(name) uint32_t name;
|
||||
|
||||
struct ModeInfoBlock {
|
||||
uint16_t attributes;
|
||||
uint8_t winA,winB;
|
||||
uint16_t granularity;
|
||||
uint16_t winsize;
|
||||
uint16_t segmentA, segmentB;
|
||||
VBE_FAR(realFctPtr);
|
||||
uint16_t pitch; // bytes per scanline
|
||||
|
||||
uint16_t Xres, Yres;
|
||||
uint8_t Wchar, Ychar, planes, bpp, banks;
|
||||
uint8_t memory_model, bank_size, image_pages;
|
||||
uint8_t reserved0;
|
||||
|
||||
uint8_t red_mask, red_position;
|
||||
uint8_t green_mask, green_position;
|
||||
uint8_t blue_mask, blue_position;
|
||||
uint8_t rsv_mask, rsv_position;
|
||||
uint8_t directcolor_attributes;
|
||||
|
||||
uint32_t physbase; // your LFB (Linear Framebuffer) address ;)
|
||||
uint32_t reserved1;
|
||||
uint16_t reserved2;
|
||||
} __attribute__((packed));
|
||||
|
||||
static ModeInfoBlock mib;
|
||||
|
||||
static void setpixel(int x, int y, uint32_t color)
|
||||
{
|
||||
uint8_t *fb = (uint8_t*)mib.physbase;
|
||||
|
||||
fb[mib.pitch * y + 4 * x + 2] = (color >> 0) & 0xFF;
|
||||
fb[mib.pitch * y + 4 * x + 1] = (color >> 8) & 0xFF;
|
||||
fb[mib.pitch * y + 4 * x + 0] = (color >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
extern "C" void init(multiboot::Structure const & data)
|
||||
{
|
||||
write_com(0x3F8, 'H');
|
||||
write_com(0x3F8, 'i');
|
||||
write_com(0x3F8, '\n');
|
||||
|
||||
const char *msg = "You should not see this.";
|
||||
while(*msg)
|
||||
{
|
||||
*(video++) = *msg++ | 0x0700;
|
||||
}
|
||||
|
||||
mib = *(ModeInfoBlock*)data.vbe.modeInfo;
|
||||
|
||||
for(int y = 0; y < mib.Yres; y++)
|
||||
{
|
||||
for(int x = 0; x < mib.Xres; x++)
|
||||
{
|
||||
uint32_t r = x % 256;
|
||||
uint32_t g = y % 256;
|
||||
uint32_t b = 0x00;
|
||||
|
||||
setpixel(x, y, r | (g << 8) | (b << 16));
|
||||
}
|
||||
}
|
||||
|
||||
write_com(0x3F8, 'B');
|
||||
write_com(0x3F8, 'y');
|
||||
write_com(0x3F8, 'e');
|
||||
write_com(0x3F8, '\n');
|
||||
|
||||
while(true);
|
||||
}
|
Loading…
Reference in a new issue