1

move folder

This commit is contained in:
churl
2022-04-16 14:50:17 +02:00
parent 87e482bc7c
commit 4ec2beeda2
25 changed files with 319 additions and 0 deletions

254
c_os/Makefile Executable file
View File

@ -0,0 +1,254 @@
# -----------------------------------------------------------------------------
#
# M A K E F I L E
#
# zum HHUos der Lehrveranstaltung 'Betriebssystem-Entwicklung'.
# -----------------------------------------------------------------------------
#
# Compilieren: make'
# Ausfuehren mit Qemu: make qemu
# GDB mit Qemu: make qemu-gdb & und danach make gdb
# DDD mit Qemu: make qemu-gdb & und danach make ddd
#
# Aufraeumen mit: make clean
#
# Achtung: Erzeugen von bootfaehigen Medien erfordert das Anpassen folgender
# Variablen: DRIVE_FD und DRIVE_HD. Aufpassen, ansonsten wir evt.
# die System-Disk zerstoert.
#
# Erzeugen einer bootfaehigen Diskette mit: make bootdisk
# Erzeugen eines bootfaehigen USB-Sticks mit: make bootdisk-usb
# Erzeugen eines bootfaehigen Festplatte mit: make bootdisk-hd
#
# -----------------------------------------------------------------------------
# Autor: Olaf Spinzcyk, TU Dortmund
#
# -----------------------------------------------------------------------------
# Liste der Quelltexte:
STARTUP_SOURCE = ./startup.asm
CC_SOURCES = $(shell find . -name "*.cc")
C_SOURCES = $(shell find . -name "*.c")
ASM_SOURCES = $(shell find ./kernel -name "*.asm")
# Einstellungen in Abhaengigkeit vom Generierungssystem:
#
# ASMOBJFORMAT: Ausgabeformat fuer den Assembler. Das Format muss dem
# jeweiligen Format des verwendeten C++ Compilers angepasst
# werde, damit gemischte Objektdateien gelinkt werden koennen.
# OBJDIR: Verzeichnis, in dem die Objektdateien abgelegt werden
# sollen.
# DEPDIR: Verzeichnis, in dem die Abhaengigkeitsdateien abgelegt werden
# sollen
# DRIVE_FD: Diskettenlaufwerk, auf das das System-Image geschrieben wird
# (Target: bootdisk)
# DRIVE_HD: Festplatten-/USB-Device, auf das das System-Image
# geschrieben wird (Target: bootdisk-hd)
# DELETE: Name des Kommandos zum Loeschen von Dateien
# ASM: Zu benutzender Assembler
# CC/CXX: Zu benutzender C/C++-Compiler
# CFLAGS: Flags fuer den C-Compileraufruf
# CXXFLAGS: Flags fuer den C++-Compileraufruf
# LD: Zu benutzender Linker
# LDFLAGS: Flags fuer den Linkeraufruf
# LDLIBS: Dazuzulinkende Bibliotheken
# LDHEAD: Am Anfang zu linkende Dateien
# LDTAIL: Am Ende zu linkende Dateien
# BOOT: Das Verzeichnis zu Bootsektor und Setup-Code
# TOOLS: Das Verzeichnis mit dem Build-Tool
VERBOSE = @
ASMOBJFORMAT = elf
OBJDIR = ./build
DEPDIR = ./dep
DRIVE_FD = /dev/sdb
# ACHTUNG: ein falsch angegebenes Laufwerk kann dazu fuehren, dass Daten auf dem
# spezifizierten Laufwerk verloren gehen! Nicht mit root-Rechten ausfuehren!
DRIVE_HD = /dev/sdb
DELETE = rm
ASM = nasm
CC ?= gcc
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
BOOT = ../c_boot
TOOLS = ../c_tools
# BIOS-dev.code:total-tracks:-heads:-sectors:start-track:-head:-sector
# Default-Werte fuer Boot von Floppy (USB/HD erkennt bootsect.asm selbst):
BOOTDEVICE = 0:80:2:18:0:0:1
# -------------------------------------------------------------------------
# Namen der Unterverzeichnisse mit den Quelltexten
VPATH = $(sort $(dir $(STARTUP_SOURCE) $(CC_SOURCES) $(C_SOURCES) $(ASM_SOURCES)))
# -------------------------------------------------------------------------
# Listen mit den Objektdateien, die beim Kompilieren entstehen:
FIRST_OBJECT = $(addprefix $(OBJDIR)/,$(patsubst %.asm,_%.o, $(notdir $(STARTUP_SOURCE))))
C_OBJECTS = $(notdir $(C_SOURCES:.c=.o))
CC_OBJECTS = $(notdir $(CC_SOURCES:.cc=.o))
DEP_FILES = $(patsubst %.o,$(DEPDIR)/%.d,$(C_OBJECTS))
DEP_FILES += $(patsubst %.o,$(DEPDIR)/%.d,$(CC_OBJECTS))
ASM_OBJECTS = $(patsubst %.asm,_%.o, $(notdir $(ASM_SOURCES)))
OBJPRE = $(addprefix $(OBJDIR)/,$(ASM_OBJECTS) $(C_OBJECTS) $(CC_OBJECTS))
# --------------------------------------------------------------------------
# Default targets (einfaches Image, Image fuer USB Sticks, Image fuer VMWare
# und Boot CDs)
all: $(OBJDIR)/bootdisk.img $(OBJDIR)/bootdisk.vmi $(OBJDIR)/bootdisk-hd.vmi
# --------------------------------------------------------------------------
# Regeln zur Erzeugung der Abhaengigkeitsdateien
$(DEPDIR)/%.d : %.c
@echo "DEP $@"
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(VERBOSE) $(CC) $(CFLAGS) -MM -MT $(OBJDIR)/$*.o -MF $@ $<
$(DEPDIR)/%.d : %.cc
@echo "DEP $@"
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(VERBOSE) $(CXX) $(CXXFLAGS) -MM -MT $(OBJDIR)/$*.o -MF $@ $<
# --------------------------------------------------------------------------
# Regeln zur Erzeugung der Objektdateien
$(OBJDIR)/%.o : %.c
@echo "CC $@"
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(VERBOSE) $(CC) -c $(CFLAGS) -o $@ $<
$(OBJDIR)/%.o : %.cc
@echo "CXX $@"
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(VERBOSE) $(CXX) -c $(CXXFLAGS) -o $@ $<
$(OBJDIR)/_%.o : %.asm
@echo "ASM $@"
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(VERBOSE) $(ASM) -f $(ASMOBJFORMAT) -o $@ $<
# --------------------------------------------------------------------------
# Gelinktes System
$(OBJDIR)/system: $(FIRST_OBJECT) $(OBJPRE)
@echo "LD $@"
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(VERBOSE) $(CXX) $(CXXFLAGS) -static -e startup -T sections -o $(OBJDIR)/system $(FIRST_OBJECT) $(OBJPRE)
# --------------------------------------------------------------------------
# 'system.img' enthaelt die zu ladenden Sections des eigentlichen Systems
$(OBJDIR)/system.img : $(OBJDIR)/system
@echo "OBJCOPY $@"
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(VERBOSE) objcopy -O binary $< $@
# --------------------------------------------------------------------------
# 'bootdisk.img' besteht aus dem 'system.img', das um den (parametrisierten)
# Bootblock und den Setup-Code erweitert wurde.
$(OBJDIR)/bootdisk.img : $(OBJDIR)/system.img $(TOOLS)/build $(BOOT)/bootsect $(BOOT)/setup
@echo "BUILD $@"
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(VERBOSE) $(TOOLS)/build $(BOOT)/bootsect $(BOOT)/setup $< $(BOOTDEVICE) $@
# 'bootdisk.vmi' ist eine bootdisk, die auf 1.44 MB mit 0 aufgefuellt ist,
# damit VMware damit klarkommt. Des weiteren wird dieses Image benoetigt, um
# bootfaehige CDs zu erstellen.
# bootdisk-hd.img wird auf etwa 1M mit 0 aufgefuellt, da qemu diese Groesse
# auf eine Festplatten-Laufwerkscharakteristik zurueckrechnen kann.
$(OBJDIR)/bootdisk.vmi: $(OBJDIR)/bootdisk.img
dd if=$< of=$@ bs=1474560 conv=sync
$(OBJDIR)/bootdisk-hd.vmi: $(OBJDIR)/bootdisk.img
dd if=$< of=$@ bs=$$((2016*512)) conv=sync
# --------------------------------------------------------------------------
# 'clean' loescht das generierte System, die Objektdateien und die
# Abhaengigkeitsdateien
clean:
@echo "RM $(OBJDIR)"
$(VERBOSE) rm -rf $(OBJDIR)
@echo "RM $(DEPDIR)"
$(VERBOSE) rm -rf $(DEPDIR)
$(MAKE) -C $(BOOT) clean
# --------------------------------------------------------------------------
# 'bootdisk' erzeugt zunaechst das System, falls das noch nicht geschehen ist.
# Danach wird eine Bootdiskette mit dem System erzeugt.
bootdisk: $(OBJDIR)/bootdisk.img
@echo "CP $<"
$(VERBOSE) cp $< $(DRIVE_FD)
# --------------------------------------------------------------------------
# 'bootdisk-hd' erzeugt zunaechst das System, falls das noch nicht geschehen
# ist. Danach wird das System auf das spezifizierte Laufwerk geschrieben,
# welches sowohl eine Festplatte, als auch ein USB-Stick sein kann.
# ACHTUNG: ein falsch angegebenes Laufwerk kann dazu fuehren, dass Daten auf dem
# spezifizierten Laufwerk verloren gehen! Nicht mit root-Rechten ausfuehren!
bootdisk-usb: bootdisk-hd
bootdisk-hd: $(OBJDIR)/bootdisk.img
@echo "CP $<"
$(VERBOSE) cp $< $(DRIVE_HD)
# --------------------------------------------------------------------------
# 'qemu' ruft den qemu-Emulator mit dem System auf.
qemu: $(OBJDIR)/bootdisk.vmi
qemu-system-i386 -fda $(OBJDIR)/bootdisk.vmi -boot a -k en-us -soundhw pcspk -vga std -cpu 486
# --------------------------------------------------------------------------
# 'qemu-gdb' ruft den qemu-Emulator mit aktiviertem GDB-Stub mit dem System
# auf, sodass es per GDB oder DDD inspiziert werden kann.
qemu-gdb: $(OBJDIR)/bootdisk.vmi
$(VERBOSE) echo "break main" > /tmp/gdbcommands.$(shell id -u)
$(VERBOSE) echo "target remote 127.0.0.1:1234" >> /tmp/gdbcommands.$(shell id -u)
$(VERBOSE) echo "continue" >> /tmp/gdbcommands.$(shell id -u)
qemu-system-i386 -fda $(OBJDIR)/bootdisk.vmi -boot a -k en-us -s -S -soundhw pcspk -vga std -cpu 486
# --------------------------------------------------------------------------
# 'gdb' startet den GDB-Debugger und verbindet sich mit dem GDB-Stub des vorher
# gestarteten Qemu.
gdb:
gdb -x /tmp/gdbcommands.$(shell id -u) $(OBJDIR)/system
# --------------------------------------------------------------------------
# 'ddd' startet den DDD-Debugger und verbindet sich mit dem GDB-Stub des vorher
# gestarteten Qemu.
ddd:
ddd --gdb -x /tmp/gdbcommands.$(shell id -u) $(OBJDIR)/system
# --------------------------------------------------------------------------
# 'build'-Tool kompilieren.
$(TOOLS)/build: $(TOOLS)/build.c
cd $(TOOLS) && $(CC) -o $@ $<
# --------------------------------------------------------------------------
# Bootsektor und Protected-Mode-Setup-Code kompilieren.
$(BOOT)/bootsect $(BOOT)/setup: $(BOOT)/bootsect.asm $(BOOT)/setup.asm
$(MAKE) -C $(BOOT)
# --------------------------------------------------------------------------
# Einbindung der Abhaengigkeitsdateien
ifneq ($(MAKECMDGOALS),clean)
-include $(DEP_FILES)
endif
.PHONY: clean bootdisk bootdisk-hd bootdisk-usb gdb ddd

