1

Setup cmake project

This commit is contained in:
2022-12-07 16:40:43 +01:00
parent db2816a092
commit f304e7f239
138 changed files with 28939 additions and 0 deletions

View File

@ -0,0 +1,305 @@
/*****************************************************************************
* *
* B L U E S C R E E N *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Ein Bluescreen, falls eine x86 Exception auftritt. Evt. *
* ist der Stack und oder Heap kaputt, weswegen hier nicht *
* kout etc. verwendet wird. *
* *
* Autor: Michael Schoettner, 11.12.2018 *
*****************************************************************************/
#include "kernel/system/Globals.h"
// in startup.asm
extern "C" {
// CR2 auslesen
unsigned int get_page_fault_address();
// 1st level interrupt handler in startup.asm sichert Zeiger auf Stackframe
// unmittelbar nach dem Interrupt und nachdem alle Register mit PUSHAD
// gesichert wurden
// |-------------|
// |  EFLAGS |
// |-------------|
// | CS |
// |-------------|
// | EIP |
// |-------------|
// | [ErrorCode] |
// |-------------|
// | EAX |
// |-------------|
// | ECX |
// |-------------|
// | EDX |
// |-------------|
// | EBX |
// |-------------|
// | ESP |
// |-------------|
// | EBP |
// |-------------|
// | ESI |
// |-------------|
// | EDI |
// |-------------| <-- int_esp
void get_int_esp(unsigned int** esp);
}
void break_on_bluescreen() {
/* wenn auf diese Methode ein breakpoint in GDB gesetzt wird
so kann man sich mithilfe des Hex-Dumps umsehen
*/
}
// Cursor-Position
int bs_xpos = 0;
int bs_ypos = 0;
/*****************************************************************************
* Funktion: bs_clear *
*---------------------------------------------------------------------------*
* Beschreibung: Bildschirm loeschen. *
*****************************************************************************/
void bs_clear() {
unsigned int x;
unsigned int y;
unsigned short* ptr = reinterpret_cast<unsigned short*>(0xb8000);
for (x = 0; x < 80; x++) {
for (y = 0; y < 25; y++) {
*(ptr + y * 80 + x) = static_cast<short>(0x1F00);
}
}
bs_xpos = 0;
bs_ypos = 0;
}
/*****************************************************************************
* Funktion: bs_lf *
*---------------------------------------------------------------------------*
* Beschreibung: Zeilenvorschub. *
*****************************************************************************/
void bs_lf() {
bs_ypos++;
bs_xpos = 0;
}
/*****************************************************************************
* Funktion: bs_print_char *
*---------------------------------------------------------------------------*
* Beschreibung: Ein Zeichen ausgeben. *
*****************************************************************************/
void bs_print_char(char c) {
unsigned char* ptr = reinterpret_cast<unsigned char*>(0xb8000);
*(ptr + bs_ypos * 80 * 2 + bs_xpos * 2) = c;
bs_xpos++;
}
/*****************************************************************************
* Funktion: bs_print_string *
*---------------------------------------------------------------------------*
* Beschreibung: Eine Zeichenkette ausgeben. *
*****************************************************************************/
void bs_print_string(char* str) {
while (*str != '\0') {
bs_print_char(*str);
str++;
}
}
/*****************************************************************************
* Funktion: bs_printHexDigit *
*---------------------------------------------------------------------------*
* Beschreibung: Ein Hex-Zeichen ausgeben. *
*****************************************************************************/
void bs_printHexDigit(int c) {
if (c < 10) {
bs_print_char('0' + static_cast<unsigned char>(c));
} else {
bs_print_char('A' + static_cast<unsigned char>(c - 10));
}
}
/*****************************************************************************
* Funktion: bs_print_uintHex *
*---------------------------------------------------------------------------*
* Beschreibung: Integer ausgeben. *
*****************************************************************************/
void bs_print_uintHex(unsigned int c) {
for (int i = 28; i >= 0; i = i - 4) {
bs_printHexDigit((c >> i) & 0xF);
}
}
/*****************************************************************************
* Funktion: bs_printReg *
*---------------------------------------------------------------------------*
* Beschreibung: String mit Integer ausgeben. Wird verwendet um ein *
* Register auszugeben. *
*****************************************************************************/
void bs_printReg(char* str, unsigned int value) {
bs_print_string(str);
bs_print_uintHex(value);
bs_print_string(" \0");
}
/*****************************************************************************
* Funktion: bs_dump *
*---------------------------------------------------------------------------*
* Beschreibung: Hauptroutine des Bluescreens. *
*****************************************************************************/
void bs_dump(unsigned int exceptionNr) {
unsigned int* int_esp;
unsigned int* sptr;
unsigned int faultAdress;
unsigned int has_error_code = 0;
bs_clear();
bs_print_string("HHUos crashed with Exception \0");
// Exception mit Error-Code?
if ((exceptionNr >= 8 && exceptionNr <= 14) || exceptionNr == 17 || exceptionNr == 30) {
has_error_code = 1;
}
// Liegt ein Page-Fault vor?
if (exceptionNr == 14) {
faultAdress = get_page_fault_address();
// Zugriff auf Seite 0 ? -> Null-Ptr. Exception
if ((faultAdress & 0xFFFFF000) == 0) {
exceptionNr = 0x1B;
}
}
bs_print_uintHex(exceptionNr);
bs_print_string(" (\0");
// Spruch ausgeben
switch (exceptionNr) {
case 0x00: bs_print_string("Divide Error\0"); break;
case 0x01: bs_print_string("Debug Exception\0"); break;
case 0x02: bs_print_string("NMI\0"); break;
case 0x03: bs_print_string("Breakpoint Exception\0"); break;
case 0x04: bs_print_string("Into Exception\0"); break;
case 0x05: bs_print_string("Index out of range Exception\0"); break;
case 0x06: bs_print_string("Invalid Opcode\0"); break;
case 0x08: bs_print_string("Double Fault\0"); break;
case 0x0D: bs_print_string("General Protection Error\0"); break;
case 0x0E: bs_print_string("Page Fault\0"); break;
case 0x18: bs_print_string("Stack invalid\0"); break;
case 0x19: bs_print_string("Return missing\0"); break;
case 0x1A: bs_print_string("Type Test Failed\0"); break;
case 0x1B: bs_print_string("Null pointer exception\0"); break;
case 0x1C: bs_print_string("MAGIC.StackTest failed\0"); break;
case 0x1D: bs_print_string("Memory-Panic\0"); break;
case 0x1E: bs_print_string("Pageload failed\0"); break;
case 0x1F: bs_print_string("Stack overflow\0"); break;
default: bs_print_string("unknown\0");
}
bs_print_string(")\0");
bs_lf();
// Zeiger auf int_esp ueber startup.asm beschaffen (Stack-Layout siehe Anfang dieser Datei)
get_int_esp(&int_esp);
// wir müssen den Inhalt auslesen und das als Zeiger verwenden, um den Stack auszulesen
sptr = reinterpret_cast<unsigned int*>(*int_esp);
bs_lf();
// wichtigste Register ausgeben
// Exception mit Error-Code?
bs_printReg("EIP=\0", *(sptr + 8 + has_error_code));
bs_printReg("EBP=\0", *(sptr + 2));
bs_printReg("ESP=\0", *(sptr + 3));
bs_printReg(" CS=\0", *(sptr + 9 + has_error_code));
bs_lf();
// verbleibende nicht-fluechtige Register ausgeben
bs_printReg("EBX=\0", *(sptr + 4));
bs_printReg("ESI=\0", *(sptr + 1));
bs_printReg("EDI=\0", *(sptr));
bs_lf();
// verbleibende fluechtige Register ausgeben
bs_printReg("EDX=\0", *(sptr + 5));
bs_printReg("ECX=\0", *(sptr + 6));
bs_printReg("EAX=\0", *(sptr + 7));
bs_printReg("EFL=\0", *(sptr + 10));
bs_lf();
// Pagefault oder Null-Pointer?
if (exceptionNr == 14 || exceptionNr == 0x1B) {
bs_lf();
bs_print_string("Fault address = \0");
bs_print_uintHex(faultAdress);
bs_lf();
bs_print_string("Last useable address = \0");
bs_print_uintHex(total_mem - 1);
bs_lf();
}
// Exception mit Error-Code?
if (has_error_code == 1) {
unsigned int error_nr = *(sptr + 8);
if (exceptionNr == 14) {
if (error_nr == 3) {
bs_print_string("Error: write access to read-only page.\0");
} else if (error_nr == 2) {
bs_print_string("Error: read access to not-present page.\0");
} else if (error_nr == 0) {
bs_print_string("Error: access to a not-present page.\0");
} else {
bs_print_string("Error code = \0");
bs_print_uintHex(error_nr);
}
bs_lf();
} else {
bs_print_string("Error code = \0");
bs_print_uintHex(error_nr);
bs_lf();
}
}
// Calling stack ...
bs_lf();
bs_print_string("Calling Stack:\0");
bs_lf();
int x = 0;
unsigned int* ebp = reinterpret_cast<unsigned int*>(*(sptr + 2));
unsigned int raddr;
// solange eip > 1 MB && ebp < 128 MB, max. Aufruftiefe 10
while (*ebp > 0x100000 && *ebp < 0x8000000 && x < 10) {
raddr = *(ebp + 1);
bs_printReg(" raddr=\0", raddr);
bs_lf();
// dynamische Kette -> zum Aufrufer
ebp = reinterpret_cast<unsigned int*>(*ebp);
x++;
}
if (x == 0) {
bs_print_string(" empty\0");
bs_lf();
}
bs_lf();
// nur falls gdb benutzt werden soll
break_on_bluescreen();
bs_print_string("System halted\0");
}

