Merge branch 'feature-08-paging'
This commit is contained in:
0
.gitignore
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
0
boot/Makefile
Executable file → Normal file
0
boot/Makefile
Executable file → Normal file
0
boot/bootsect.asm
Executable file → Normal file
0
boot/bootsect.asm
Executable file → Normal file
0
boot/setup.asm
Executable file → Normal file
0
boot/setup.asm
Executable file → Normal file
0
c_os/.clang-tidy
Executable file → Normal file
0
c_os/.clang-tidy
Executable file → Normal file
@ -70,10 +70,13 @@ DELETE = rm
|
|||||||
ASM = nasm
|
ASM = nasm
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CXX ?= g++
|
CXX ?= g++
|
||||||
CFLAGS := $(CFLAGS) -m32 -march=i486 -Wall -fno-stack-protector -nostdlib -I. -g -ffreestanding -fno-pie -fno-pic -mpreferred-stack-boundary=2 -Wno-write-strings -mno-sse -mno-sse2 -mmanual-endbr
|
|
||||||
CXXFLAGS := $(CFLAGS) -Wno-non-virtual-dtor -fno-threadsafe-statics -fno-use-cxa-atexit -fno-rtti -fno-exceptions -std=c++17
|
# I added O0 to allow paging/bluescreen to work (We need the ebp on the stack)
|
||||||
|
CFLAGS := $(CFLAGS) -O0 -m32 -march=i486 -Wall -fno-stack-protector -nostdlib -I. -g -ffreestanding -fno-pie -fno-pic -mpreferred-stack-boundary=2 -Wno-write-strings -mno-sse -mno-sse2 -mmanual-endbr
|
||||||
|
|
||||||
# I added -std=c++17 for if constexpr, but it isn't necessary for anything critical
|
# I added -std=c++17 for if constexpr, but it isn't necessary for anything critical
|
||||||
# Needed for template concepts, but we don't have it available: -std=c++20
|
# Needed for template concepts, but we don't have it available: -std=c++20
|
||||||
|
CXXFLAGS := $(CFLAGS) -Wno-non-virtual-dtor -fno-threadsafe-statics -fno-use-cxa-atexit -fno-rtti -fno-exceptions -std=c++17
|
||||||
|
|
||||||
BOOT = ../boot
|
BOOT = ../boot
|
||||||
TOOLS = ../tools
|
TOOLS = ../tools
|
||||||
|
|||||||
@ -15,7 +15,8 @@
|
|||||||
#ifndef __CGA_Stream_include__
|
#ifndef __CGA_Stream_include__
|
||||||
#define __CGA_Stream_include__
|
#define __CGA_Stream_include__
|
||||||
|
|
||||||
#include "devices/BufferedCGA.h"
|
// #include "devices/BufferedCGA.h"
|
||||||
|
#include "devices/CGA.h"
|
||||||
#include "lib/OutStream.h"
|
#include "lib/OutStream.h"
|
||||||
|
|
||||||
// NOTE: I added this
|
// NOTE: I added this
|
||||||
@ -33,7 +34,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: I added this (changed this) to use BufferedCGA
|
// NOTE: I added this (changed this) to use BufferedCGA
|
||||||
class CGA_Stream : public OutStream, public BufferedCGA {
|
class CGA_Stream : public OutStream, public CGA {
|
||||||
private:
|
private:
|
||||||
CGA_Stream(CGA_Stream& copy) = delete; // Verhindere Kopieren
|
CGA_Stream(CGA_Stream& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
|
|||||||
@ -340,9 +340,10 @@ void Keyboard::trigger() {
|
|||||||
// NOTE: My keyboard has no delete key...
|
// NOTE: My keyboard has no delete key...
|
||||||
if (key.ctrl_left() && key.alt_left() && (char)key == 'r') {
|
if (key.ctrl_left() && key.alt_left() && (char)key == 'r') {
|
||||||
this->reboot();
|
this->reboot();
|
||||||
} else if ((char)key == 'k' || (char)key == 'j') {
|
|
||||||
scroll_mode(key);
|
|
||||||
}
|
}
|
||||||
|
// else if ((char)key == 'k' || (char)key == 'j') {
|
||||||
|
// scroll_mode(key);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Where to place this?
|
// TODO: Where to place this?
|
||||||
@ -350,13 +351,13 @@ void Keyboard::trigger() {
|
|||||||
// - Ereignisverwaltung, wo man Threads registrieren kann
|
// - Ereignisverwaltung, wo man Threads registrieren kann
|
||||||
// - Blockierte Threads verwalten und aufwecken bei ereignissen
|
// - Blockierte Threads verwalten und aufwecken bei ereignissen
|
||||||
// Waits for keys to control the scrollback buffer display
|
// Waits for keys to control the scrollback buffer display
|
||||||
void scroll_mode(Key key) {
|
// void scroll_mode(Key key) {
|
||||||
switch ((char)key) {
|
// switch ((char)key) {
|
||||||
case 'k':
|
// case 'k':
|
||||||
kout.scroll_page_backward();
|
// kout.scroll_page_backward();
|
||||||
break;
|
// break;
|
||||||
case 'j':
|
// case 'j':
|
||||||
kout.scroll_page_forward();
|
// kout.scroll_page_forward();
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
211
c_os/kernel/Paging.cc
Normal file
211
c_os/kernel/Paging.cc
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* *
|
||||||
|
* P A G I N G *
|
||||||
|
* *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Rudimentaeres Paging: 1:1 Mapping fuer gesamten logischen*
|
||||||
|
* Adressraum. logische Adresse = physikalische Adresse *
|
||||||
|
* *
|
||||||
|
* Page-Directory (alle Eintraege present, read/write *
|
||||||
|
* 0. Eintrag zeigt auf eine Page-Table (4 KB Eintraege)*
|
||||||
|
* Alle restl. Eintraege sind 4 MB Seiten und verweisen *
|
||||||
|
* somit auf keine Page-Tabelle sondern direkt auf die *
|
||||||
|
* 4 MB Seite. *
|
||||||
|
* *
|
||||||
|
* Page-Table (Logische Adressen 0 - 4 MB) *
|
||||||
|
* 1. Eintrag not present, read-only *
|
||||||
|
* -> Null-Pointer abfangen *
|
||||||
|
* 2. restl. Eintraege present & read/write *
|
||||||
|
* *
|
||||||
|
* Memory-Laylout *
|
||||||
|
* *
|
||||||
|
* boot.asm *
|
||||||
|
* 0x07c0: Bootsector vom BIOS geladen *
|
||||||
|
* 0x0060: Boot-Code verschiebt sich hier hin *
|
||||||
|
* 0x9000: Setup-Code (max. 64K inkl. Stack) vom *
|
||||||
|
* Bootsector-Code geladen *
|
||||||
|
* setup.asm *
|
||||||
|
* 0x1000: System-Code (max. 512K) geladen *
|
||||||
|
* BIOS-Aufruf *
|
||||||
|
* 0x24000: Parameter fuer BIOS-Aufurf *
|
||||||
|
* 0x25000: Altes ESP sichern, vor BIOS-Aufruf *
|
||||||
|
* 0x26000: 16-Bit Code-Segment fuer BIOS-Aufurf *
|
||||||
|
* System-Code *
|
||||||
|
* 0x100000: System-Code, kopiert nach Umschalten in *
|
||||||
|
* den Protected Mode kopiert (GRUB kann nur *
|
||||||
|
* an Adressen >1M laden) *
|
||||||
|
* Globale Variablen: Direkt nach dem Code liegen die globalen *
|
||||||
|
* Variablen. *
|
||||||
|
* Paging: *
|
||||||
|
* 0x200000: Page-Directory *
|
||||||
|
* 0x201000: Page-Table *
|
||||||
|
* 0x202000: erste allozierbare Page (via Paging.cc) *
|
||||||
|
* 0x3FF000: Anfang der letzten allozierbaren Page *
|
||||||
|
* Heap: *
|
||||||
|
* 0x400000: Start-Adresse der Heap-Verwaltung *
|
||||||
|
* Ende: Letzte Adresse des phys. Speichers *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
* Autor: Michael Schoettner, 20.12.2018 *
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "kernel/Paging.h"
|
||||||
|
#include "kernel/Globals.h"
|
||||||
|
|
||||||
|
// Bits fuer Eintraege in der Page-Table
|
||||||
|
#define PAGE_PRESENT 0x001
|
||||||
|
#define PAGE_WRITEABLE 0x002
|
||||||
|
#define PAGE_BIGSIZE 0x080
|
||||||
|
#define PAGE_RESERVED 0x800 // Bit 11 ist frei fuer das OS
|
||||||
|
|
||||||
|
// Adresse des Page-Directory (benoetigt 4 KB)
|
||||||
|
#define PAGE_DIRECTORY 0x200000
|
||||||
|
|
||||||
|
// Adresse der Page-Table (benoetigt 4 KB)
|
||||||
|
#define PAGE_TABLE 0x201000
|
||||||
|
|
||||||
|
// Start- und End-Adresse der 4 KB Seiten die durch die Page-Table adressiert werden
|
||||||
|
#define FST_ALLOCABLE_PAGE 0x202000
|
||||||
|
#define LST_ALLOCABLE_PAGE 0x2FF000
|
||||||
|
|
||||||
|
// Externe Funktionen in startup.asm
|
||||||
|
extern "C" {
|
||||||
|
void paging_on(unsigned int* p_pdir); // Paging einschalten
|
||||||
|
void invalidate_tlb_entry(unsigned int* ptr); // Page in TLB invalid.
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Funktion: pg_alloc_page *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Alloziert eine 4 KB Seite. Allozieren heisst hier *
|
||||||
|
* lediglich Setzen eines eigenen RESERVED-Bits. *
|
||||||
|
*****************************************************************************/
|
||||||
|
unsigned int* pg_alloc_page() {
|
||||||
|
unsigned int* p_page;
|
||||||
|
|
||||||
|
p_page = (unsigned int*)PAGE_TABLE;
|
||||||
|
|
||||||
|
// 1. Eintrag ist fuer Null-Pointer-Exception reserviert
|
||||||
|
// ausserdem liegt an die Page-Table an Adresse PAGE_TABLE
|
||||||
|
// somit ist est PAGE_TABLE + 4 KB frei (bis max. 3 MB, da beginnt der Heap)
|
||||||
|
for (int i = 1; i < 1024; i++) {
|
||||||
|
p_page++;
|
||||||
|
// pruefe ob Page frei
|
||||||
|
if (((*p_page) & PAGE_RESERVED) == 0) {
|
||||||
|
*p_page = (*p_page | PAGE_RESERVED);
|
||||||
|
return (unsigned int*)(i << 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Funktion: pg_write_protect_page *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Schreibschutz fuer die uebergebene Seite aktivieren. *
|
||||||
|
* Dies fuer das Debugging nuetzlich. *
|
||||||
|
*****************************************************************************/
|
||||||
|
void pg_write_protect_page(unsigned int* p_page) {
|
||||||
|
|
||||||
|
/* hier muss Code eingefügt werden */
|
||||||
|
|
||||||
|
unsigned int mask = PAGE_WRITEABLE; // fill to 32bit
|
||||||
|
*p_page = *p_page & ~mask; // set writable to 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Funktion: pg_notpresent_page *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Seite als ausgelagert markieren. Nur fuer Testzwecke. *
|
||||||
|
*****************************************************************************/
|
||||||
|
void pg_notpresent_page(unsigned int* p_page) {
|
||||||
|
|
||||||
|
/* hier muss Code eingefügt werden */
|
||||||
|
|
||||||
|
unsigned int mask = PAGE_PRESENT;
|
||||||
|
*p_page = *p_page & ~mask; // set present to 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Funktion: pg_free_page *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Gibt eine 4 KB Seite frei. Es wird hierbei das RESERVED- *
|
||||||
|
* Bit geloescht. *
|
||||||
|
*****************************************************************************/
|
||||||
|
void pg_free_page(unsigned int* p_page) {
|
||||||
|
int idx = (unsigned int)p_page >> 12;
|
||||||
|
|
||||||
|
// ausserhalb Page ?
|
||||||
|
if (idx < 1 || idx > 1023) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eintrag einlesen und aendern (PAGE_WRITEABLE loeschen)
|
||||||
|
p_page = (unsigned int*)PAGE_TABLE;
|
||||||
|
p_page += idx;
|
||||||
|
|
||||||
|
*p_page = ((idx << 12) | PAGE_WRITEABLE | PAGE_PRESENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Funktion: pg_init *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Page-Tables einrichten und Paging mithilfe von *
|
||||||
|
* startup.asm aktivieren. *
|
||||||
|
*****************************************************************************/
|
||||||
|
void pg_init() {
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int* p_pdir; // Zeiger auf Page-Directory
|
||||||
|
unsigned int* p_page; // Zeiger auf einzige Page-Table fuer 4 KB Pages
|
||||||
|
unsigned int num_pages; // Anzahl 4 MB Pages die phys. Adressraum umfassen
|
||||||
|
|
||||||
|
// wie viele 4 MB Seiten sollen als 'Present' angelegt werden,
|
||||||
|
// sodass genau der physikalische Adressraum abgedeckt ist?
|
||||||
|
num_pages = total_mem / (4096 * 1024);
|
||||||
|
|
||||||
|
kout << "pg_init: " << total_mem << endl;
|
||||||
|
|
||||||
|
kout << " total_mem: " << total_mem << endl;
|
||||||
|
kout << " #pages: " << total_mem / (4096 * 1024) << endl;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Aufbau des Page-Directory
|
||||||
|
//
|
||||||
|
|
||||||
|
// Eintrag 0: Zeiger auf 4 KB Page-Table
|
||||||
|
p_pdir = (unsigned int*)PAGE_DIRECTORY;
|
||||||
|
*p_pdir = PAGE_TABLE | PAGE_WRITEABLE | PAGE_PRESENT;
|
||||||
|
|
||||||
|
// Eintraege 1-1023: Direktes Mapping (1:1) auf 4 MB Pages (ohne Page-Table)
|
||||||
|
for (i = 1; i < 1024; i++) {
|
||||||
|
p_pdir++;
|
||||||
|
if (i > num_pages) {
|
||||||
|
*p_pdir = ((i << 22) | PAGE_BIGSIZE);
|
||||||
|
} else {
|
||||||
|
*p_pdir = ((i << 22) | PAGE_BIGSIZE | PAGE_WRITEABLE | PAGE_PRESENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Page-Table
|
||||||
|
//
|
||||||
|
p_page = (unsigned int*)PAGE_TABLE;
|
||||||
|
|
||||||
|
// ersten Eintrag loeschen -> not present, write protected -> Null-Pointer abfangen
|
||||||
|
*p_page = 0;
|
||||||
|
|
||||||
|
// Eintraege 1-1023: Direktes Mapping (1:1) auf 4 KB page frames
|
||||||
|
for (i = 1; i < 1024; i++) {
|
||||||
|
p_page++;
|
||||||
|
|
||||||
|
// Seiten unter FST_ALLOCABLE_PAGE reservieren, damit diese nicht
|
||||||
|
// alloziert werden und das System kaputt geht
|
||||||
|
if ((i << 12) >= FST_ALLOCABLE_PAGE) {
|
||||||
|
*p_page = ((i << 12) | PAGE_WRITEABLE | PAGE_PRESENT);
|
||||||
|
} else {
|
||||||
|
*p_page = ((i << 12) | PAGE_WRITEABLE | PAGE_PRESENT | PAGE_RESERVED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paging aktivieren (in startup.asm)
|
||||||
|
paging_on((unsigned int*)PAGE_DIRECTORY);
|
||||||
|
}
|
||||||
70
c_os/kernel/Paging.h
Normal file
70
c_os/kernel/Paging.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* *
|
||||||
|
* P A G I N G *
|
||||||
|
* *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Rudimentaeres Paging: 1:1 Mapping fuer gesamten logischen*
|
||||||
|
* Adressraum. logische Adresse = physikalische Adresse *
|
||||||
|
* *
|
||||||
|
* Page-Directory (alle Eintraege present, read/write *
|
||||||
|
* 0. Eintrag zeigt auf eine Page-Table (4 KB Eintraege)*
|
||||||
|
* Alle restl. Eintraege sind 4 MB Seiten und verweisen *
|
||||||
|
* somit auf keine Page-Tabelle sondern direkt auf die *
|
||||||
|
* 4 MB Seite. *
|
||||||
|
* *
|
||||||
|
* Page-Table (Logische Adressen 0 - 4 MB) *
|
||||||
|
* 1. Eintrag not present, read-only *
|
||||||
|
* -> Null-Pointer abfangen *
|
||||||
|
* 2. restl. Eintraege present & read/write *
|
||||||
|
* *
|
||||||
|
* Memory-Laylout *
|
||||||
|
* *
|
||||||
|
* boot.asm *
|
||||||
|
* 0x07c0: Bootsector vom BIOS geladen *
|
||||||
|
* 0x0060: Boot-Code verschiebt sich hier hin *
|
||||||
|
* 0x9000: Setup-Code (max. 64K inkl. Stack) vom *
|
||||||
|
* Bootsector-Code geladen *
|
||||||
|
* setup.asm *
|
||||||
|
* 0x1000: System-Code (max. 512K) geladen *
|
||||||
|
* BIOS-Aufruf *
|
||||||
|
* 0x24000: Parameter fuer BIOS-Aufurf *
|
||||||
|
* 0x25000: Altes ESP sichern, vor BIOS-Aufruf *
|
||||||
|
* 0x26000: 16-Bit Code-Segment fuer BIOS-Aufurf *
|
||||||
|
* System-Code *
|
||||||
|
* 0x100000: System-Code, kopiert nach Umschalten in *
|
||||||
|
* den Protected Mode kopiert (GRUB kann nur *
|
||||||
|
* an Adressen >1M laden) *
|
||||||
|
* Globale Variablen: Direkt nach dem Code liegen die globalen *
|
||||||
|
* Variablen. *
|
||||||
|
* Paging: *
|
||||||
|
* 0x200000: Page-Directory *
|
||||||
|
* 0x201000: Page-Table *
|
||||||
|
* 0x202000: erste allozierbare Page (via Paging.cc) *
|
||||||
|
* 0x3FF000: letzte allozierbare Page *
|
||||||
|
* Heap: *
|
||||||
|
* 0x400000: Start-Adresse der Heap-Verwaltung *
|
||||||
|
* Ende: Letzte Adresse des phys. Speichers *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
* Autor: Michael Schoettner, 2.2.2017 *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __Paging_include__
|
||||||
|
#define __Paging_include__
|
||||||
|
|
||||||
|
// ativiert paging
|
||||||
|
extern void pg_init();
|
||||||
|
|
||||||
|
// alloziert eine 4 KB Page
|
||||||
|
extern unsigned int* pg_alloc_page();
|
||||||
|
|
||||||
|
// Schreibschutz auf Seite setzen -> fuer debugging nuetzlich
|
||||||
|
extern void pg_write_protect_page(unsigned int* p_page);
|
||||||
|
|
||||||
|
// Present Bit loeschen
|
||||||
|
extern void pg_notpresent_page(unsigned int* p_page);
|
||||||
|
|
||||||
|
// gibt eine 4 KB Page frei
|
||||||
|
extern void pg_free_page(unsigned int* p_page);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -10,6 +10,7 @@ void TreeAllocator::init() {
|
|||||||
this->free_start->left = NULL;
|
this->free_start->left = NULL;
|
||||||
this->free_start->right = NULL;
|
this->free_start->right = NULL;
|
||||||
this->free_start->parent = NULL;
|
this->free_start->parent = NULL;
|
||||||
|
this->free_start->red = false; // The root is always black
|
||||||
this->free_start->next = (list_block_t*)this->free_start;
|
this->free_start->next = (list_block_t*)this->free_start;
|
||||||
this->free_start->previous = (list_block_t*)this->free_start;
|
this->free_start->previous = (list_block_t*)this->free_start;
|
||||||
|
|
||||||
@ -59,9 +60,6 @@ void* TreeAllocator::alloc(unsigned int req_size) {
|
|||||||
unsigned int size = this->get_size(best_fit);
|
unsigned int size = this->get_size(best_fit);
|
||||||
if constexpr (DEBUG) { kout << " - Found best-fit: " << hex << (unsigned int)best_fit << endl; }
|
if constexpr (DEBUG) { kout << " - Found best-fit: " << hex << (unsigned int)best_fit << endl; }
|
||||||
|
|
||||||
// Remove the block first so we can insert correctly when cutting
|
|
||||||
// kout << " - Removing block from freelist" << endl;
|
|
||||||
this->rbt_remove(best_fit);
|
|
||||||
if (size > HEAP_MIN_FREE_BLOCK_SIZE + rreq_size + sizeof(list_block_t)) {
|
if (size > HEAP_MIN_FREE_BLOCK_SIZE + rreq_size + sizeof(list_block_t)) {
|
||||||
// Block can be cut
|
// Block can be cut
|
||||||
if constexpr (DEBUG) { kout << " - Allocating " << dec << rreq_size << " Bytes with cutting" << endl; }
|
if constexpr (DEBUG) { kout << " - Allocating " << dec << rreq_size << " Bytes with cutting" << endl; }
|
||||||
@ -77,6 +75,11 @@ void* TreeAllocator::alloc(unsigned int req_size) {
|
|||||||
// need to remove it from the freelist, which is done for both cases
|
// need to remove it from the freelist, which is done for both cases
|
||||||
if constexpr (DEBUG) { kout << " - Allocating " << dec << rreq_size << " Bytes without cutting" << endl; }
|
if constexpr (DEBUG) { kout << " - Allocating " << dec << rreq_size << " Bytes without cutting" << endl; }
|
||||||
}
|
}
|
||||||
|
// Remove the old block from the freelist
|
||||||
|
// BUG: If the first allocation allocates the whole heap, this removal will crash the paging
|
||||||
|
// as the freelist will no longer contain any notes, gives NullPointerException as it's not handled
|
||||||
|
// kout << " - Removing block from freelist" << endl;
|
||||||
|
this->rbt_remove(best_fit);
|
||||||
|
|
||||||
if constexpr (DEBUG) { kout << " - Returned address " << hex << (unsigned int)((char*)best_fit + sizeof(list_block_t)) << endl; }
|
if constexpr (DEBUG) { kout << " - Returned address " << hex << (unsigned int)((char*)best_fit + sizeof(list_block_t)) << endl; }
|
||||||
return (void*)((char*)best_fit + sizeof(list_block_t));
|
return (void*)((char*)best_fit + sizeof(list_block_t));
|
||||||
|
|||||||
@ -45,7 +45,7 @@ private:
|
|||||||
|
|
||||||
void dump_free_memory(tree_block_t* node);
|
void dump_free_memory(tree_block_t* node);
|
||||||
|
|
||||||
// NOTE: Would be nice to have this stuff somewhere else for general use,
|
// NOTE: Would be nice to have this stuff somewhere else for general use (scheduling?)
|
||||||
// but that would require different rbt_node/dll_node structures.
|
// but that would require different rbt_node/dll_node structures.
|
||||||
// If I need this again later I should move it.
|
// If I need this again later I should move it.
|
||||||
void rbt_rot_l(tree_block_t* x);
|
void rbt_rot_l(tree_block_t* x);
|
||||||
|
|||||||
306
c_os/kernel/interrupts/Bluescreen.cc
Normal file
306
c_os/kernel/interrupts/Bluescreen.cc
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* *
|
||||||
|
* 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 "devices/CGA.h"
|
||||||
|
#include "kernel/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 = (unsigned short*)0xb8000;
|
||||||
|
|
||||||
|
for (x = 0; x < 80; x++) {
|
||||||
|
for (y = 0; y < 25; y++) {
|
||||||
|
*(ptr + y * 80 + x) = (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 = (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' + (unsigned char)c);
|
||||||
|
} else {
|
||||||
|
bs_print_char('A' + (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, 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 = (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) {
|
||||||
|
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 = (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 = (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");
|
||||||
|
}
|
||||||
19
c_os/kernel/interrupts/Bluescreen.h
Normal file
19
c_os/kernel/interrupts/Bluescreen.h
Normal 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
|
||||||
@ -13,6 +13,7 @@
|
|||||||
#include "kernel/interrupts/IntDispatcher.h"
|
#include "kernel/interrupts/IntDispatcher.h"
|
||||||
#include "kernel/CPU.h"
|
#include "kernel/CPU.h"
|
||||||
#include "kernel/Globals.h"
|
#include "kernel/Globals.h"
|
||||||
|
#include "kernel/interrupts/Bluescreen.h"
|
||||||
|
|
||||||
extern "C" void int_disp(unsigned int slot);
|
extern "C" void int_disp(unsigned int slot);
|
||||||
|
|
||||||
@ -31,9 +32,16 @@ extern "C" void int_disp(unsigned int slot);
|
|||||||
void int_disp(unsigned int vector) {
|
void int_disp(unsigned int vector) {
|
||||||
|
|
||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
|
if (vector < 32) {
|
||||||
|
bs_dump(vector);
|
||||||
|
cpu.halt();
|
||||||
|
}
|
||||||
|
|
||||||
// kout << "Ein Interrupt ist aufgetreten (vector: " << vector << ")" << endl;
|
if (intdis.report(vector) < 0) {
|
||||||
intdis.report(vector);
|
kout << "Panic: unexpected interrupt " << vector;
|
||||||
|
kout << " - processor halted." << endl;
|
||||||
|
cpu.halt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|||||||
0
c_os/kernel/threads/Dispatch.cc
Executable file → Normal file
0
c_os/kernel/threads/Dispatch.cc
Executable file → Normal file
0
c_os/kernel/threads/Dispatch.h
Executable file → Normal file
0
c_os/kernel/threads/Dispatch.h
Executable file → Normal file
0
c_os/kernel/threads/IdleThread.h
Executable file → Normal file
0
c_os/kernel/threads/IdleThread.h
Executable file → Normal file
10
c_os/kernel/threads/Scheduler.cc
Executable file → Normal file
10
c_os/kernel/threads/Scheduler.cc
Executable file → Normal file
@ -96,10 +96,12 @@ void Scheduler::yield() {
|
|||||||
|
|
||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
// if (this->readyQueue.isEmpty()) {
|
// When only one thread exists (IdleThread) it can't yield as the readyqueue becomes empty
|
||||||
// // Idle thread running
|
// and this is not handled anywhere else
|
||||||
// return;
|
if (this->readyQueue.isEmpty()) {
|
||||||
// }
|
// Idle thread running
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Thread& next = *(Thread*)this->readyQueue.dequeue();
|
Thread& next = *(Thread*)this->readyQueue.dequeue();
|
||||||
this->readyQueue.enqueue(this->get_active());
|
this->readyQueue.enqueue(this->get_active());
|
||||||
|
|||||||
0
c_os/kernel/threads/Scheduler.h
Executable file → Normal file
0
c_os/kernel/threads/Scheduler.h
Executable file → Normal file
0
c_os/kernel/threads/Thread.asm
Normal file → Executable file
0
c_os/kernel/threads/Thread.asm
Normal file → Executable file
0
c_os/kernel/threads/Thread.cc
Normal file → Executable file
0
c_os/kernel/threads/Thread.cc
Normal file → Executable file
0
c_os/kernel/threads/Thread.h
Executable file → Normal file
0
c_os/kernel/threads/Thread.h
Executable file → Normal file
0
c_os/kernel/threads/Thread.inc
Normal file → Executable file
0
c_os/kernel/threads/Thread.inc
Normal file → Executable file
0
c_os/kernel/threads/ThreadState.h
Normal file → Executable file
0
c_os/kernel/threads/ThreadState.h
Normal file → Executable file
0
c_os/lib/Queue.h
Executable file → Normal file
0
c_os/lib/Queue.h
Executable file → Normal file
37
c_os/main.cc
37
c_os/main.cc
@ -11,6 +11,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "kernel/Globals.h"
|
#include "kernel/Globals.h"
|
||||||
|
#include "kernel/Paging.h"
|
||||||
|
#include "kernel/threads/IdleThread.h"
|
||||||
#include "user/CoopThreadDemo.h"
|
#include "user/CoopThreadDemo.h"
|
||||||
#include "user/HelloWorldThread.h"
|
#include "user/HelloWorldThread.h"
|
||||||
#include "user/VBEdemo.h"
|
#include "user/VBEdemo.h"
|
||||||
@ -22,11 +24,11 @@ int main() {
|
|||||||
allocator.init();
|
allocator.init();
|
||||||
|
|
||||||
// Initialize scrollback buffer after allocator.init()
|
// Initialize scrollback buffer after allocator.init()
|
||||||
kout.init(5);
|
// kout.init(5);
|
||||||
|
|
||||||
// Startmeldung
|
// Startmeldung
|
||||||
if constexpr (!DEBUG) {
|
if constexpr (!DEBUG) {
|
||||||
kout << "HHUos 0.7\n"
|
kout << "HHUos 0.8\n"
|
||||||
<< "=========\n"
|
<< "=========\n"
|
||||||
<< "Unterstuetzte Funktionen:\n"
|
<< "Unterstuetzte Funktionen:\n"
|
||||||
<< " - Bildschirmausgaben\n"
|
<< " - Bildschirmausgaben\n"
|
||||||
@ -36,6 +38,7 @@ int main() {
|
|||||||
<< " - Tastatureingaben per Interrupt\n"
|
<< " - Tastatureingaben per Interrupt\n"
|
||||||
<< " - Kooperative Threads\n"
|
<< " - Kooperative Threads\n"
|
||||||
<< " - VESA Graphics Mode\n"
|
<< " - VESA Graphics Mode\n"
|
||||||
|
<< " - Paging\n"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,18 +50,27 @@ int main() {
|
|||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
cpu.enable_int();
|
cpu.enable_int();
|
||||||
|
|
||||||
// text_demo();
|
// Activate paging
|
||||||
// sound_demo();
|
// This has to happen after the allocator is initialized but before the scheduler is started
|
||||||
// keyboard_demo();
|
// TODO: Scheduler triggers bluescreen?
|
||||||
// heap_demo();
|
pg_init();
|
||||||
// key_irq_demo();
|
|
||||||
// coroutineDemo.main();
|
|
||||||
|
|
||||||
// Threads anlegen
|
// Trigger Bluescreen
|
||||||
|
// kout << "Trigger Bluescreen, if you can read this it didn't work" << endl;
|
||||||
|
|
||||||
|
// BlueScreen 1
|
||||||
|
// asm("int $3");
|
||||||
|
|
||||||
|
// BlueScreen 2
|
||||||
|
// unsigned int* page = pg_alloc_page();
|
||||||
|
// *page = 42; // Should work
|
||||||
|
// pg_write_protect_page(page);
|
||||||
|
// *page = 42; // should trigger BlueScreen
|
||||||
|
|
||||||
|
// Demo threads anlegen
|
||||||
// scheduler.ready(new HelloWorldThread());
|
// scheduler.ready(new HelloWorldThread());
|
||||||
// scheduler.ready(new CoopThreadDemo());
|
scheduler.ready(new CoopThreadDemo());
|
||||||
|
// scheduler.ready(new VBEdemo()); // Switch to VESA graphics mode
|
||||||
scheduler.ready(new VBEdemo());
|
|
||||||
|
|
||||||
// Scheduler starten (schedule() erzeugt den Idle-Thread)
|
// Scheduler starten (schedule() erzeugt den Idle-Thread)
|
||||||
scheduler.schedule();
|
scheduler.schedule();
|
||||||
@ -66,5 +78,6 @@ int main() {
|
|||||||
// TODO: Use templates for queue so threads don't have to be casted down from chain
|
// TODO: Use templates for queue so threads don't have to be casted down from chain
|
||||||
// TODO: Move scrollback control to thread
|
// TODO: Move scrollback control to thread
|
||||||
|
|
||||||
|
// Scheduler doesn't return
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
71
c_os/startup.asm
Executable file → Normal file
71
c_os/startup.asm
Executable file → Normal file
@ -9,7 +9,7 @@
|
|||||||
;* die weitere Ausfuehrung durch C-Code erfolgen kann. *
|
;* die weitere Ausfuehrung durch C-Code erfolgen kann. *
|
||||||
;* *
|
;* *
|
||||||
;* Autor: Olaf Spinczyk, TU Dortmund *
|
;* Autor: Olaf Spinczyk, TU Dortmund *
|
||||||
;* Michael Schoettner, HHU, 9.9.2016 *
|
;* Michael Schoettner, HHU, 15.12.2018 *
|
||||||
;******************************************************************************
|
;******************************************************************************
|
||||||
|
|
||||||
; Multiboot-Konstanten
|
; Multiboot-Konstanten
|
||||||
@ -31,6 +31,10 @@ MULTIBOOT_EAX_MAGIC equ 0x2badb002
|
|||||||
[GLOBAL idt]
|
[GLOBAL idt]
|
||||||
[GLOBAL __cxa_pure_virtual]
|
[GLOBAL __cxa_pure_virtual]
|
||||||
[GLOBAL bios_call]
|
[GLOBAL bios_call]
|
||||||
|
[GLOBAL invalidate_tlb_entry]
|
||||||
|
[GLOBAL paging_on]
|
||||||
|
[GLOBAL get_page_fault_address]
|
||||||
|
[GLOBAL get_int_esp]
|
||||||
|
|
||||||
; Michael Schoettner:
|
; Michael Schoettner:
|
||||||
; Nachfolgender label steht fuer das 'delete', welches jetzt implementiert
|
; Nachfolgender label steht fuer das 'delete', welches jetzt implementiert
|
||||||
@ -138,7 +142,9 @@ _fini_done:
|
|||||||
|
|
||||||
%macro wrapper 1
|
%macro wrapper 1
|
||||||
wrapper_%1:
|
wrapper_%1:
|
||||||
push eax
|
pushad ; alle Register sichern (fuer den Bluescreen)
|
||||||
|
mov ecx, int_esp ; Stack_zeiger sichern, fuer Zugriff im Bluescreen
|
||||||
|
mov [ecx], esp
|
||||||
mov al,%1
|
mov al,%1
|
||||||
jmp wrapper_body
|
jmp wrapper_body
|
||||||
%endmacro
|
%endmacro
|
||||||
@ -161,7 +167,7 @@ wrapper_body:
|
|||||||
add esp,4 ; Parameter vom Stack entfernen
|
add esp,4 ; Parameter vom Stack entfernen
|
||||||
pop edx ; fluechtige Register wieder herstellen
|
pop edx ; fluechtige Register wieder herstellen
|
||||||
pop ecx
|
pop ecx
|
||||||
pop eax
|
popad ; alle Register wiederherstellen
|
||||||
iret ; fertig!
|
iret ; fertig!
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -252,6 +258,46 @@ bios_call:
|
|||||||
lidt [idt_descr]
|
lidt [idt_descr]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; Paging aktivieren
|
||||||
|
; (siehe Paging.cc)
|
||||||
|
paging_on:
|
||||||
|
mov eax,[4+esp] ; Parameter Addr. Page-Dir. ins eax Register
|
||||||
|
mov ebx, cr4
|
||||||
|
or ebx, 0x10 ; 4 MB Pages aktivieren
|
||||||
|
mov cr4, ebx ; CR4 schreiben
|
||||||
|
mov cr3, eax ; Page-Directory laden
|
||||||
|
mov ebx, cr0
|
||||||
|
or ebx, 0x80010000 ; Paging aktivieren
|
||||||
|
mov cr0, ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Paging-Fault-Adresse holen
|
||||||
|
; (siehe Paging.cc)
|
||||||
|
get_page_fault_address:
|
||||||
|
mov eax,cr2
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Invalidiert eine Seite im TLB. Dies notwendig, falls eine
|
||||||
|
; die Bits Present, R/W in einem Seitentabelleneintrag
|
||||||
|
; geaendert werden. Falls die Seite im TLB gespeichert ist
|
||||||
|
; wuerde die MMU nichts von diesen Aenderungen erkennen,
|
||||||
|
; da die MMU dann nicht auf die Seitentabellen zugreift.
|
||||||
|
; (siehe Paging.cc)
|
||||||
|
invalidate_tlb_entry:
|
||||||
|
mov eax, [esp+4]
|
||||||
|
invlpg [eax]
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Auslesen von 'int_esp'
|
||||||
|
; wird im Bluescreen benoetigt, um den Stacks zuzugreifen
|
||||||
|
;
|
||||||
|
; C Prototyp: void get_int_esp (unsigned int** esp);
|
||||||
|
get_int_esp:
|
||||||
|
mov eax,[4+esp] ; esp
|
||||||
|
mov ecx, int_esp
|
||||||
|
mov [eax], ecx
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
[SECTION .data]
|
[SECTION .data]
|
||||||
|
|
||||||
@ -319,3 +365,22 @@ gdt_48:
|
|||||||
idt16_descr:
|
idt16_descr:
|
||||||
dw 1024 ; idt enthaelt max. 1024 Eintraege
|
dw 1024 ; idt enthaelt max. 1024 Eintraege
|
||||||
dd 0 ; Adresse 0
|
dd 0 ; Adresse 0
|
||||||
|
|
||||||
|
;
|
||||||
|
; Stack-Zeiger fuer Bluescreen
|
||||||
|
; (genauerer Stack-Aufbau siehe Bluescreen.cc)
|
||||||
|
;
|
||||||
|
; |-------------|
|
||||||
|
; | EFLAGS |
|
||||||
|
; |-------------|
|
||||||
|
; | CS |
|
||||||
|
; |-------------|
|
||||||
|
; | EIP |
|
||||||
|
; |-------------|
|
||||||
|
; | [ErrorCode] |
|
||||||
|
; |-------------|
|
||||||
|
; | alle Regs. |
|
||||||
|
; | (PUSHAD) |
|
||||||
|
; |-------------| <-- int_esp
|
||||||
|
int_esp:
|
||||||
|
db 0,0,0,0
|
||||||
|
|||||||
0
c_os/user/CoopThreadDemo.cc
Executable file → Normal file
0
c_os/user/CoopThreadDemo.cc
Executable file → Normal file
0
c_os/user/CoopThreadDemo.h
Executable file → Normal file
0
c_os/user/CoopThreadDemo.h
Executable file → Normal file
0
c_os/user/HelloWorldThread.cc
Executable file → Normal file
0
c_os/user/HelloWorldThread.cc
Executable file → Normal file
0
c_os/user/HelloWorldThread.h
Executable file → Normal file
0
c_os/user/HelloWorldThread.h
Executable file → Normal file
0
c_os/user/LoopThread.cc
Executable file → Normal file
0
c_os/user/LoopThread.cc
Executable file → Normal file
0
c_os/user/LoopThread.h
Executable file → Normal file
0
c_os/user/LoopThread.h
Executable file → Normal file
BIN
tools/build
BIN
tools/build
Binary file not shown.
Reference in New Issue
Block a user