1

add vorgabe07

This commit is contained in:
churl
2022-06-17 15:27:48 +02:00
parent 01495fda93
commit d29dc064cb
23 changed files with 19128 additions and 2 deletions

235
c_os/kernel/BIOS.cc Normal file
View File

@ -0,0 +1,235 @@
/*****************************************************************************
* *
* B I O S *
* *
*---------------------------------------------------------------------------*
* Beschreibung: BIOS-Schnittstelle *
* *
* Autor: Michael Schoettner, 29.11.2018 *
*****************************************************************************/
#include "kernel/Globals.h"
#include "kernel/BIOS.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!
#define BIOS16_CODE_MEMORY_START 0x24000
// Parameter fuer BIOS-Aufrufe (Register)
#define BIOS16_PARAM_BASE 0x26000
// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf (siehe BIOS.h)
struct BIOScall_params* BC_params = (struct 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 = (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; codeAddr++;
}
/*****************************************************************************
* Methode: BIOS::Int *
*---------------------------------------------------------------------------*
* Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. *
*****************************************************************************/
void BIOS::Int(int inter) {
unsigned char *ptr = (unsigned char*)BIOS16_CODE_MEMORY_START;
// Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...)
*(ptr+48) = (unsigned char)inter;
cpu.disable_int (); // Interrupts abschalten
bios_call ();
cpu.enable_int ();
}

54
c_os/kernel/BIOS.h Normal file
View File

@ -0,0 +1,54 @@
/*****************************************************************************
* *
* 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
#define 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 struct BIOScall_params* BC_params;
class BIOS {
private:
BIOS(const BIOS &copy); // Verhindere Kopieren
public:
// Initialisierung: manuelles Anlegen einer Funktion
BIOS();
// BIOS-Aufruf, per Software-Interrupt
void Int(int inter);
};
#endif

View File

@ -21,3 +21,5 @@ unsigned int total_mem; // RAM total
// LinkedListAllocator allocator;
TreeAllocator allocator;
Scheduler scheduler;
BIOS bios; // Schnittstelle zum 16-Bit BIOS
VESA vesa; // VESA-Treiber

View File

@ -13,9 +13,11 @@
#include "devices/CGA_Stream.h"
#include "devices/Keyboard.h"
#include "devices/PCSPK.h"
#include "devices/VESA.h"
#include "kernel/allocator/BumpAllocator.h"
#include "kernel/allocator/LinkedListAllocator.h"
#include "kernel/allocator/TreeAllocator.h"
#include "kernel/BIOS.h"
#include "kernel/CPU.h"
#include "kernel/interrupts/IntDispatcher.h"
#include "kernel/interrupts/PIC.h"
@ -32,6 +34,8 @@ extern unsigned int total_mem; // RAM total
// extern LinkedListAllocator allocator;
extern TreeAllocator allocator;
extern Scheduler scheduler;
extern BIOS bios; // Schnittstelle zum 16-Bit BIOS
extern VESA vesa; // VESA-Treiber
constexpr bool DEBUG = true;