View File

@ -0,0 +1,19 @@
/*****************************************************************************
* *
* B L U E S C R E E N *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Ein Bluescreen, falls eine x86 Exception auftritt. Evt. *
* ist der Stack und oder Heap kaputt, weswegen hier nicht *
* kout etc. verwendet wird. *
* *
* Autor: Michael Schoettner, 2.2.2017 *
*****************************************************************************/
#ifndef Bluescreen_include__
#define Bluescreen_include__
// dump blue screen (will not return)
void bs_dump(unsigned int exceptionNr);
#endif

27
src/kernel/interrupt/ISR.h Executable file
View File

@ -0,0 +1,27 @@
/*****************************************************************************
* *
* I S R *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Interrupt Service Routine. Jeweils ein Objekt pro ISR. *
* Erlaubt es einen Kontext mit Variablen fuer die Unter- *
* brechungsroutine bereitzustellen. *
* *
* Autor: Michael Schoettner, 06.04.20 *
*****************************************************************************/
#ifndef ISR_include__
#define ISR_include__
class ISR {
public:
ISR(const ISR& copy) = delete; // Verhindere Kopieren
// virtual ~ISR() = default;
ISR() = default;
// Unterbrechungsbehandlungsroutine
virtual void trigger() = 0;
};
#endif