7
c_os/README Executable file
View File

@ -0,0 +1,7 @@
Implementierungen in folgenden Dateien
======================================
main.cc
devices/CGA.h
devices/CGA.cc
devices/PCSPK.cc

312
c_os/compile_commands.json Normal file
View File

@ -0,0 +1,312 @@
[
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/SoundDemo.o",
"./user/SoundDemo.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/user/SoundDemo.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/SoundDemo.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/TextDemo.o",
"./user/TextDemo.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/user/TextDemo.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/TextDemo.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/Globals.o",
"./kernel/Globals.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/kernel/Globals.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/Globals.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/IntDispatcher.o",
"./kernel/interrupts/IntDispatcher.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/kernel/interrupts/IntDispatcher.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/IntDispatcher.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/main.o",
"main.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/main.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/main.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/OutStream.o",
"./lib/OutStream.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/lib/OutStream.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/OutStream.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/StringBuffer.o",
"./lib/StringBuffer.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/lib/StringBuffer.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/StringBuffer.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/CGA_Stream.o",
"./devices/CGA_Stream.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/devices/CGA_Stream.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/CGA_Stream.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/CGA.o",
"./devices/CGA.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/devices/CGA.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/CGA.o"
},
{
"arguments": [
"/usr/bin/g++",
"-c",
"-m32",
"-march=i486",
"-Wall",
"-fno-stack-protector",
"-I.",
"-g",
"-ffreestanding",
"-fno-pie",
"-fno-pic",
"-mpreferred-stack-boundary=2",
"-Wno-write-strings",
"-mno-sse",
"-mno-sse2",
"-mmanual-endbr",
"-Wno-non-virtual-dtor",
"-fno-threadsafe-statics",
"-fno-use-cxa-atexit",
"-fno-rtti",
"-fno-exceptions",
"-o",
"build/PCSPK.o",
"./devices/PCSPK.cc"
],
"directory": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01",
"file": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/devices/PCSPK.cc",
"output": "/home/christoph/Notes/HHU/Betriebssystementwicklung/Guest/c_vorgabe01/build/PCSPK.o"
}
]

