1
This commit is contained in:
2022-07-16 01:01:58 +02:00
parent 35a5d7f9db
commit f41eda0215

View File

@ -8,24 +8,23 @@
* Autor: Michael Schoettner, 29.11.2018 * * Autor: Michael Schoettner, 29.11.2018 *
*****************************************************************************/ *****************************************************************************/
#include "kernel/Globals.h"
#include "kernel/BIOS.h" #include "kernel/BIOS.h"
#include "kernel/Globals.h"
// 16-Bit Code aufrufen, siehe Konstruktor und Aufruf in startup.asm // 16-Bit Code aufrufen, siehe Konstruktor und Aufruf in startup.asm
extern "C" { void bios_call(); } extern "C" {
void bios_call();
}
// in startup.asm im GDT-Eintrag so festgeschrieben! // in startup.asm im GDT-Eintrag so festgeschrieben!
#define BIOS16_CODE_MEMORY_START 0x24000 #define BIOS16_CODE_MEMORY_START 0x24000
// Parameter fuer BIOS-Aufrufe (Register) // Parameter fuer BIOS-Aufrufe (Register)
#define BIOS16_PARAM_BASE 0x26000 #define BIOS16_PARAM_BASE 0x26000
// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf (siehe BIOS.h) // Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf (siehe BIOS.h)
struct BIOScall_params* BC_params = (struct BIOScall_params*)BIOS16_PARAM_BASE; struct BIOScall_params* BC_params = (struct BIOScall_params*)BIOS16_PARAM_BASE;
/***************************************************************************** /*****************************************************************************
* Methode: BIOS::BIOS * * Methode: BIOS::BIOS *
*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*
@ -34,202 +33,293 @@ struct BIOScall_params* BC_params = (struct BIOScall_params*)BIOS16_PARAM_BASE;
* im 4. GDT-Eintrag (siehe startup.asm). * * im 4. GDT-Eintrag (siehe startup.asm). *
*****************************************************************************/ *****************************************************************************/
BIOS::BIOS() { BIOS::BIOS() {
unsigned char *codeAddr = (unsigned char*)BIOS16_CODE_MEMORY_START; unsigned char* codeAddr = (unsigned char*)BIOS16_CODE_MEMORY_START;
// mov eax, 25000 (Adresse wohin aktuelles esp gesichert wird) // mov eax, 25000 (Adresse wohin aktuelles esp gesichert wird)
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0xB8; codeAddr++; codeAddr++;
*codeAddr = 0x00; codeAddr++; *codeAddr = 0xB8;
*codeAddr = 0x50; codeAddr++; codeAddr++;
*codeAddr = 0x02; codeAddr++; *codeAddr = 0x00;
*codeAddr = 0x00; codeAddr++; codeAddr++;
*codeAddr = 0x50;
codeAddr++;
*codeAddr = 0x02;
codeAddr++;
*codeAddr = 0x00;
codeAddr++;
// mov [eax], esp (esp abspeichern) // mov [eax], esp (esp abspeichern)
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0x67; codeAddr++; codeAddr++;
*codeAddr = 0x89; codeAddr++; *codeAddr = 0x67;
*codeAddr = 0x20; codeAddr++; codeAddr++;
*codeAddr = 0x89;
codeAddr++;
*codeAddr = 0x20;
codeAddr++;
// mov eax,cr0 (cr0 auslesen) // mov eax,cr0 (cr0 auslesen)
*codeAddr = 0x0F; codeAddr++; *codeAddr = 0x0F;
*codeAddr = 0x20; codeAddr++; codeAddr++;
*codeAddr = 0xC0; codeAddr++; *codeAddr = 0x20;
codeAddr++;
*codeAddr = 0xC0;
codeAddr++;
// and eax, 7FFEFFFE (Bitmaske zum Abschlaten des Protected-Mode) // and eax, 7FFEFFFE (Bitmaske zum Abschlaten des Protected-Mode)
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0x25; codeAddr++; codeAddr++;
*codeAddr = 0xFE; codeAddr++; *codeAddr = 0x25;
*codeAddr = 0xFF; codeAddr++; codeAddr++;
*codeAddr = 0xFE; codeAddr++; *codeAddr = 0xFE;
*codeAddr = 0x7F; codeAddr++; codeAddr++;
*codeAddr = 0xFF;
codeAddr++;
*codeAddr = 0xFE;
codeAddr++;
*codeAddr = 0x7F;
codeAddr++;
// mov cr0, eax (cr0 syetzen um den Protected-Mode auszuschalten) // mov cr0, eax (cr0 syetzen um den Protected-Mode auszuschalten)
*codeAddr = 0x0F; codeAddr++; *codeAddr = 0x0F;
*codeAddr = 0x22; codeAddr++; codeAddr++;
*codeAddr = 0xC0; codeAddr++; *codeAddr = 0x22;
codeAddr++;
*codeAddr = 0xC0;
codeAddr++;
// jmp 2400:001B Instruktions-Pipeline leeren und Dekodierungseinheit auf 16-Bit code umschalten // jmp 2400:001B Instruktions-Pipeline leeren und Dekodierungseinheit auf 16-Bit code umschalten
// Wir springen hier zur naechsten Instruktion (*) // Wir springen hier zur naechsten Instruktion (*)
// 2400:001B (2400<<4 = 24000 + 1B) // 2400:001B (2400<<4 = 24000 + 1B)
*codeAddr = 0xEA; codeAddr++; *codeAddr = 0xEA;
*codeAddr = 0x1B; codeAddr++; codeAddr++;
*codeAddr = 0x00; codeAddr++; *codeAddr = 0x1B;
*codeAddr = 0x00; codeAddr++; codeAddr++;
*codeAddr = 0x24; codeAddr++; *codeAddr = 0x00;
codeAddr++;
*codeAddr = 0x00;
codeAddr++;
*codeAddr = 0x24;
codeAddr++;
// (*) mov dx,2400 (Lade 0x2400 nach dx (fuer Parameter-Zugriff -> BIOS16_PARAM_BAS) // (*) mov dx,2400 (Lade 0x2400 nach dx (fuer Parameter-Zugriff -> BIOS16_PARAM_BAS)
*codeAddr = 0xBA; codeAddr++; *codeAddr = 0xBA;
*codeAddr = 0x00; codeAddr++; codeAddr++;
*codeAddr = 0x24; codeAddr++; *codeAddr = 0x00;
codeAddr++;
*codeAddr = 0x24;
codeAddr++;
// mov ss,dx (Lade Stack-Segment-Register) // mov ss,dx (Lade Stack-Segment-Register)
*codeAddr = 0x8E; codeAddr++; *codeAddr = 0x8E;
*codeAddr = 0xD2; codeAddr++; codeAddr++;
*codeAddr = 0xD2;
codeAddr++;
// mov gs,dx // mov gs,dx
*codeAddr = 0x8E; codeAddr++; *codeAddr = 0x8E;
*codeAddr = 0xEA; codeAddr++; codeAddr++;
*codeAddr = 0xEA;
codeAddr++;
// mov esp,2000 -> BIOS16_PARAM_BASE 0x260000 (= 0x2400:2000) // mov esp,2000 -> BIOS16_PARAM_BASE 0x260000 (= 0x2400:2000)
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0xBC; codeAddr++; codeAddr++;
*codeAddr = 0x00; codeAddr++; *codeAddr = 0xBC;
*codeAddr = 0x20; codeAddr++; codeAddr++;
*codeAddr = 0x00; codeAddr++; *codeAddr = 0x00;
*codeAddr = 0x00; codeAddr++; codeAddr++;
*codeAddr = 0x20;
codeAddr++;
*codeAddr = 0x00;
codeAddr++;
*codeAddr = 0x00;
codeAddr++;
// Register laden (stehen in BIOS16_PARAM_BASE, ab 0x260000) // Register laden (stehen in BIOS16_PARAM_BASE, ab 0x260000)
// (pop erhöht die Adressen) // (pop erhöht die Adressen)
// pop ds // pop ds
*codeAddr = 0x1F; codeAddr++; *codeAddr = 0x1F;
codeAddr++;
// pop es // pop es
*codeAddr = 0x07; codeAddr++; *codeAddr = 0x07;
codeAddr++;
// pop fs // pop fs
*codeAddr = 0x0f; codeAddr++; *codeAddr = 0x0f;
*codeAddr = 0xa1; codeAddr++; codeAddr++;
*codeAddr = 0xa1;
codeAddr++;
// pop ax // pop ax
*codeAddr = 0x58; codeAddr++; *codeAddr = 0x58;
codeAddr++;
// popad // popad
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0x61; codeAddr++; codeAddr++;
*codeAddr = 0x61;
codeAddr++;
// int(nr) // int(nr)
*codeAddr = 0xCD; codeAddr++; // 'int' Instruktion *codeAddr = 0xCD;
*codeAddr = 0x00; codeAddr++; // Nummer (wird direkt von BIOS::Int direkt hier reingeschrieben) codeAddr++; // 'int' Instruktion
*codeAddr = 0x00;
codeAddr++; // Nummer (wird direkt von BIOS::Int direkt hier reingeschrieben)
// Register speichern in BIOS16_PARAM_BASE (ab 0x260000) // Register speichern in BIOS16_PARAM_BASE (ab 0x260000)
// pushad // pushad
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0x60; codeAddr++; codeAddr++;
*codeAddr = 0x60;
codeAddr++;
// pushf // pushf
*codeAddr = 0x9C; codeAddr++; *codeAddr = 0x9C;
codeAddr++;
// push fs // push fs
*codeAddr = 0x0f; codeAddr++; *codeAddr = 0x0f;
*codeAddr = 0xa0; codeAddr++; codeAddr++;
*codeAddr = 0xa0;
codeAddr++;
// push es // push es
*codeAddr = 0x06; codeAddr++; *codeAddr = 0x06;
codeAddr++;
// push ds // push ds
*codeAddr = 0x1E; codeAddr++; *codeAddr = 0x1E;
codeAddr++;
// mov eax,cr0 // mov eax,cr0
*codeAddr = 0x0F; codeAddr++; *codeAddr = 0x0F;
*codeAddr = 0x20; codeAddr++; codeAddr++;
*codeAddr = 0xC0; codeAddr++; *codeAddr = 0x20;
codeAddr++;
*codeAddr = 0xC0;
codeAddr++;
// or eax, 00010001 (protected mode without paging) // or eax, 00010001 (protected mode without paging)
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0x0D; codeAddr++; codeAddr++;
*codeAddr = 0x01; codeAddr++; *codeAddr = 0x0D;
*codeAddr = 0x00; codeAddr++; codeAddr++;
*codeAddr = 0x01; codeAddr++; *codeAddr = 0x01;
*codeAddr = 0x00; codeAddr++; codeAddr++;
*codeAddr = 0x00;
codeAddr++;
*codeAddr = 0x01;
codeAddr++;
*codeAddr = 0x00;
codeAddr++;
// mov cr0, eax // mov cr0, eax
*codeAddr = 0x0F; codeAddr++; *codeAddr = 0x0F;
*codeAddr = 0x22; codeAddr++; codeAddr++;
*codeAddr = 0xC0; codeAddr++; *codeAddr = 0x22;
codeAddr++;
*codeAddr = 0xC0;
codeAddr++;
// jmp 0018:0049, flush pipeline & switch decoding (active 32 Bit PM) // jmp 0018:0049, flush pipeline & switch decoding (active 32 Bit PM)
// 0018:0049 // 0018:0049
*codeAddr = 0xEA; codeAddr++; *codeAddr = 0xEA;
*codeAddr = 0x49; codeAddr++; codeAddr++;
*codeAddr = 0x00; codeAddr++; *codeAddr = 0x49;
*codeAddr = 0x18; codeAddr++; codeAddr++;
*codeAddr = 0x00; codeAddr++; *codeAddr = 0x00;
codeAddr++;
*codeAddr = 0x18;
codeAddr++;
*codeAddr = 0x00;
codeAddr++;
// mov dx,0010 // mov dx,0010
*codeAddr = 0xBA; codeAddr++; *codeAddr = 0xBA;
*codeAddr = 0x10; codeAddr++; codeAddr++;
*codeAddr = 0x00; codeAddr++; *codeAddr = 0x10;
codeAddr++;
*codeAddr = 0x00;
codeAddr++;
// mov ds,dx // mov ds,dx
*codeAddr = 0x8E; codeAddr++; *codeAddr = 0x8E;
*codeAddr = 0xDA; codeAddr++; codeAddr++;
*codeAddr = 0xDA;
codeAddr++;
// mov es,dx // mov es,dx
*codeAddr = 0x8E; codeAddr++; *codeAddr = 0x8E;
*codeAddr = 0xC2; codeAddr++; codeAddr++;
*codeAddr = 0xC2;
codeAddr++;
// mov es,dx // mov es,dx
*codeAddr = 0x8E; codeAddr++; *codeAddr = 0x8E;
*codeAddr = 0xE2; codeAddr++; codeAddr++;
*codeAddr = 0xE2;
codeAddr++;
// mov fs,dx // mov fs,dx
*codeAddr = 0x8E; codeAddr++; *codeAddr = 0x8E;
*codeAddr = 0xEA; codeAddr++; codeAddr++;
*codeAddr = 0xEA;
codeAddr++;
// mov ss,dx // mov ss,dx
*codeAddr = 0x8E; codeAddr++; *codeAddr = 0x8E;
*codeAddr = 0xD2; codeAddr++; codeAddr++;
*codeAddr = 0xD2;
codeAddr++;
// mov eax, 25000 // mov eax, 25000
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0xB8; codeAddr++; codeAddr++;
*codeAddr = 0x00; codeAddr++; *codeAddr = 0xB8;
*codeAddr = 0x50; codeAddr++; codeAddr++;
*codeAddr = 0x02; codeAddr++; *codeAddr = 0x00;
*codeAddr = 0x00; codeAddr++; codeAddr++;
*codeAddr = 0x50;
codeAddr++;
*codeAddr = 0x02;
codeAddr++;
*codeAddr = 0x00;
codeAddr++;
// mov esp, [eax] // mov esp, [eax]
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0x67; codeAddr++; codeAddr++;
*codeAddr = 0x8B; codeAddr++; *codeAddr = 0x67;
*codeAddr = 0x20; codeAddr++; codeAddr++;
*codeAddr = 0x8B;
codeAddr++;
*codeAddr = 0x20;
codeAddr++;
// far ret // far ret
*codeAddr = 0x66; codeAddr++; *codeAddr = 0x66;
*codeAddr = 0xCB; codeAddr++; codeAddr++;
*codeAddr = 0xCB;
codeAddr++;
} }
/***************************************************************************** /*****************************************************************************
* Methode: BIOS::Int * * Methode: BIOS::Int *
*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*
* Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. * * Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. *
*****************************************************************************/ *****************************************************************************/
void BIOS::Int(int inter) { void BIOS::Int(int inter) {
unsigned char *ptr = (unsigned char*)BIOS16_CODE_MEMORY_START; unsigned char* ptr = (unsigned char*)BIOS16_CODE_MEMORY_START;
// Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...) // Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...)
*(ptr+48) = (unsigned char)inter; *(ptr + 48) = (unsigned char)inter;
cpu.disable_int (); // Interrupts abschalten cpu.disable_int(); // Interrupts abschalten
bios_call();
bios_call (); cpu.enable_int();
cpu.enable_int ();
} }