View File

@ -0,0 +1,109 @@
/*****************************************************************************
* *
* I N T D I S P A T C H E R *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Zentrale Unterbrechungsbehandlungsroutine des Systems. *
* Der Parameter gibt die Nummer des aufgetretenen *
* Interrupts an. Wenn eine Interrupt Service Routine *
* registriert ist, wird diese aufgerufen. *
* *
* Autor: Michael Schoettner, 31.8.2016 *
*****************************************************************************/
#include "IntDispatcher.h"
#include "device/cpu/CPU.h"
#include "kernel/system/Globals.h"
#include "kernel/interrupt/Bluescreen.h"
extern "C" void int_disp(unsigned int vector);
/*****************************************************************************
* Prozedur: int_disp *
*---------------------------------------------------------------------------*
* Beschreibung: Low-Level Interrupt-Behandlung. *
* Diese Funktion ist in der IDT fuer alle Eintraege einge- *
* tragen. Dies geschieht bereits im Bootloader. *
* Sie wird also fuer alle Interrupts aufgerufen. Von hier *
* aus sollen die passenden ISR-Routinen der Treiber-Objekte*
* mithilfe von 'IntDispatcher::report' aufgerufen werden. *
* Parameter: *
* vector: Vektor-Nummer der Unterbrechung *
*****************************************************************************/
void int_disp(unsigned int vector) {
/* hier muss Code eingefuegt werden */
if (vector < 32) {
bs_dump(vector);
CPU::halt();
}
if (intdis.report(vector) < 0) {
kout << "Panic: unexpected interrupt " << vector;
kout << " - processor halted." << endl;
CPU::halt();
}
}
/*****************************************************************************
* Methode: IntDispatcher::assign *
*---------------------------------------------------------------------------*
* Beschreibung: Registrierung einer ISR. *
* *
* Parameter: *
* vector: Vektor-Nummer der Unterbrechung *
* isr: ISR die registriert werden soll *
* *
* Rueckgabewert: 0 = Erfolg, -1 = Fehler *
*****************************************************************************/
int IntDispatcher::assign(unsigned int vector, ISR& isr) {
/* hier muss Code eingefuegt werden */
if (vector >= size) {
log.error() << "Invalid vector number when assigning" << endl;
return -1;
}
map[vector] = &isr;
log.info() << "Registered ISR for vector " << dec << vector << endl;
return 0;
}
/*****************************************************************************
* Methode: IntDispatcher::report *
*---------------------------------------------------------------------------*
* Beschreibung: Eingetragene ISR ausfuehren. *
* *
* Parameter: *
* vector: Gesuchtes ISR-Objekt fuer diese Vektor-Nummer. *
* *
* Rueckgabewert: 0 = ISR wurde aufgerufen, -1 = unbekannte Vektor-Nummer *
*****************************************************************************/
int IntDispatcher::report(unsigned int vector) {
/* hier muss Code eingefuegt werden */
if (vector >= size) {
return -1;
}
ISR* isr = map[vector];
if (isr == nullptr) {
log.error() << "No ISR registered for vector " << vector << endl;
return -1;
}
// 32 = Timer
// 33 = Keyboard
// log.trace() << "Interrupt: " << dec << vector << endl;
if (vector == 33) {
log.debug() << "Keyboard Interrupt" << endl;
}
isr->trigger();
return 0;
}