121
c_os/devices/CGA.cc Executable file
View File

@ -0,0 +1,121 @@
/*****************************************************************************
* *
* C G A *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Mit Hilfe dieser Klasse kann man auf den Bildschirm des *
* PCs zugreifen. Der Zugriff erfolgt direkt auf der Hard- *
* wareebene, d.h. ueber den Bildschirmspeicher und den *
* I/O-Ports der Grafikkarte. *
* *
* Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 21.8.2016 *
*****************************************************************************/
#include "devices/CGA.h"
/*****************************************************************************
* Methode: CGA::setpos *
*---------------------------------------------------------------------------*
* Beschreibung: Setzen des Cursors in Spalte x und Zeile y. *
*****************************************************************************/
void CGA::setpos (int x, int y) {
/* Hier muess Code eingefuegt werden */
}
/*****************************************************************************
* Methode: CGA::getpos *
*---------------------------------------------------------------------------*
* Beschreibung: Abfragem der Cursorposition *
* *
* Rückgabewerte: x und y *
*****************************************************************************/
void CGA::getpos (int &x, int &y) {
/* Hier muess Code eingefuegt werden */
}
/*****************************************************************************
* Methode: CGA::show *
*---------------------------------------------------------------------------*
* Beschreibung: Anzeige eines Zeichens mit Attribut an einer bestimmten *
* Stelle auf dem Bildschirm. *
* *
* Parameter: *
* x,y Position des Zeichens *
* character Das auszugebende Zeichen *
* attrib Attributbyte fuer das Zeichen *
*****************************************************************************/
void CGA::show (int x, int y, char character, unsigned char attrib) {
/* Hier muess Code eingefuegt werden */
}
/*****************************************************************************
* Methode: CGA::print *
*---------------------------------------------------------------------------*
* Beschreibung: Anzeige mehrerer Zeichen ab der aktuellen Cursorposition *
* '\n' fuer Zeilenvorschub. *
* *
* Parameter: *
* string Auszugebende Zeichenkette *
* n Laenger der Zeichenkette *
* attrib Attributbyte fuer alle Zeichen der Zeichenkette *
*****************************************************************************/
void CGA::print (char* string, int n, unsigned char attrib) {
/* Hier muess Code eingefuegt werden */
}
/*****************************************************************************
* Methode: CGA::scrollup *
*---------------------------------------------------------------------------*
* Beschreibung: Verschiebt den Bildschirminhalt um eine Zeile nach oben. *
* Die neue Zeile am unteren Bildrand wird mit Leerzeichen *
* gefuellt. *
*****************************************************************************/
void CGA::scrollup () {
/* Hier muess Code eingefuegt werden */
}
/*****************************************************************************
* Methode: CGA::clear *
*---------------------------------------------------------------------------*
* Beschreibung: Lösche den Textbildschirm. *
*****************************************************************************/
void CGA::clear () {
/* Hier muess Code eingefuegt werden */
}
/*****************************************************************************
* Methode: CGA::attribute *
*---------------------------------------------------------------------------*
* Beschreibung: Hilfsfunktion zur Erzeugung eines Attribut-Bytes aus *
* Hintergrund- und Vordergrundfarbe und der Angabe, ob das *
* Zeichen blinkend darzustellen ist. *
* *
* Parameter: *
* bg Background color *
* fg Foreground color *
* blink ywa/no *
*****************************************************************************/
unsigned char CGA::attribute (CGA::color bg, CGA::color fg, bool blink) {
/* Hier muess Code eingefuegt werden */
}

73
c_os/devices/CGA.h Executable file
View File

@ -0,0 +1,73 @@
/*****************************************************************************
* *
* C G A *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Mit Hilfe dieser Klasse kann man auf den Bildschirm des *
* PCs zugreifen. Der Zugriff erfolgt direkt auf der Hard- *
* wareebene, d.h. ueber den Bildschirmspeicher und den *
* I/O-Ports der Grafikkarte. *
* *
* Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 21.8.2016 *
*****************************************************************************/
#ifndef __CGA_include__
#define __CGA_include__
#include "kernel/IOport.h"
class CGA {
private:
IOport index_port; // Auswahl eines Register der Grafikkarte
IOport data_port; // Lese-/Schreib-Zugriff auf Register der Grafikk.
// Copy Konstrutkor unterbinden
CGA(const CGA &copy);
public:
const char *CGA_START; // Startadresse des Buldschirmspeichers
// Konstruktur mit Initialisierung der Ports
CGA () : index_port (0x3d4), data_port (0x3d5) {
CGA_START = (const char*)0xb8000;
}
// Konstanten fuer die moeglichen Farben im Attribut-Byte.
typedef enum {
BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHT_GREY,
DARK_GREY, LIGHT_BLUE, LIGHT_GREEN, LIGHT_CYAN, LIGHT_RED,
LIGHT_MAGENTA, YELLOW, WHITE
} color;
// Standardzeichenfarbe
enum { STD_ATTR = BLACK << 4 | LIGHT_GREY };
// Groesse des Bildschirms (25 Zeilen, 80 Spalten)
enum { ROWS = 25, COLUMNS = 80 };
// Setzen des Cursors in Spalte x und Zeile y.
void setpos (int x, int y);
// Abfragen der Cursorpostion
void getpos (int& x, int& y);
// Anzeige eines Zeichens mit Attribut an einer bestimmten Stelle
void show (int x, int y, char character, unsigned char attrib = STD_ATTR);
// Anzeige mehrerer Zeichen ab der aktuellen Cursorposition
void print (char* string, int n, unsigned char attrib = STD_ATTR);
// Verschiebt den Bildschirminhalt um eine Zeile nach oben.
// Neue Zeile am unteren Bildrand mit Leerzeichen fuellen
void scrollup ();
// Lösche den Textbildschirm
void clear ();
// Hilfsfunktion zur Erzeugung eines Attribut-Bytes
unsigned char attribute (CGA::color bg, CGA::color fg, bool blink);
};
#endif

31
c_os/devices/CGA_Stream.cc Executable file
View File

@ -0,0 +1,31 @@
/*****************************************************************************
* *
* C G A _ S T R E A M *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Die Klasse CGA_Stream ermoeglicht die Ausgabe verschied. *
* Datentypen als Zeichenketten auf dem CGA-Bildschirm eines*
* PCs. Fuer weitergehende Formatierung oder spezielle *
* Effekte stehen die Methoden der Klasse CGA_Stream zur *
* Verfuegung. *
* *
* Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 1.8.16 *
*****************************************************************************/
#include "devices/CGA_Stream.h"
/*****************************************************************************
* Methode: CGA_Stream::flush *
*---------------------------------------------------------------------------*
* Beschreibung: Methode zur Ausgabe des Pufferinhalts der Basisklasse *
* StringBuffer. Die Methode wird implizit aufgerufen, *
* sobald der Puffer voll ist, kann aber auch explizit *
* verwendet werden, um eine Ausgabe zu erzwingen. *
*****************************************************************************/
void CGA_Stream::flush () {
print (buffer, pos);
pos = 0;
}

