OS9-L2

Aus
Wechseln zu: Navigation, Suche


OS9 Level 2


Verbesserungen gegenüber Level 1

Die Unterschiede zwischen OS9 L1 und L2:

  • Erweiterung des Adressraum von 64KB auf bis zu mehrere MB
  • jeder Task kann bis zu 64KB Speicher für sich alleine haben
  • Trennung von System und Usermodus (Schutz)




Erweiterung des Adressraum

Während bei L1 die Größe des Arbeitsspeicher auf 64KB beschränkt ist, kann L2 mehrere MB große Arbeitsspeicher verwalten. Dazu ist eine zusätzliche Hardware (MMU) notwendig, da die CPU ja nur 64KB adressieren kann.


Die CPU sieht immer nur 64KB (logischer Adressraum). Die MMU sieht den gesamten Arbeitsspeicher (physischer Adressraum). Der physischer Adressraum kann mehrere MB groß sein.

Die MMU



Memory MAP

Der physikalische Adressraum hat eine Größe von einem oder mehreren Megabytes. Dem gegenüber steht eine CPU die nur 64K adressieren kann (logischer Adressraum). Diese Diskrepanz wird gelöst durch den Einsatz einer MMU (Memory Management Unit).


Bei der MMU von Motorola (MC6829) hat der physikalische Adressraum eine Größe von 2MB und ist in 1024 Seiten (Pages) zu je 2K (Page $000 bis $3FF) unterteilt.

Diese MMU splittet den logischen Adressraum (64K) auf in 32 Blöcke zu je 2K. Jeder dieser 2K großen Blöcke kann nun irgendwo im physikalischen Adressraum liegen (in 2K Schritten). Es erfolgt also eine Zuordnung von Block zu Page.

Bei der MMU-16 hat der physikalische Adressraum eine Größe von 16MB und ist in 8192 Seiten (Pages) zu je 2K (Page $000 bis $1FFF) unterteilt.


Beide MMU splitten den logischen Adressraum (64K) auf in 32 Blöcke zu je 2K. Jeder dieser 2K großen Blöcke kann nun irgendwo im physikalischen Adressraum liegen (in 2K Schritten). Es erfolgt also eine Zuordnung von Block zu Page.


Es sind 32 Blöcke die einer Page zugeordnet werden. Dazu gibt es 32 Zeiger zu je 10 Bit (MMU 6829) bzw. 16 Bit (MMU-16). Es sind also zwei Bytes pro Page (insgesamt 64 Bytes), die eine ganze Speicherbelegung (Memory Map) beschreiben.

Die Memory MAP ist also ein komplette 'Sicht' auf den logischen Adressraum von 64K. Das ermöglicht einen sehr flexiblen Zugriff auf den gesamten physikalischen Adressraum. Zudem kann das Block Mapping dynamisch verändert werden, sodass die CPU stets die gerade wichtigen Teile des physikalischen Adressraum im Zugriff hat.


Memory MAP bei der MMU 6829


Memory MAP bei der MMU-16


Speicher Management (MMU)

Das NitrOS9 Level 2 hat bestimmte Anforderungen an die Hardware. Neben den Mindestanforderungen von 128K RAM sollte auch das Banking bestimmten Anforderungen entsprechen. Der Grund ist die Multitasking Fähigkeit von NitrOS9, das erfordert eine blitzschnelle Umschaltung zwischen verschiedenen Speicherbelegungen (Memory Maps).

In einem NitrOS9 System gibt es mehr als eine Memory MAP. Es ist sinnvoll, dass das OS andere Teile des physikalischen Adressraum sieht als ein Benutzer Programm. Zudem ist NitrOS9 in der Lage mehrere Benutzer Programme quasi gleichzeitig laufen zu lassen (Multi Tasking). Es gibt also mehrere Memory MAPs für das OS, für Treiber und für mehrere Benutzer Programme. Deshalb wird eine bestimmte Memory MAP als 'Task' bezeichnet.

Jeder Task beschreibt also eine ganze Memory MAP. Eine Memory MAP besteht technisch gesehen aus x Zeiger in den physikalischen Adressraum (für jeden Block ein Zeiger). Jeder Zeiger enthält die Nummer der zugeordneten Page, also eine Zahl zwischen 0 und 1023 (10 Bit bei der MMU 6829) bzw. zwischen 0 und 8191 (13 +3 Bit bei der MMU-16). Die Zeiger sind dynamisch änderbar, also quasi ein RAM Speicher aus Sicht der CPU. Die MMU benötigt also 64 Byte RAM Speicher pro Task.