View File

@ -0,0 +1,51 @@
/*****************************************************************************
* *
* I N T D I S P A T C H E R *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Zentrale Unterbrechungsbehandlungsroutine des Systems. *
* Der Parameter gibt die Nummer des aufgetretenen *
* Interrupts an. Wenn eine Interrupt Service Routine (ISR) *
* in der Map registriert ist, so wird diese aufgerufen. *
* *
* Autor: Michael Schoettner, 30.7.16 *
*****************************************************************************/
#ifndef IntDispatcher_include__
#define IntDispatcher_include__
#include "ISR.h"
#include "lib/util/Array.h"
#include "kernel/log/Logger.h"
class IntDispatcher {
private:
NamedLogger log;
enum { size = 256 };
bse::array<ISR*, size> map;
public:
IntDispatcher(const IntDispatcher& copy) = delete; // Verhindere Kopieren
// Vektor-Nummern
enum {
timer = 32,
keyboard = 33,
com1 = 36
};
// Initialisierung der ISR map mit einer Default-ISR.
IntDispatcher() : log("IntDis") {
for (ISR*& slot : map) {
slot = nullptr;
}
}
// Registrierung einer ISR. (Rueckgabewert: 0 = Erfolg, -1 = Fehler)
int assign(unsigned int vector, ISR& isr);
// ISR fuer 'vector' ausfuehren
int report(unsigned int vector);
};
#endif