33
c_os/devices/CGA_Stream.h Executable file
View File

@ -0,0 +1,33 @@
/*****************************************************************************
* *
* C G A _ S T R E A M *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Die Klasse CGA_Stream ermoeglicht die Ausgabe verschied. *
* Datentypen als Zeichenketten auf dem CGA-Bildschirm eines*
* PCs. Fuer weitergehende Formatierung oder spezielle *
* Effekte stehen die Methoden der Klasse CGA zur *
* Verfuegung. *
* *
* Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 06.04.20 *
*****************************************************************************/
#ifndef __CGA_Stream_include__
#define __CGA_Stream_include__
#include "devices/CGA.h"
#include "lib/OutStream.h"
class CGA_Stream : public OutStream, public CGA {
private:
CGA_Stream(CGA_Stream &copy); // Verhindere Kopieren
public:
CGA_Stream () : OutStream(), CGA () { flush(); }
// Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer.
virtual void flush ();
};
#endif

861
c_os/devices/PCSPK.cc Executable file
View File

@ -0,0 +1,861 @@
/*****************************************************************************
* *
* P C S P K *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Mit Hilfe dieser Klasse kann man Toene auf dem *
* PC-Lautsprecher ausgeben. *
* *
* Achtung: Qemu muss mit dem Parameter -soundhw pcspk aufgerufen *
* werden. Ansonsten kann man nichts hoeren. *
* *
* Autor: Michael Schoettner, HHU, 22.9.2016 *
*****************************************************************************/
#include "devices/PCSPK.h"
#include "kernel/Globals.h"
/*****************************************************************************
* Methode: PCSPK::play *
*---------------------------------------------------------------------------*
* Beschreibung: Ton abspielen. *
* *
* Rückgabewerte: f: Frequenz des Tons *
* len: Laenge des Tons in ms *
*****************************************************************************/
void PCSPK::play (float f, int len) {
int freq = (int)f;
int cntStart = 1193180 / freq;
int status;
// Zaehler laden
control.outb (0xB6); // Zaehler-2 konfigurieren
data2.outb (cntStart%256); // Zaehler-2 laden (Lobyte)
data2.outb (cntStart/256); // Zaehler-2 laden (Hibyte)
// Lautsprecher einschalten
status = (int)ppi.inb (); // Status-Register des PPI auslesen
ppi.outb ( status|3 ); // Lautpsrecher Einschalten
// Pause
delay(len);
// Lautsprecher ausschalten
off ();
}
/*****************************************************************************
* Methode: PCSPK::off *
*---------------------------------------------------------------------------*
* Beschreibung: Lautsprecher ausschalten. *
*****************************************************************************/
void PCSPK::off () {
int status;
status = (int)ppi.inb (); // Status-Register des PPI auslesen
ppi.outb ( (status>>2)<<2 ); // Lautsprecher ausschalten
}
/*****************************************************************************
* Methode: PCSPK::readCounter *
*---------------------------------------------------------------------------*
* Beschreibung: Zaehler von PIT Channel 0 auslesen. *
* (wird fuer delay benoetigt). *
* *
* Rückgabewerte: counter *
*****************************************************************************/
inline unsigned int PCSPK::readCounter() {
unsigned char lo, hi;
control.outb (0x0); // Latch Command
lo = data0.inb (); // Lobyte des Counters auslesen
hi = data0.inb (); // Hibyte des Counters auslesen
return (hi << 8) | lo;
}
/*****************************************************************************
* Methode: PCSPK::delay *
*---------------------------------------------------------------------------*
* Beschreibung: Verzoegerung um X ms (in 1ms Schritten; Min. 1ms). *
* *
* Parameter: time (delay in ms) *
*****************************************************************************/
inline void PCSPK::delay (int time) {
/* Hier muess Code eingefuegt werden */
}
/*****************************************************************************
* Methode: PCSPK::tetris *
*---------------------------------------------------------------------------*
* Beschreibung: Tetris Sound, Kévin Rapaille, August 2013 *
* https://gist.github.com/XeeX/6220067 *
*****************************************************************************/
void PCSPK::tetris () {
play(658, 125);
play(1320, 500);
play(990, 250);
play(1056, 250);
play(1188, 250);
play(1320, 125);
play(1188, 125);
play(1056, 250);
play(990, 250);
play(880, 500);
play(880, 250);
play(1056, 250);
play(1320, 500);
play(1188, 250);
play(1056, 250);
play(990, 750);
play(1056, 250);
play(1188, 500);
play(1320, 500);
play(1056, 500);
play(880, 500);
play(880, 500);
delay(250);
play(1188, 500);
play(1408, 250);
play(1760, 500);
play(1584, 250);
play(1408, 250);
play(1320, 750);
play(1056, 250);
play(1320, 500);
play(1188, 250);
play(1056, 250);
play(990, 500);
play(990, 250);
play(1056, 250);
play(1188, 500);
play(1320, 500);
play(1056, 500);
play(880, 500);
play(880, 500);
delay(500);
play(1320, 500);
play(990, 250);
play(1056, 250);
play(1188, 250);
play(1320, 125);
play(1188, 125);
play(1056, 250);
play(990, 250);
play(880, 500);
play(880, 250);
play(1056, 250);
play(1320, 500);
play(1188, 250);
play(1056, 250);
play(990, 750);
play(1056, 250);
play(1188, 500);
play(1320, 500);
play(1056, 500);
play(880, 500);
play(880, 500);
delay(250);
play(1188, 500);
play(1408, 250);
play(1760, 500);
play(1584, 250);
play(1408, 250);
play(1320, 750);
play(1056, 250);
play(1320, 500);
play(1188, 250);
play(1056, 250);
play(990, 500);
play(990, 250);
play(1056, 250);
play(1188, 500);
play(1320, 500);
play(1056, 500);
play(880, 500);
play(880, 500);
delay(500);
play(660, 1000);
play(528, 1000);
play(594, 1000);
play(495, 1000);
play(528, 1000);
play(440, 1000);
play(419, 1000);
play(495, 1000);
play(660, 1000);
play(528, 1000);
play(594, 1000);
play(495, 1000);
play(528, 500);
play(660, 500);
play(880, 1000);
play(838, 2000);
play(660, 1000);
play(528, 1000);
play(594, 1000);
play(495, 1000);
play(528, 1000);
play(440, 1000);
play(419, 1000);
play(495, 1000);
play(660, 1000);
play(528, 1000);
play(594, 1000);
play(495, 1000);
play(528, 500);
play(660, 500);
play(880, 1000);
play(838, 2000);
off ();
}
/*****************************************************************************
* Methode: PCSPK::tetris *
*---------------------------------------------------------------------------*
* Beschreibung: Clint, Part of Daft Punks Aerodynamic *
* https://www.kirrus.co.uk/2010/09/linux-beep-music/ *
*****************************************************************************/
void PCSPK::aerodynamic() {
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(370.0, 122);
play(493.9, 122);
play(370.0, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(587.3, 122);
play(415.3, 122);
play(493.9, 122);
play(415.3, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(784.0, 122);
play(493.9, 122);
play(659.3, 122);
play(493.9, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(440.0, 122);
play(659.3, 122);
play(440.0, 122);
play(554.4, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(740.0, 122);
play(987.8, 122);
play(740.0, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1174.7, 122);
play(830.6, 122);
play(987.8, 122);
play(830.6, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1568.0, 122);
play(987.8, 122);
play(1318.5, 122);
play(987.8, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
play(1318.5, 122);
play(880.0, 122);
play(1108.7, 122);
play(880.0, 122);
off ();
}

94
c_os/devices/PCSPK.h Executable file
View File

@ -0,0 +1,94 @@
/*****************************************************************************
* *
* P C S P K *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Mit Hilfe dieser Klasse kann man Toene auf dem *
* PC-Lautsprecher ausgeben. *
* *
* Achtung: Qemu muss mit dem Parameter -soundhw pcspk aufgerufen *
* werden. Ansonsten kann man nichts hoeren. *
* *
* Autor: Michael Schoettner, HHU, 22.9.2016 *
*****************************************************************************/
#ifndef __PCSPK_include__
#define __PCSPK_include__
#include "kernel/IOport.h"
// Note, Frequenz
#define C0 130.81
#define C0X 138.59
#define D0 146.83
#define D0X 155.56
#define E0 164.81
#define F0 174.61
#define F0X 185.00
#define G0 196.00
#define G0X 207.65
#define A0 220.00
#define A0X 233.08
#define B0 246.94
#define C1 261.63
#define C1X 277.18
#define D1 293.66
#define D1X 311.13
#define E1 329.63
#define F1 349.23
#define F1X 369.99
#define G1 391.00
#define G1X 415.30
#define A1 440.00
#define A1X 466.16
#define B1 493.88
#define C2 523.25
#define C2X 554.37
#define D2 587.33
#define D2X 622.25
#define E2 659.26
#define F2 698.46
#define F2X 739.99
#define G2 783.99
#define G2X 830.61
#define A2 880.00
#define A2X 923.33
#define B2 987.77
#define C3 1046.50
class PCSPK {
private:
IOport control; // Steuerregister (write only)
IOport data0; // Zaehler-0 Datenregister (read/write)
IOport data2; // Zaehler-2 Datenregister
IOport ppi; // Status-Register des PPI
PCSPK (const PCSPK &copy); // Verhindere Kopieren
// Verzoegerung um X ms (in 1ms Schritten; Min. 1ms)
inline void delay (int time);
// Zaehler von PIT Channel 0 auslesen (wird fuer delay benoetigt)
inline unsigned int readCounter ();
public:
// Konstruktor. Initialisieren der Ports.
PCSPK () : control(0x43), data0(0x40), data2(0x42), ppi(0x61) {}
// Demo Sounds
void tetris ();
void aerodynamic ();
// Ton abspielen
void play (float f, int len);
// Lautsprecher ausschalten
void off ();
};
#endif

30
c_os/kernel/CPU.h Executable file
View File

@ -0,0 +1,30 @@
/*****************************************************************************
* *
* C P U *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Implementierung einer Abstraktion fuer den Prozessor. *
* *
* Autor: Michael Schoettner, 30.7.16 *
*****************************************************************************/
#ifndef __CPU_include__
#define __CPU_include__
class CPU {
private:
CPU(const CPU &copy); // Verhindere Kopieren
public:
CPU() {}
// Time-Stamp-Counter auslesen
inline unsigned long long int rdtsc() {
unsigned long long int ret;
asm volatile ( "rdtsc" : "=A"(ret) );
return ret;
}
};
#endif

17
c_os/kernel/Globals.cc Executable file
View File

@ -0,0 +1,17 @@
/*****************************************************************************
* *
* G L O B A L S *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Globale Variablen des Systems. *
* *
* Autor: Michael Schoettner, 30.7.16 *
*****************************************************************************/
#include "kernel/Globals.h"
CPU cpu; // CPU-spezifische Funktionen
PCSPK pcspk; // PC-Lautsprecher
CGA_Stream kout; // Ausgabe-Strom fuer Kernel

21
c_os/kernel/Globals.h Executable file
View File

@ -0,0 +1,21 @@
/*****************************************************************************
* *
* G L O B A L S *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Globale Variablen des Systems. *
* *
* Autor: Michael Schoettner, 30.7.16 *
*****************************************************************************/
#ifndef __Globals_include__
#define __Globals_include__
#include "kernel/CPU.h"
#include "devices/PCSPK.h"
#include "devices/CGA_Stream.h"
extern CPU cpu; // CPU-spezifische Funktionen
extern PCSPK pcspk; // PC-Lautsprecher
extern CGA_Stream kout; // Ausgabe-Strom fuer Kernel
#endif

76
c_os/kernel/IOport.h Executable file
View File

@ -0,0 +1,76 @@
/*****************************************************************************
* *
* I O P O R T *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Diese Klasse dient dem Zugriff auf die Ein-/Ausgabe *
* Ports des PCs. Beim PC gibt es einen gesonderten I/O- *
* Adressraum, der nur mittels der Maschineninstruktionen *
* 'in' und 'out' angesprochen werden kann. Ein IOport- *
* Objekt wird beim Erstellen an eine Adresse des I/O- *
* Adressraums gebunden und kann dann fuer byte- oder *
* wortweise Ein- oder Ausgaben verwendet werden. *
* *
* Autor: Michael Schoettner, 28.8.2016 *
*****************************************************************************/
#ifndef __IOport_include__
#define __IOport_include__
class IOport {
// Kopieren erlaubt!
// 16-Bit Adresse im I/O-Adressraum
unsigned short address;
public:
// Konstruktor, speichert Port-Adresse
IOport (unsigned short a) : address (a) { };
// Byteweise Ausgabe eines Wertes ueber einen I/O-Port.
void outb (unsigned char val) const {
asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(address) );
}
// Wortweise Ausgabe eines Wertes ueber einen I/O-Port.
void outw (unsigned short val) const {
asm volatile ( "outw %0, %1" : : "a"(val), "Nd"(address) );
}
// 32-Bit Ausgabe eines Wertes ueber einen I/O-Port.
void outdw (unsigned int val) const {
asm volatile ( "outl %0, %1" : : "a"(val), "Nd"(address) );
}
// Byteweises Einlesen eines Wertes ueber einen I/O-Port.
unsigned char inb () const {
unsigned char ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "Nd"(address) );
return ret;
}
// Wortweises Einlesen eines Wertes ueber einen I/O-Port.
unsigned short inw () const {
unsigned short ret;
asm volatile ( "inw %1, %0"
: "=a"(ret)
: "Nd"(address) );
return ret;
}
// 32-Bit Einlesen eines Wertes ueber einen I/O-Port.
unsigned int indw () const {
unsigned int ret;
asm volatile ( "inl %1, %0"
: "=a"(ret)
: "Nd"(address) );
return ret;
}
};
#endif

View File

@ -0,0 +1,21 @@
/*****************************************************************************
* *
* 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, 30.7.16 *
*****************************************************************************/
extern "C" void int_disp (unsigned int slot);
// Low-Level Interrupt-Behandlung. (Die Funktion wird spaeter noch erweitert)
void int_disp (unsigned int slot) {
}

160
c_os/lib/OutStream.cc Executable file
View File

@ -0,0 +1,160 @@
/*****************************************************************************
* *
* O U T S T R E A M *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Die Klasse OutStream enthaelt die Definition des *
* << Operators fuer die wichtigsten der vordefinierten *
* Datentypen und realisiert somit die bekannte Ausgabe- *
* funktion der C++ iO_Stream Bibliothek. Zur Zeit wird *
* die Darstellung von Zeichen, Zeichenketten und ganzen *
* Zahlen unterstuetzt. Ein weiterer << Operator erlaubt *
* die Verwendung von Manipulatoren. *
* *
* Neben der Klasse OutStream sind hier auch die *
* Manipulatoren hex, dec, oct und bin fuer die Wahl der *
* Basis bei der Zahlendarstellung, sowie endl fuer den *
* Zeilenumbruch definiert. *
* *
* Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 1.8.16 *
*****************************************************************************/
#include "lib/OutStream.h"
//
// Zeichen und Zeichenketten in Stream ausgeben
//
OutStream& OutStream::operator << (char c) {
put(c);
return *this;
}
OutStream& OutStream::operator << (unsigned char c) {
return *this << (char) c;
}
OutStream& OutStream::operator << (char* string) {
char* pos = string;
while (*pos) {
put (*pos);
pos++;
}
return *this;
}
//
// Ganzer Zahlen im Zahlensystem zur Basis base in Stream ausgeveb
// Alle vorzeichenbehafteten Datentypen werden als long dargestellt,
// Alle vorzeichenlosen als unsigned long.
OutStream& OutStream::operator << (short ival) {
return *this << (long) ival;
}
OutStream& OutStream::operator << (unsigned short ival) {
return *this << (unsigned long) ival;
}
OutStream& OutStream::operator << (int ival) {
return *this << (long) ival;
}
OutStream& OutStream::operator << (unsigned int ival) {
return *this << (unsigned long) ival;
}
// Darstellung eine vorzeichenbehafteten ganzen Zahl.
OutStream& OutStream::operator << (long ival) {
// Bei negativen Werten wird ein Minuszeichen ausgegeben.
if (ival < 0) {
put ('-');
ival = -ival;
}
// Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben.
return *this << (unsigned long) ival;
}
// Darstellung einer vorzeichenlosen ganzen Zahl.
OutStream& OutStream::operator << (unsigned long ival) {
unsigned long div;
char digit;
if (base == 8)
put ('0'); // oktale Zahlen erhalten eine fuehrende Null
else if (base == 16) {
put ('0'); // hexadezimale Zahlen ein "0x"
put ('x');
}
// Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die
// noch kleiner als die darzustellende Zahl ist.
for (div = 1; ival/div >= (unsigned long) base; div *= base);
// ziffernweise Ausgabe der Zahl
for (; div > 0; div /= (unsigned long) base) {
digit = ival / div;
if (digit < 10)
put ('0' + digit);
else
put ('a' + digit - 10);
ival %= div;
}
return *this;
}
// Darstellung eines Zeigers als hexadezimale ganze Zahl
OutStream& OutStream::operator << (void* ptr) {
int oldbase = base;
base = 16;
*this << (unsigned long) ptr;
base = oldbase;
return *this;
}
// Aufruf einer Manipulatorfunktion
OutStream& OutStream::operator << (OutStream& (*f) (OutStream&)) {
return f(*this);
}
//
// Manipulatorfunktionen
//
// Die folgenden Funktionen erhalten und liefern jeweils eine Referenz auf
// ein OutStream Objekt. Da die Klasse O_Stream einen Operator << fuer
// derartige Funktionen definiert, koennen sie mit Hilfe dieses Operators
// aufgerufen und sogar in weitere Eingaben eingebettet werden.
// Aufgabe der Manipulatoren ist, die Darstellung der nachfolgenden Ausgaben
// zu beeinflussen, z.B durch die Wahl des Zahlensystems.
// Fuege einen Zeilenumbruch in die Ausgabe ein.
OutStream& endl (OutStream& os) {
os << '\n';
os.flush ();
return os;
}
// Waehlt das binaere Zahlensystem aus.
OutStream& bin (OutStream& os) {
os.base = 2;
return os;
}
// Waehlt das oktale Zahlensystem aus.
OutStream& oct (OutStream& os) {
os.base = 8;
return os;
}
// Waehlt das dezimale Zahlensystem aus.
OutStream& dec (OutStream& os) {
os.base = 10;
return os;
}
// Waehlt das hexadezimale Zahlensystem aus.
OutStream& hex (OutStream& os) {
os.base = 16;
return os;
}

92
c_os/lib/OutStream.h Executable file
View File

@ -0,0 +1,92 @@
/*****************************************************************************
* *
* O U T S T R E A M *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Die Klasse OutStream enthaelt die Definition des *
* << Operators fuer die wichtigsten der vordefinierten *
* Datentypen und realisiert somit die bekannte Ausgabe- *
* funktion der C++ iO_Stream Bibliothek. Zur Zeit wird *
* die Darstellung von Zeichen, Zeichenketten und ganzen *
* Zahlen unterstuetzt. Ein weiterer << Operator erlaubt *
* die Verwendung von Manipulatoren. *
* *
* Neben der Klasse OutStream sind hier auch die *
* Manipulatoren hex, dec, oct und bin fuer die Wahl der *
* Basis bei der Zahlendarstellung, sowie endl fuer den *
* Zeilenumbruch definiert. *
* *
* Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 06.04.20 *
*****************************************************************************/
#ifndef __OutStream_include__
#define __OutStream_include__
#include "lib/StringBuffer.h"
class OutStream : public StringBuffer {
private:
OutStream(const OutStream &copy); // Verhindere Kopieren
public:
int base; // Basis des Zahlensystems: z.B. 2, 8, 10 oder 16
OutStream () : StringBuffer () { base = 10; } // initial Dezimalsystem
virtual void flush () = 0; // weiterhin undefiniert
// OPERATOR << : Umwandlung des angegebenen Datentypes in eine
// Zeichenkette.
// Darstellung eines Zeichens (trivial)
OutStream& operator << (char c);
OutStream& operator << (unsigned char c);
// Darstellung einer nullterminierten Zeichenkette
OutStream& operator << (char* string);
// Darstellung ganzer Zahlen im Zahlensystem zur Basis base
OutStream& operator << (short ival);
OutStream& operator << (unsigned short ival);
OutStream& operator << (int ival);
OutStream& operator << (unsigned int ival);
OutStream& operator << (long ival);
OutStream& operator << (unsigned long ival);
// Darstellung eines Zeigers als hexadezimale ganze Zahl
OutStream& operator << (void* ptr);
// Aufruf einer Manipulatorfunktion
OutStream& operator << (OutStream& (*f) (OutStream&));
};
//
// Manipulatorfunktionen
//
// Die folgenden Funktionen erhalten und liefern jeweils eine Referenz auf
// ein OutStream Objekt. Da die Klasse OutStream einen Operator << fuer
// derartige Funktionen definiert, koennen sie mit Hilfe dieses Operators
// aufgerufen und sogar in weitere Eingaben eingebettet werden.
// Aufgabe der Manipulatoren ist, die Darstellung der nachfolgenden Ausgaben
// zu beeinflussen, z.B durch die Wahl des Zahlensystems.
// Zeilenumbruch in Ausgabe einfuegen.
OutStream& endl (OutStream& os);
// Waehle binaeres Zahlensystem aus.
OutStream& bin (OutStream& os);
// Waehle oktales Zahlensystem aus.
OutStream& oct (OutStream& os);
// Waehle dezimales Zahlensystem aus.
OutStream& dec (OutStream& os);
// Waehle hexadezimales Zahlensystem aus.
OutStream& hex (OutStream& os);
#endif

38
c_os/lib/StringBuffer.cc Executable file
View File

@ -0,0 +1,38 @@
/*****************************************************************************
* *
* S T R I N G B U F F E R *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Die Klasse StringBuffer stellt einen Puffer fuer die *
* Sammlung von Zeichen zur Darstellung auf dem Bildschirm *
* oder anderen Ausgabegeraeten bereit. Die Ausgabe der *
* Zeichen erfolgt, sobald der Puffer voll ist oder wenn *
* explizit die Methode flush() aufgerufen wird. *
* Da StringBuffer geraeteunabhaengig sein soll, ist *
* flush() eine virtuelle Methode, die von den abgeleiteten *
* Klassen definiert werden muss. *
* *
* Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 1.8.16 *
*****************************************************************************/
#include "lib/StringBuffer.h"
/*****************************************************************************
* Methode: StringBuffer::put *
*---------------------------------------------------------------------------*
* Beschreibung: Fuegt ein Zeichen in den Puffer ein. Wenn der Puffer *
* daraufhin voll ist, wird er durch Aufruf der Methode *
* flush geleert. *
* *
* Parameter: *
* c: Einzufuegendes Zeichen. *
*****************************************************************************/
void StringBuffer::put (char c) {
buffer[pos] = c;
pos++;
if (pos == sizeof (buffer))
flush ();
}

47
c_os/lib/StringBuffer.h Executable file
View File

@ -0,0 +1,47 @@
/*****************************************************************************
* *
* S T R I N G B U F F E R *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Die Klasse StringBuffer stellt einen Puffer fuer die *
* Sammlung von Zeichen zur Darstellung auf dem Bildschirm *
* oder anderen Ausgabegeraeten bereit. Die Ausgabe der *
* Zeichen erfolgt, sobald der Puffer voll ist oder wenn *
* explizit die Methode flush() aufgerufen wird. *
* Da StringBuffer geraeteunabhaengig sein soll, ist *
* flush() eine virtuelle Methode, die von den abgeleiteten *
* Klassen definiert werden muss. *
* *
* Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 06.04.20 *
*****************************************************************************/
#ifndef __StringBuffer_include__
#define __StringBuffer_include__
class StringBuffer {
private:
StringBuffer(const StringBuffer &copy); // Verhindere Kopieren
// Alle Variablen und Methoden dieser Klasse sind "protected",
// da die abgeleiteten Klassen einen direkten Zugriff auf den
// Puffer, den Konstruktor, den Destruktor und die Methode put
// benoetigen. Die Methode flush() muss sowieso neu definiert
// werden und kann dann auch public werden.
protected:
char buffer[80];
int pos;
// StringBuffer: Im Konstruktor wird der Puffer als leer markiert.
StringBuffer () : pos(0) {}
// Fuegt ein Zeichen in den Puffer ein. Wenn der Puffer
void put (char c);
// Methode zur Ausgabe des Pufferinhalts
virtual void flush () = 0;
};
#endif

31
c_os/main.cc Executable file
View File

@ -0,0 +1,31 @@
/*****************************************************************************
* *
* M A I N *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Startroutine, wird direkt vom Bootlader angesprungen, *
* nachdem dieser in den Protected Mode geschaltet hat und *
* die GDT und IDT initalisiert hat. *
* *
* Autor: Michael Schoettner, HHU, 15.8.2016 *
*****************************************************************************/
#include "kernel/Globals.h"
#include "user/TextDemo.h"
#include "user/SoundDemo.h"
int main() {
/* Hier muess Code eingefuegt werden */
// Bildschirm loeschen.
// Startmeldung ausgeben
text_demo();
sound_demo();
while (1);
return 0;
}

70
c_os/sections Executable file
View File

@ -0,0 +1,70 @@
/* $Id: sections 5834 2013-10-08 17:04:08Z os $ */
SECTIONS
{
. = 0x100000; /* Startadresse des Systems */
.text :
{
*(".text")
*(".text.*")
*(".text$")
*(".init")
*(".fini")
*(".gnu.linkonce.*")
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
KEEP (*(".ctors"))
KEEP (*(".ctor"))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
KEEP (*(".dtors"))
KEEP (*(".dtor"))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.data :
{
*(".data")
*(".data$")
*(".rodata")
*(".rodata.*")
*(".got")
*(".got.plt")
*(".eh_frame")
*(".eh_fram")
*(".jcr")
*(".note.*")
}
.bss :
{
___BSS_START__ = .;
*(".bss")
*(".bss.*")
___BSS_END__ = .;
}
/*
/DISCARD/ :
{
*(".note")
*(".comment")
*(".debug_line")
*(".debug_info")
*(".debug_abbrev")
*(".debug_aranges")
}
*/
}

284
c_os/startup.asm Executable file
View File

@ -0,0 +1,284 @@
;******************************************************************************
;* *
;* S T A R T U P . A S M *
;* *
;*----------------------------------------------------------------------------*
;* Beschreibung: 'startup' ist der Eintrittspunkt des eigentlichen Systems.*
;* Die Umschaltung in den Protected-Mode ist bereits erfolgt.*
;* Es wird alles vorbereitet, damit so schnell wie moeglich *
;* die weitere Ausfuehrung durch C-Code erfolgen kann. *
;* *
;* Autor: Olaf Spinczyk, TU Dortmund *
;******************************************************************************
; Multiboot-Konstanten
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
; Magic-Number fuer Multiboot
MULTIBOOT_HEADER_MAGIC equ 0x1badb002
; Multiboot-Flags (ELF-spezifisch!)
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
MULTIBOOT_HEADER_CHKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
MULTIBOOT_EAX_MAGIC equ 0x2badb002
;
; System
;
[GLOBAL startup]
[GLOBAL idt]
[GLOBAL __cxa_pure_virtual]
[GLOBAL _ZdlPv]
[EXTERN main]
[EXTERN int_disp]
[EXTERN ___BSS_START__]
[EXTERN ___BSS_END__]
[EXTERN __init_array_start]
[EXTERN __init_array_end]
[EXTERN __fini_array_start]
[EXTERN __fini_array_end]
[SECTION .text]
startup:
jmp skip_multiboot_hdr
multiboot_header:
align 4
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_HEADER_CHKSUM
skip_multiboot_hdr:
; GCC-kompilierter Code erwartet das so.
cld
cmp eax,MULTIBOOT_EAX_MAGIC
jne floppy_boot
;
; GDT setzen (notwendig, falls wir durch GRUB geladen wurden)
;
lgdt [gdt_48]
floppy_boot:
; Globales Datensegment
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
; Stack festlegen
mov ss,ax
mov esp,init_stack+4096
; Unterbrechungsbehandlung sicherstellen
call setup_idt
call reprogram_pics
; BSS loeschen
mov edi, ___BSS_START__
clear_bss:
mov byte [edi], 0
inc edi
cmp edi, ___BSS_END__
jne clear_bss
; Aufruf des C-Codes
call _init ; Konstruktoren globaler Objekte ausfuehren
call main ; C/C++ Level System
call _fini ; Destruktoren
hlt
;; Ausfuehrung der Konstruktoren globaler Objekte
_init:
mov edi, __init_array_start
_init_loop:
cmp edi, __init_array_end
je _init_done
mov eax, [edi]
call eax
add edi, 4
ja _init_loop
_init_done:
ret
;; Ausfuehrung der Destruktoren globaler Objekte
_fini:
mov edi, __fini_array_start
_fini_loop:
cmp edi, __fini_array_end
je _fini_done
mov eax, [edi]
call eax
add edi, 4
ja _fini_loop
_fini_done:
ret
; Default Interrupt Behandlung
; Spezifischer Kopf der Unterbrechungsbehandlungsroutinen
%macro wrapper 1
wrapper_%1:
push eax
mov al,%1
jmp wrapper_body
%endmacro
; ... wird automatisch erzeugt.
%assign i 0
%rep 256
wrapper i
%assign i i+1
%endrep
; Gemeinsamer Rumpf
wrapper_body:
cld ; das erwartet der gcc so.
push ecx ; Sichern der fluechtigen Register
push edx
and eax,0xff ; Der generierte Wrapper liefert nur 8 Bits
push eax ; Nummer der Unterbrechung uebergeben
call int_disp
add esp,4 ; Parameter vom Stack entfernen
pop edx ; fluechtige Register wieder herstellen
pop ecx
pop eax
iret ; fertig!
;
; setup_idt
;
; Relokation der Eintraege in der IDT und Setzen des IDTR
setup_idt:
mov eax,wrapper_0 ; ax: niederwertige 16 Bit
mov ebx,eax
shr ebx,16 ; bx: hoeherwertige 16 Bit
mov ecx,255 ; Zaehler
.loop: add [idt+8*ecx+0],ax
adc [idt+8*ecx+6],bx
dec ecx
jge .loop
lidt [idt_descr]
ret
;
; reprogram_pics
;
; Neuprogrammierung der PICs (Programmierbare Interrupt-Controller), damit
; alle 15 Hardware-Interrupts nacheinander in der idt liegen.
reprogram_pics:
mov al,0x11 ; ICW1: 8086 Modus mit ICW4
out 0x20,al
call delay
out 0xa0,al
call delay
mov al,0x20 ; ICW2 Master: IRQ # Offset (32)
out 0x21,al
call delay
mov al,0x28 ; ICW2 Slave: IRQ # Offset (40)
out 0xa1,al
call delay
mov al,0x04 ; ICW3 Master: Slaves an IRQs
out 0x21,al
call delay
mov al,0x02 ; ICW3 Slave: Verbunden mit IRQ2 des Masters
out 0xa1,al
call delay
mov al,0x03 ; ICW4: 8086 Modus und automatischer EIO
out 0x21,al
call delay
out 0xa1,al
call delay
mov al,0xff ; Hardware-Interrupts durch PICs
out 0xa1,al ; ausmaskieren. Nur der Interrupt 2,
call delay ; der der Kaskadierung der beiden
mov al,0xfb ; PICs dient, ist erlaubt.
out 0x21,al
ret
; delay
;
; Kurze Verzoegerung fuer in/out Befehle.
delay:
jmp .L2
.L2: ret
; Die Funktion wird beim abarbeiten der globalen Konstruktoren aufgerufen
; (unter Linux). Das Label muss definiert sein (fuer den Linker). Die
; Funktion selbst kann aber leer sein, da bei StuBs keine Freigabe des
; Speichers erfolgen muss.
__cxa_pure_virtual:
_ZdlPv:
ret
[SECTION .data]
; 'interrupt descriptor table' mit 256 Eintraegen.
idt:
%macro idt_entry 1
dw (wrapper_%1 - wrapper_0) & 0xffff
dw 0x0008
dw 0x8e00
dw ((wrapper_%1 - wrapper_0) & 0xffff0000) >> 16
%endmacro
; ... wird automatisch erzeugt.
%assign i 0
%rep 256
idt_entry i
%assign i i+1
%endrep
idt_descr:
dw 256*8-1 ; idt enthaelt 256 Eintraege
dd idt
; Stack und interrupt descriptor table im BSS Bereich
[SECTION .bss]
init_stack:
resb 4096
[SECTION .data]
;
; Descriptor-Tabellen
;
gdt:
dw 0,0,0,0 ; NULL Deskriptor
dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb)
dw 0x0000 ; base address=0
dw 0x9A00 ; code read/exec
dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit)
dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb)
dw 0x0000 ; base address=0
dw 0x9200 ; data read/write
dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit)
gdt_48:
dw 0x18 ; GDT Limit=24, 3 GDT Eintraege
dd gdt ; Physikalische Adresse der GDT