Das Multitasking ist natürlich nicht wirklich eine 'gleichzeitige' Ausführung von Programmen. Selbstverständlich wird immer nur ein Programm nach dem anderen ausgeführt. Um das Gefühl von gleichzeitig zu bekommen, wechselt die Ausführung der verschiedenen Tasks relativ häufig (zig mal pro Sekunde). Nun hat jeder Task seine eigene Memory MAP bestehend aus 64 Zeiger in den physikalischen Adressraum. Dank MMU muss das OS aber nur einen Schreibzugriff ausführen, um einen Task Wechsel zu veranlassen. Dazu stellt die MMU ein TASK-Register zur Verfügung.

Unter NitrOS9 werden alle Interrupts der CPU vom OS ausgeführt. Das bedeutet einen Task Wechsel in der MMU für jeden einzelnen Interrupt. Und natürlich einen Taskwechsel zurück zum Task der vorher eingestellt war. Das NitrOS9 läuft dabei immer auf Task #0.



MMU Motorola 6829

Die MMU 6829 hat der physikalische Adressraum eine Größe von 2MB und ist in 1024 Seiten (Pages) zu je 2K (Page $000 bis $3FF) unterteilt.

Diese MMU splittet den logischen Adressraum (64K) auf in 32 Blöcke zu je 2K. Jeder dieser 2K großen Blöcke kann nun irgendwo im physikalischen Adressraum liegen (in 2K Schritten). Es erfolgt also eine Zuordnung von Block zu Page.

Es sind 32 Blöcke die einem der 1024 Pages zugeordnet werden. Dazu gibt es 32 Zeiger zu je 10 Bit (zwei Bytes), also insgesamt 64 Bytes, die eine ganze Speicherbelegung (Memory Map) beschreiben.


Die MMU MC6829 stellt vier Tasks zur Verfügung. Also insgesamt 256 Bytes (64 mal 4). Jeder Speicherzugriff der CPU ist zunächst ein Zugriff in den logischen Adressraum (64K). Das System stellt aber einen physikalischen Adressraum von 2MB zur Verfügung. Die MMU muss jeden Speicherzugriff umrechnen von logischer Adresse zu physikalischer Adresse. Das ist insbesondere bei einer 3MHz CPU eine ziemliche Herausforderung.



Kaskadierung

Wenn das Multitasking intensiv genutzt wird, dann reichen diese 4 Tasks der MMU nicht mehr aus. In diesem Fall muss das NitrOS9 auf virtuelle Memory MAPs ausweichen. Das bedeutet aber, dass der Task Wechsel jedes mal 64 Bytes kopieren muss. Das bremst das System natürlich aus, darum ist eine größere Anzahl an echten Tasks wünschenswert.


Mit einer MMU hat man 4 'echte' Tasks

  • 0: System,
  • 1: DMA
  • 2,3: User Tasks


Die MMU MC6829 kann sehr einfach kaskadiert werden. Es können bis zu 8 MMUs (32 Tasks) problemlos im selben System arbeiten. Kaskadierte MMU's haben alle Pins bis auf einen einfach durchverbunden. Der eine Pin der unterschiedlich verdrahtet ist, selektiert die gewünschte MMU. Diese Selektion kann zB. durch einen 74LS138 erfolgen.



Die MMU-16

Die Motorola MMU 6829 ist heutzutage kaum noch zu bekommen. Aus diesem Grund wurde die MMU-16 entwickelt. Die Arbeitsweise und die Register der MMU-16 sind kompatibel zur Motorola 6829. Alle Bauteile sind auch heutzutage noch gut erhältlich.


Bei der MMU-16 hat der physikalische Adressraum eine Größe von 16MB und ist in 8192 Seiten (Pages) zu je 2K (Page $0000 bis $1FFF) unterteilt.

Diese MMU splittet den logischen Adressraum (64K) auf in 32 Blöcke zu je 2K. Jeder dieser 2K großen Blöcke kann nun irgendwo im physikalischen Adressraum liegen (in 2K Schritten). Es erfolgt also eine Zuordnung von Block zu Page.

Es sind 32 Blöcke die einem der 8192 Pages zugeordnet werden. Dazu gibt es 32 Zeiger zu je 13 Bit (zwei Bytes), also insgesamt 64 Bytes, die eine ganze Speicherbelegung (Memory Map) beschreiben. Zu den 13 Adressbits kommen noch 3 Bits, die den Zugriff beschränken. So sind alle 16 Bit des Mapping RAM in Verwendung.


Die MMU-16 stellt 256 Tasks zur Verfügung. Das Mapping RAM hat insgesamt 2 x 8192 Bytes (64 mal 256). Jeder Speicherzugriff der CPU ist zunächst ein Zugriff in den logischen Adressraum (64K). Das System stellt aber einen physikalischen Adressraum von 16MB zur Verfügung.


Die MMU-16 besteht aus folgenden Teilen:

  • CPLD-1: ein ATF1504-44 (Selektor und Multiplexer des logischen Adressbus)
  • CPLD-2: ein ATF1504-84 (MMU Logik und Handling am physikalischen Adressbus)
  • zwei schnelle SRAM (Cache RAM) zu je 8K (Mapping RAM)


