Schreiben eines Multitasking-Betriebssystems für einen Prozessor ohne MMU

9

Ich habe darüber nachgedacht, ein Hobby-Betriebssystem für einige der ARM-Prozessoren zu schreiben. Es gibt viele beliebte Einplatinencomputer mit ARM MPU, daher wollte ich einfach einen davon kaufen (einen mit offenerer Dokumentation auswählen). Ich war überrascht, als ich herausfand, dass selbst Boards mit wirklich genügend Speicher keine MPUs mit Memory Management Unit haben.

Da ich immer mit i386 + -Prozessoren gearbeitet habe und nie etwas anderes (außer einigen Microchip-PICs), bin ich jetzt verwirrt und nicht sicher, ob man ein funktionierendes Betriebssystem schreiben kann, dessen Funktionalität im Vergleich zu geschriebenen Betriebssystemen nicht eingeschränkt wäre für MPUs mit MMU.

Ich könnte mir nur wenige Lösungen zum "Ersetzen" oder "Simulieren" von MMU vorstellen und habe einige Fragen:

  • Auf Intel-Prozessoren im 16- und 32-Bit-Modus gibt es eine Möglichkeit, Segmente und Segmentselektoren zu verwenden, um unterschiedliche Speicherblöcke für unterschiedliche Aufgaben zu verwenden. Das bedeutet, dass ich den Speicherplatz ändern kann, indem ich den Inhalt der Segmentregister ändere, wenn ich unter x86 einen Taskwechsel durchführe. Gibt es allgemeine Konzepte für die Speichersegmentierung, die für die ARM-Architektur verwendet werden könnten?
  • Durch Laden einer verknüpften Objektdatei anstelle einer ausführbaren Datei konnte ich Verschiebungen (Korrekturen) oder positionsunabhängigen Code verwenden, um Aufgaben auf Speicherelemente zu verweisen, so als ob ich den Speicher mithilfe von Paging-Strukturen zugeordnet hätte. Wäre das effektiv genug?
  • Ich habe auch etwas über Speicherschutzeinheiten auf ARM-Prozessoren gelesen. Könnten diese hilfreich sein?

Gibt es "übliche" Möglichkeiten, Aufgaben auf Systemen ohne MMU zu verwalten?

user35443
quelle

Antworten:

16

Es ist eigentlich gar nicht so schwer, ein Betriebssystem zu entwerfen, für das keine MMU erforderlich ist. Es gibt ein paar Annehmlichkeiten, auf die Sie verzichten müssen, aber nichts Unüberwindbares.

  • Da verschiedene Aufgaben an verschiedenen Adressen geladen werden müssen, muss Ihr gesamter Code (mit Ausnahme des Kernels, der Standardbibliothek und aller anderen Codes, die Teil Ihrer Basislaufzeitumgebung sind) als positionsunabhängig kompiliert werden. Dies bedeutet relative Sprünge und eine Basisadresse für den Heap-Zugriff, die in einem Register gespeichert sind. Das Ausgeben eines Registers als Basisadresse mag kostspielig erscheinen, wenn Sie an die vier allgemeinen Register von x86-32 gewöhnt sind, aber die meisten modernen Architekturen verfügen über mehr, und sogar 8088 verfügt genau dafür über die Segmentregister.
  • Eine Unix-ähnliche Architektur muss überarbeitet werden, da Sie sie nicht implementieren können fork. Das ist in Ordnung, die meisten Betriebssysteme haben keine fork. (Sie können haben vfork.)
  • Sie können keine großen Speicherplätze vorab zuweisen, ohne auch den entsprechenden Speicher zuzuweisen. Dies bedeutet, dass der Stapel oder Haufen nicht im laufenden Betrieb wächst, indem jeweils eine weitere Seite zugewiesen wird.

Wenn Sie eine MPU haben, können Ihre Aufgaben wie in Multitasking-Betriebssystemen üblich voneinander getrennt werden. Ohne eine MPU kann die Speichertrennung nur kooperativ sein, wenn Sie zulassen, dass Aufgaben beliebigen Code ausführen. Eine Möglichkeit, eine Speichertrennung ohne MPU zu erreichen, besteht darin, Aufgaben darauf zu beschränken, nur verifizierten Code auf einer virtuellen Maschine zu verwenden und den Speicherschutz in Software als Teil der VM-Engine zu implementieren.

uClinux ist ein Projekt, das auf dem Linux-Kernel basiert und auf Prozessoren (einschließlich ARM Cortex-M) ohne MMU ausgeführt wird. Die Einschränkungen für Multitasking sind im Wesentlichen die oben beschriebenen.

Gilles 'SO - hör auf böse zu sein'
quelle