17
c_os/user/SoundDemo.cc Executable file
View File

@ -0,0 +1,17 @@
/*****************************************************************************
* *
* S O U N D D E M O *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Test für den PC-Lautsprecher-Treiber. *
* *
* Autor: Michael Schoettner, HHU, 26.10.2018 *
*****************************************************************************/
#include "kernel/Globals.h"
void sound_demo() {
/* Hier muess Code eingefuegt werden */
}

16
c_os/user/SoundDemo.h Executable file
View File

@ -0,0 +1,16 @@
/*****************************************************************************
* *
* S O U N D D E M O *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Test für den PC-Lautsprecher-Treiber. *
* *
* Autor: Michael Schoettner, HHU, 26.10.2018 *
*****************************************************************************/
#ifndef __SoundDemo_include__
#define __SondDemo_include__
void sound_demo();
#endif

18
c_os/user/TextDemo.cc Executable file
View File

@ -0,0 +1,18 @@
/*****************************************************************************
* *
* T E X T D E M O *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Testausgaben für den CGA-Treiber. *
* *
* Autor: Michael Schoettner, HHU, 26.10.2018 *
*****************************************************************************/
#include "kernel/Globals.h"
void text_demo() {
/* Hier muess Code eingefuegt werden */
}

16
c_os/user/TextDemo.h Executable file
View File

@ -0,0 +1,16 @@
/*****************************************************************************
* *
* T E X T D E M O *
* *
*---------------------------------------------------------------------------*
* Beschreibung: Testausgaben für den CGA-Treiber. *
* *
* Autor: Michael Schoettner, HHU, 26.10.2018 *
*****************************************************************************/
#ifndef __TextDemo_include__
#define __TextDemo_include__
void text_demo();
#endif