Unterschiede zur MMU 6829:

  • der physikalische Adressraum hat eine Größe von 16MB (statt 2MB bei der 6829)
  • pro Page kann der Zugriff mittels der drei Zugriffs Bits gesteuert werden
  • die MMU-16 stellt 256 Tasks zur Verfügung, eine Kaskadierung ist daher unnötig
  • es gibt keine KV Register, weil es ja keine Kaskadierung gibt
  • ein Schreibzugriff auf die Adresse des KV-0 Register beendet den Reset Modus (wie bei der 6829)
  • die Lage der MMU im logischen Adressraum dekodiert die MMU-16 selbst (CPLD 1)


Die MMU muss für jeden Speicherzugriff die logische Adresse umrechnen zu einer physikalischen Adresse. Das ist insbesondere bei einer 3MHz CPU eine ziemliche Herausforderung an den RAM in der MMU. Der Mapping RAM muss eine Antwortzeit von maximal 10 bis 12 Nanosekunden haben.

Der Code für die Initialisierung der MMU-16 nach einem Reset ist derselbe, wie für ein System mit einer einzigen Motorola 6829. Auch der restliche Systemcode für Taskwechsel, Interrupts, DMA und sonstiges müsste kompatibel sein. Natürlich werden ohne Änderungen nur 10 Adressbits statt der möglichen 13 verwendet um die physikalische Adresse zu bilden.



Speicher Schutz

Wenn nur ein Programm läuft, dann braucht man keinen besonderen Schutz des Speicherraum. Ganz anders ist es, wenn man mehrere Programme gleichzeitig laufen lässt (Multitasking). Es erhöht die Stabilität des System ungemein, wenn jedes Programm nur 'seinen eigenen Speicher' im Zugriff hat.

Das gilt insbesondere auch für den Speicher des Betriebssystem selbst. Wenn Benutzerprogramm in den Speicherbereich des NitrOS9 schreiben können, dann kann es zu Problemen und Abstürze kommen.

All Ressourcen im System (Bildschirm, IO, Massenspeicher, Kommunikation ...) können bei einer Motorola CPU nur als quasi 'Speicher' zugegriffen werden. Daher ist eine Speicherschutz auch glz. ein Schutz aller Ressourcen im System. Zum Beispiel der Bildschirm RAM, wenn da zwei Programme glz. hinein schreiben, dann wird es wahrscheinlich chaotisch aussehen am Bildschirm den Benutzer.


Nun kann die CPU ja nur ihren logischen Adressraum zugreifen. Daraus folgt, die CPU kann im physikalischen Adressraum nur zugeordnete Pages verändern. Letztlich muss also nur der Zugriff auf die MMU selbst beschränkt werden, um einen Speicherschutz zu erreichen.

Bei der MMU 6829 ist der Zugriff auf die MMU nur im Task #0 möglich. Task #0 ist also der System Task, der die alleinige Kontrolle über das Page Mapping hat. Der Speicherschutz ist folglich alleinige Aufgabe des OS. Das NitrOS9 kann sensible Speicherbereiche einem Programm zuordnen oder eben nicht.


Maximale Speicher Nutzung

Unter NitrOS9 Level 1 hatte man nie den vollen logischen Adressraum zur Verfügung. In jedem Fall musste stets ein ROM im obersten Ende des Speicher sein, weil da die Vektoren für Interrupts und SWI stehen und auch der Code dafür musste stets im Zugriff stehen.

Dank MMU und NitrOS9 Level 2 kann nun jeder Task die gesamten 64K voll RAM haben. Es wird kein einziges Byte verschwendet für ROM oder IO.


Möglich wird das durch eine besondere Fähigkeit der MMU, die selbstständig beim Aufruf einen OS9 Service (SWI) oder eines Interrupts automatisch in den System Task #0 schalten kann. Dazu stellt die CPU eigene Signale zur Verfügung, die ermöglichen der MMU die Erkennung, was die CPU gerade so macht. Im Falle eines Interrupt werden die Register auf den User Stack geschrieben, dann schaltet die MMU automatisch auf den Task #0, wodurch das System ROM sichtbar wird. Die CPU lädt den Interrupt Vektor aus dem System ROM und führt den Code aus.


Jeder Benutzer Task kann zusätzlichen RAM anfordern vom OS. Über einen Banking Bereich kann man so auch mehr als 64K Speicher zur Verfügung haben. Man kann RAM teilen mit mit anderen Tasks (gemeinsame RAM Bereiche). Es braucht keinen Platz für IO und keinen ROM Bereich in der Memory MAP eines Benutzer Task, es ist aber optional trotzdem noch möglich.

