Adds linker script, C++ support and a simple screen class.
This commit is contained in:
parent
cd5d85f99c
commit
f85042a9c7
10 changed files with 206 additions and 46 deletions
|
@ -1,21 +1,24 @@
|
|||
|
||||
AS=clang
|
||||
CC=clang
|
||||
CXX=clang++
|
||||
AS=gcc
|
||||
CC=gcc
|
||||
CXX=g++
|
||||
LD=ld
|
||||
|
||||
FLAGS = -ffreestanding -m32
|
||||
FLAGS = -ffreestanding -m32 -Wall -iquote include
|
||||
ASFLAGS = $(FLAGS)
|
||||
CFLAGS = $(FLAGS)
|
||||
CXXFLAGS = $(FLAGS)
|
||||
CXXFLAGS = $(FLAGS) -std=c++14 -fno-rtti -fno-exceptions -fno-leading-underscore -fno-use-cxa-atexit -nostdlib -fno-builtin
|
||||
|
||||
SRCS = $(shell find -name '*.[cS]')
|
||||
SRCS = $(shell find -regextype egrep -regex '.*/.*\.(cpp|S|c)')
|
||||
OBJS = $(addsuffix .o, $(notdir $(basename $(SRCS))))
|
||||
|
||||
all: kernel-base.ker
|
||||
|
||||
kernel-base.ker: $(OBJS)
|
||||
$(LD) -melf_i386 -Ttext=0x1000000 -o kernel-base.ker $(addprefix obj/, $^)
|
||||
$(LD) -melf_i386 -Tlinker.ld -o kernel-base.ker $(addprefix obj/, $^)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(ASFLAGS) -c -o obj/$@ $<
|
||||
|
@ -23,5 +26,16 @@ kernel-base.ker: $(OBJS)
|
|||
%.o: %.S
|
||||
$(AS) $(CFLAGS) -c -o obj/$@ $<
|
||||
|
||||
%.o: %.cpp
|
||||
$(CPP) $(CXXFLAGS) -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/$@ $<
|
||||
|
||||
run:
|
||||
qemu-system-i386 -kernel kernel-base.ker
|
||||
|
||||
bnr: kernel-base.ker run
|
|
@ -1,30 +1,22 @@
|
|||
.section .text
|
||||
|
||||
// Init ist eine Funktion aus init.c
|
||||
.extern init
|
||||
.extern compat_call_ctors
|
||||
.extern compat_call_dtors
|
||||
|
||||
// _start muss global sein, damit der Linker es findet und als Einsprungspunkt
|
||||
// benutzen kann (alle Labels, die nicht global sind, sind nur in dieser Datei
|
||||
// sichtbar)
|
||||
.global _start
|
||||
_start:
|
||||
// Stack initialisieren
|
||||
mov $kernel_stack, %esp
|
||||
mov $kernel_stack, %esp
|
||||
|
||||
// C-Code aufrufen
|
||||
call init
|
||||
call compat_call_ctors
|
||||
call init
|
||||
call compat_call_dtors
|
||||
|
||||
// Falls wir jemals aus init zurueckkommen sollten, sperren wir die Interrupts und
|
||||
// halten einfach den Prozessor an. (man braucht ihn ja nicht unnötig heißlaufen lassen.)
|
||||
_stop:
|
||||
cli
|
||||
hlt
|
||||
cli
|
||||
hlt
|
||||
jmp _stop
|
||||
|
||||
// Sollte es doch weitergehen, probieren wir erneut die CPU schlafen zu lassen
|
||||
jmp _stop
|
||||
|
||||
// 8 kB Stack fuer den Kernel. Das Label steht hinter dem freien Speicher,
|
||||
// weil der Stack nach unten waechst
|
||||
.section .bss
|
||||
.space 8192
|
||||
kernel_stack:
|
13
prototypes/base/include/compat.h
Normal file
13
prototypes/base/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
|
63
prototypes/base/include/screen.hpp
Normal file
63
prototypes/base/include/screen.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include <inttypes.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;
|
||||
private:
|
||||
ScreenChar * const buffer;
|
||||
const int width;
|
||||
const int height;
|
||||
public:
|
||||
static Screen main;
|
||||
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];
|
||||
}
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
void init(void)
|
||||
{
|
||||
const char hw[] = "Hello World!";
|
||||
int i;
|
||||
char* video = (char*) 0xb8000;
|
||||
|
||||
// C-Strings haben ein Nullbyte als Abschluss
|
||||
for (i = 0; hw[i] != '\0'; i++) {
|
||||
|
||||
// Zeichen i in den Videospeicher kopieren
|
||||
video[i * 2] = hw[i];
|
||||
|
||||
// 0x07 = Hellgrau auf Schwarz
|
||||
video[i * 2 + 1] = 0x07;
|
||||
}
|
||||
}
|
21
prototypes/base/init.cpp
Normal file
21
prototypes/base/init.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <inttypes.h>
|
||||
|
||||
#include "screen.hpp"
|
||||
#include "compat.h"
|
||||
|
||||
extern "C" void init(void)
|
||||
{
|
||||
const char hw[] = "Hello World!";
|
||||
int i;
|
||||
|
||||
// C-Strings haben ein Nullbyte als Abschluss
|
||||
for (i = 0; hw[i] != '\0'; i++) {
|
||||
|
||||
// Zeichen i in den Videospeicher kopieren
|
||||
Screen::main(i,0).c = hw[i];
|
||||
|
||||
// 0x07 = Hellgrau auf Schwarz
|
||||
Screen::main(i,0).fg = (int)Color::Black;
|
||||
Screen::main(i,0).bg = (int)Color::LightRed;
|
||||
}
|
||||
}
|
37
prototypes/base/linker.ld
Normal file
37
prototypes/base/linker.ld
Normal file
|
@ -0,0 +1,37 @@
|
|||
ENTRY(_start)
|
||||
OUTPUT_FORMAT(elf32-i386)
|
||||
OUTPUT_ARCH(i386:i386)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x100000;
|
||||
|
||||
kernelStart = .;
|
||||
|
||||
.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);
|
||||
kernelEnd = .;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
.section .text
|
||||
.section multiboot
|
||||
|
||||
#define MB_MAGIC 0x1badb002
|
||||
#define MB_FLAGS 0x0
|
||||
|
|
17
prototypes/base/src/compat.c
Normal file
17
prototypes/base/src/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()
|
||||
{
|
||||
|
||||
}
|
19
prototypes/base/src/screen.cpp
Normal file
19
prototypes/base/src/screen.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include <inttypes.h>
|
||||
#include "screen.hpp"
|
||||
|
||||
ScreenChar Screen::outOfScreen;
|
||||
Screen Screen::main((ScreenChar*)0xb8000, 80, 25);
|
||||
|
||||
Screen::Screen(ScreenChar *buffer, int width, int height) :
|
||||
buffer(buffer),
|
||||
width(width),
|
||||
height(height)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void Screen::clear() {
|
||||
for(int i = 0; i < this->width * this->height; i++) {
|
||||
this->buffer[i].c = ' ';
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue