Setup cmake project
This commit is contained in:
324
src/device/bios/BIOS.cc
Normal file
324
src/device/bios/BIOS.cc
Normal file
@ -0,0 +1,324 @@
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* B I O S *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: BIOS-Schnittstelle *
|
||||
* *
|
||||
* Autor: Michael Schoettner, 29.11.2018 *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "BIOS.h"
|
||||
#include "kernel/system/Globals.h"
|
||||
|
||||
// 16-Bit Code aufrufen, siehe Konstruktor und Aufruf in startup.asm
|
||||
extern "C" {
|
||||
void bios_call();
|
||||
}
|
||||
|
||||
// in startup.asm im GDT-Eintrag so festgeschrieben!
|
||||
constexpr const unsigned int BIOS16_CODE_MEMORY_START = 0x24000;
|
||||
|
||||
// Parameter fuer BIOS-Aufrufe (Register)
|
||||
constexpr const unsigned int BIOS16_PARAM_BASE = 0x26000;
|
||||
|
||||
// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf (siehe BIOS.h)
|
||||
BIOScall_params* BC_params = reinterpret_cast<BIOScall_params*>(BIOS16_PARAM_BASE);
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: BIOS::BIOS *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Konstruktor. Baut manuell ein 16-Bit Code Segment fuer *
|
||||
* den BIOS-Aufruf. Startadresse dieser Funktion steht *
|
||||
* im 4. GDT-Eintrag (siehe startup.asm). *
|
||||
*****************************************************************************/
|
||||
BIOS::BIOS() {
|
||||
unsigned char* codeAddr = reinterpret_cast<unsigned char*>(BIOS16_CODE_MEMORY_START);
|
||||
|
||||
// mov eax, 25000 (Adresse wohin aktuelles esp gesichert wird)
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xB8;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x50;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x02;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
|
||||
// mov [eax], esp (esp abspeichern)
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x67;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x89;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x20;
|
||||
codeAddr++;
|
||||
|
||||
// mov eax,cr0 (cr0 auslesen)
|
||||
*codeAddr = 0x0F;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x20;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xC0;
|
||||
codeAddr++;
|
||||
|
||||
// and eax, 7FFEFFFE (Bitmaske zum Abschlaten des Protected-Mode)
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x25;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xFE;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xFF;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xFE;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x7F;
|
||||
codeAddr++;
|
||||
|
||||
// mov cr0, eax (cr0 syetzen um den Protected-Mode auszuschalten)
|
||||
*codeAddr = 0x0F;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x22;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xC0;
|
||||
codeAddr++;
|
||||
|
||||
// jmp 2400:001B Instruktions-Pipeline leeren und Dekodierungseinheit auf 16-Bit code umschalten
|
||||
// Wir springen hier zur naechsten Instruktion (*)
|
||||
// 2400:001B (2400<<4 = 24000 + 1B)
|
||||
*codeAddr = 0xEA;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x1B;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x24;
|
||||
codeAddr++;
|
||||
|
||||
// (*) mov dx,2400 (Lade 0x2400 nach dx (fuer Parameter-Zugriff -> BIOS16_PARAM_BAS)
|
||||
*codeAddr = 0xBA;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x24;
|
||||
codeAddr++;
|
||||
|
||||
// mov ss,dx (Lade Stack-Segment-Register)
|
||||
*codeAddr = 0x8E;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xD2;
|
||||
codeAddr++;
|
||||
|
||||
// mov gs,dx
|
||||
*codeAddr = 0x8E;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xEA;
|
||||
codeAddr++;
|
||||
|
||||
// mov esp,2000 -> BIOS16_PARAM_BASE 0x260000 (= 0x2400:2000)
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xBC;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x20;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
|
||||
// Register laden (stehen in BIOS16_PARAM_BASE, ab 0x260000)
|
||||
// (pop erhöht die Adressen)
|
||||
|
||||
// pop ds
|
||||
*codeAddr = 0x1F;
|
||||
codeAddr++;
|
||||
|
||||
// pop es
|
||||
*codeAddr = 0x07;
|
||||
codeAddr++;
|
||||
|
||||
// pop fs
|
||||
*codeAddr = 0x0f;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xa1;
|
||||
codeAddr++;
|
||||
|
||||
// pop ax
|
||||
*codeAddr = 0x58;
|
||||
codeAddr++;
|
||||
|
||||
// popad
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x61;
|
||||
codeAddr++;
|
||||
|
||||
// int(nr)
|
||||
*codeAddr = 0xCD;
|
||||
codeAddr++; // 'int' Instruktion
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++; // Nummer (wird direkt von BIOS::Int direkt hier reingeschrieben)
|
||||
|
||||
// Register speichern in BIOS16_PARAM_BASE (ab 0x260000)
|
||||
|
||||
// pushad
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x60;
|
||||
codeAddr++;
|
||||
|
||||
// pushf
|
||||
*codeAddr = 0x9C;
|
||||
codeAddr++;
|
||||
|
||||
// push fs
|
||||
*codeAddr = 0x0f;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xa0;
|
||||
codeAddr++;
|
||||
|
||||
// push es
|
||||
*codeAddr = 0x06;
|
||||
codeAddr++;
|
||||
|
||||
// push ds
|
||||
*codeAddr = 0x1E;
|
||||
codeAddr++;
|
||||
|
||||
// mov eax,cr0
|
||||
*codeAddr = 0x0F;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x20;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xC0;
|
||||
codeAddr++;
|
||||
|
||||
// or eax, 00010001 (protected mode without paging)
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x0D;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x01;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x01;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
|
||||
// mov cr0, eax
|
||||
*codeAddr = 0x0F;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x22;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xC0;
|
||||
codeAddr++;
|
||||
|
||||
// jmp 0018:0049, flush pipeline & switch decoding (active 32 Bit PM)
|
||||
// 0018:0049
|
||||
*codeAddr = 0xEA;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x49;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x18;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
|
||||
// mov dx,0010
|
||||
*codeAddr = 0xBA;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x10;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
|
||||
// mov ds,dx
|
||||
*codeAddr = 0x8E;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xDA;
|
||||
codeAddr++;
|
||||
|
||||
// mov es,dx
|
||||
*codeAddr = 0x8E;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xC2;
|
||||
codeAddr++;
|
||||
|
||||
// mov es,dx
|
||||
*codeAddr = 0x8E;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xE2;
|
||||
codeAddr++;
|
||||
|
||||
// mov fs,dx
|
||||
*codeAddr = 0x8E;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xEA;
|
||||
codeAddr++;
|
||||
|
||||
// mov ss,dx
|
||||
*codeAddr = 0x8E;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xD2;
|
||||
codeAddr++;
|
||||
|
||||
// mov eax, 25000
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xB8;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x50;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x02;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x00;
|
||||
codeAddr++;
|
||||
|
||||
// mov esp, [eax]
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x67;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x8B;
|
||||
codeAddr++;
|
||||
*codeAddr = 0x20;
|
||||
codeAddr++;
|
||||
|
||||
// far ret
|
||||
*codeAddr = 0x66;
|
||||
codeAddr++;
|
||||
*codeAddr = 0xCB;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: BIOS::Int *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. *
|
||||
*****************************************************************************/
|
||||
void BIOS::Int(int inter) {
|
||||
unsigned char* ptr = reinterpret_cast<unsigned char*>(BIOS16_CODE_MEMORY_START);
|
||||
|
||||
// Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...)
|
||||
*(ptr + 48) = static_cast<unsigned char>(inter);
|
||||
|
||||
CPU::disable_int(); // Interrupts abschalten
|
||||
bios_call();
|
||||
CPU::enable_int();
|
||||
}
|
||||
53
src/device/bios/BIOS.h
Normal file
53
src/device/bios/BIOS.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* B I O S *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Zugriff auf das 16-Bit BIOS. Fuer VESA-Funktionen. *
|
||||
* *
|
||||
* Autor: Michael Schoettner, 13.9.2016 *
|
||||
*****************************************************************************/
|
||||
#ifndef BIOS_include__
|
||||
#define BIOS_include__
|
||||
|
||||
// Speicherseite fuer Rueckgabewerte von BIOS-Aufrufen
|
||||
constexpr const unsigned int RETURN_MEM = 0x9F000;
|
||||
|
||||
// Struktur fuer Parameteruebergabe fuer einen BIOS-Aufruf
|
||||
struct BIOScall_params {
|
||||
unsigned short DS;
|
||||
unsigned short ES;
|
||||
unsigned short FS;
|
||||
unsigned short Flags;
|
||||
unsigned int DI;
|
||||
unsigned int SI;
|
||||
unsigned int BP;
|
||||
unsigned int SP;
|
||||
unsigned int BX;
|
||||
unsigned int DX;
|
||||
unsigned int CX;
|
||||
unsigned int AX;
|
||||
} __attribute__((packed));
|
||||
// kein Auffuellen von bytes auf Wortgrenzen
|
||||
|
||||
// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf
|
||||
extern BIOScall_params* BC_params;
|
||||
|
||||
class BIOS {
|
||||
private:
|
||||
// Initialisierung: manuelles Anlegen einer Funktion
|
||||
BIOS();
|
||||
|
||||
public:
|
||||
BIOS(const BIOS& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
static BIOS& instance() {
|
||||
static BIOS bios;
|
||||
return bios;
|
||||
}
|
||||
|
||||
// BIOS-Aufruf, per Software-Interrupt
|
||||
static void Int(int inter);
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user