Der Benutzer Speicher ist geschützt vor Zugriffe eines anderen Benutzer Task. Alles Speicherbereiche des OS und die IO Bereiche sind geschützt vor den Benutzer Tasks.


Spezielle Funktionen der MMU

Durch spezielle Steuersignale von der CPU erkennt die MMU automatisch einen Reset, einen Interrupt (IRQ) oder einen SWI Befehl. Der Task Wechsel ist ein sensibler und komplexer Vorgang. Durch die Änderung der Speicher MAP ändert sich ja unter Umständen gänzlich alles, auch der Stack und User Stack liegt plötzlich an einer ganz anderen physikalischen Adresse. Die MMU zählt CPU Takte, damit die Umschaltung der Speicher MAP immer an dem exakt definierten Zeitpunkt statt findet.

Der Wechsel zum System Task #0 erfolgt voll automatisch. Die CPU sichert die Register noch in der User MAP und fetched die Vektoren bereits in der System MAP. Dann wird der Code des OS bzw. einer Modul (Hardware Treiber) ausgeführt. Die Rückkehr zum User Task erfolgt in der Regel durch ein RTI. Da muss der RTI Befehl noch aus der System MAP gelesen werden, die Rücksicherung der Register muss aber bereits vom Stack des Benutzer Task erfolgen. Der Zeitpunkt des Task Wechsel in der MMU ist sehr sensibel. Zum Glück übernimmt das NitrOS9 diese Aufgabe.


Der Schutz des OS vor Benutzer Code und der Schutz des Benutzer Code vor anderem Benutzer Code erfolgt nur durch das Paging. Der Schlüssel dazu ist die Konfiguration der MMU. Deshalb kann die MMU Konfiguration nur verändert werden durch "privilegierten Code". Die MMU Register sowie der Paging RAM können nur verändert werden, wenn der Task #0 aktiv ist. Mit anderen Worten, für DMA und Benutzerprogramme ist die MMU unsichtbar.

Nach einem Reset ist die MMU in einem speziellen Modus. Die Adressleitungen PA11 bis PA20 sind high, daher muss das Start ROM im oberen Ende des physikalischen Adressraum liegen. Da liegen auch die MMU Register und der MMU RAM. Bei der NitrOS9 Platine liegt die MMU an der Adresse 1FFF00 bis 1FFF7F (128 Bytes). Es ist egal ob die MMU Register sichtbar sind oder nicht, in diesem Adressbereich ist das ROM immer ausgeblendet.

Selbst wenn es einem Benutzer Programm gelingt, die Page 1023 einzublenden und so Zugriff auf den Adressen Bereich 1FFF00 bis 1FFF7F zu erlangen, kann das Programm die MMU nicht zugreifen (MMU ist unsichtbar).

Die MMU Hardware ist wasserdicht, der Speicher ist perfekt geschützt. Nur wenn das OS einen Zugriff erlaubt, hat das Benutzerprogramm einen Zugriff. Die Schwachstelle ist also immer das OS, eine Schadsoftware könnte aber theoretisch Fehler im Systemcode nutzen. Im Normalfall läuft der Benutzer Code in einer sichern Blase, quasi eine virtuelle Umgebung. Es läuft in seiner virtuellen Speicher Welt, die das OS eingestellt hat, und kommt nicht heraus.

Das Konzept mit der MMU geht schon in die Richtung, die beim PC erst seit dem Intel 386 funktionieren. Der Intel Prozessor ist natürlich 16/32 Bit breit, und hat das ganze Paging voll integriert in der CPU. Aber im Grunde gab es das schon Jahre vorher.


Start Sequenz

Nach einem Reset fetched die CPU den RESET Vektor von der logischen Adresse $FFFE und führt den Code aus. Die MMU ist nach einem RESET in einem speziellen Modus. Die Adressleitungen PA11 bis PA20 sind high, daher wird der Reset Vektor gelesen von der physischen Adresse $1FFFFE. Es läuft privilegierter Code, die MMU Konfig Register sind in der Page 1023 sichtbar.

Das erste was die CPU nun zu tun hat, ist die Konfiguration der MMU. Sonst hat man keinen Zugriff außerhalb der Page 1023. Die MMU bekommt nun die Konfiguration unter der NitrOS9 laufen kann. Dann wird der Kern Code gestartet. Je nach Art des NitrOS9 ist entweder das gesamte OS im ROM (20K) oder nur der Kern (4K).


News

  • 19.07.2022 -- OS9 Board mit MMU-16 läuft
  • 23.05.2022 -- OS9 Board mit MMU 6829 läuft
  • 19.05.2022 -- Teil-Inbetriebnahme OS9 Board (ohne MMU)
  • 29.04.2022 -- Layout des OS9 Board
  • 13.03.2022 -- Aufbau und erste Versuche mit der ByteMachine


Downloads


Links