Autor Thema: Idee OS mit eigener Managed Sprache  (Gelesen 16572 mal)

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« am: 29. December 2010, 19:13 »
Guten Abend,
mir ist so eben die Idee gekommen einen Kernel zu entwickeln der eine eigene Interpretersprache unterstützt, welche an Assembler vom Befehlssatz angelehnt ist. Auf realen Register wird bei der Sprache verzichtet, stattdessen müsste man virtuelle bereitstellen.

Sinn der ganzen Sache wäre nur den Kernel in C und Asm zu schreiben und den rest in dieser Interpretersprache... Man könnte das laufende System einfach pausieren und den Managed Bytecode anpassen und dann weiterlaufen lassen. Aber die wirklichen Vorteile sehe ich in der Sicherheit und in der Portierbarkeit des Systems, man müsste für einen anderen Prozessor z.B. ARM nur den Interpreter anpassen.

Das sind nur mal so die groben Ideen, klar perfekt ist es nicht, aber vll. Habt ihr weitere Anregungen oder Kritik.

Gruß
Remake

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 29. December 2010, 19:39 »
Schau dir mal Android an, das ist ein Linux-Kernel, in dem eine Java-Implementation läuft; das Android-System selbst ist in Java geschrieben. Der Unterschied zu realem Java ist, dass du bei Java-Bytecode eine stackbasierte Architektur hast, die sich schlecht auf reale CPUs mappen lässt, darum hat Android die Dalvik-Architektur, das ist registerbasierter Bytecode.

Im Prinzip baust du einen System-Emulator als Kernel; ob das mit den Treibern so einfach hinhaut, kann ich nicht einschätzen. Der wahrscheinlich beste Ansatzpunkt wäre, die Dalvik-Maschine auf bare Hardware zu portieren.

Probleme sehe ich insbesondere in der Performance, aber ich glaube, das weißt du sicherlich auch selbst. ;-)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 29. December 2010, 20:23 »
Wenn man es richtig macht, sehe ich in der Performance keine Probleme. Die Interpretersprache darf man dann natürlich nicht wörtlich nehmen, sondern muss einen JIT-Compiler oder so hernehmen. Vorteil ist, dass man sich den ganzen Aufwand für Speicherschutz sparen kann, weil der in die Sprache/VM schon eingebaut ist - also keine Kontext- und Ringwechsel, alles kann sicher im selben Speicherkontext in Ring 0 laufen.

Einfach mal zwischendurch den Kernel neukompilieren und Teile austauschen wird natürlich schwierig,weil es ja immer auch ein paar nicht ganz unwichtige Daten gibt, die den Wechsel überleben müssen - und das, obwohl die Datenstrukturen möglicherweise geändert worden sind. Vermutlich nicht ganz so einfach. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 29. December 2010, 20:31 »
Abend und danke für die schnelle Antwort.
Ja,... Performance ist klar, das ein Interpretiertes Programm langsamer ist als ein Natives. Doch bei der heutigen Rechenpower bzw. wenn man sieht was mit Interpretersprachen so möglich ist, wenn der Interpreter gut optimiert ist... siehe JavaScript im Chrome mit der V8 Engine...

Problem sehe ich ähnlich wie du bei den Treibern, eventuell müssten diese weiterhin in C/ASM geschrieben sein.

Auch wenn es einen tick langsamer durch den Interpreter läuft, bleibt weiterhin der Vorteil, dass das OS in einer Art Sandkasten läuft bzw. vor Bufferoverflows usw. geschützt wäre... Eventuell bekommt man am Ende kein Betriebssystem für Hardcore Gamer heraus, was eh unrealistisch ist... aber was realistisch klingt wäre ein stabiler Kernel den man mit managed code füttern kann und ein kleines stabiles OS bieten könnte.

Gruß
Remake

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 29. December 2010, 20:38 »
Wenn man es richtig macht, sehe ich in der Performance keine Probleme. Die Interpretersprache darf man dann natürlich nicht wörtlich nehmen, sondern muss einen JIT-Compiler oder so hernehmen. Vorteil ist, dass man sich den ganzen Aufwand für Speicherschutz sparen kann, weil der in die Sprache/VM schon eingebaut ist - also keine Kontext- und Ringwechsel, alles kann sicher im selben Speicherkontext in Ring 0 laufen.

Einfach mal zwischendurch den Kernel neukompilieren und Teile austauschen wird natürlich schwierig,weil es ja immer auch ein paar nicht ganz unwichtige Daten gibt, die den Wechsel überleben müssen - und das, obwohl die Datenstrukturen möglicherweise geändert worden sind. Vermutlich nicht ganz so einfach. ;)

Ah ja JIT wäre auch eine Idee, aber zuerst würde ich das mit einen stabilen Interpreter probieren, optimieren kann man später immer noch ;-)

Ja der Kernel sollte schon sehr stabil und so minimal wie möglich sein... Das meiste in bytecode der im laufe des OS geändert werden kann... Also ein OS das während der Laufzeit verändert und debuggt werden kann. Ich glaube das wäre sehr interessant. Im Debug Modus sollte wirklich das komplette OS pausieren und nur Debugger und einen Codeeditor anzeigen, wo man während der laufzeit änderungen vornehmen kann... Kann mir vorstellen, das dies auch viel zur Sicherheit beiträgt, wenn der Benutzer direkt sehen kann was der Rechner alles macht.

Gruß
Remake

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 29. December 2010, 20:55 »
Naja, ich schätze mal, ein JIT ist nicht nice to have, sondern Pflicht. Die modernen JavaScript-Engines, die du als Beispiel nennst, sind auch längst keine Interpreter im klassischen Sinn mehr. Was für eine Performance du von einem reinem Interpreter zu erwarten hast, kannst du dir anschauen, indem du mal ein Linux in bochs bootest. Macht keinen Spaß.

Mit dem Ändern zur Laufzeit - wie gesagt: Wie gehst du mit geänderten Datenstrukturen um? Nehmen wir mal an, du hast ein neues Feld in eine Struktur eingefügt, die eine Page beschreibt. Die Daten der Speicherverwaltung beibehalten musst du auf jeden Fall, sonst kriegst du sehr schnell ein Problem.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 29. December 2010, 21:20 »
So viele Gedanken wegen der Datenstruktur habe ich mir noch nicht gemacht.
Das sind alles erstmal nur grobe Gedanken...

Das später ein JIT Pflicht ist, ist klar.. aber für die ersten Tests sollte ein Interpreter ausreichen ;-) Und dann wird optimiert, ähnlich wie Google es macht, dort wird auch nachträglich V8 immer weiter optimiert.

Ja klar Bochs ist lahm, aber das auch ein kompletter Computer Emulator...
Aber Interpretersprachen wie PHP sind Performance mäßig auch akzeptabel ;-)


Gruß
Remake

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 29. December 2010, 22:04 »
Was die Datenstrukturen betrifft, spreche ich ja auch nicht von irgendeiner konkreten Datenstruktur. Aber du wirst definitiv den Fall haben, dass du einen Kernelteil austauschen willst, der im Moment irgendwelche Datenstrukturen benutzt, die erhalten bleiben müssen. Bei der Speicherverwaltung ist es ganz offensichtlich, denn ansonsten weißt du nicht mehr, welcher Speicherbereich frei ist und welcher nicht. (Das Beispiel ist gleichzeitig auch blöd, weil die Speicherverwaltung in der VM stecken wird und nicht im Managed Code ;)) Zum Beispiel Hardwaretreiber haben aber in der Regel auch irgendeinen Zustand, der erhalten bleiben muss.

An dieser Stelle musst du dir halt überlegen, wie du es hinkriegst, dass eine Struktur zwar in der neuen Version verändert wird, dass aber gleichzeitig die Daten im Speicher weiterbenutzt werden können. Vielleicht musst du an dieser Stelle transparent irgendwas konvertieren. Darüber würde ich mir Gedanken machen, wenn du das mit dem Austauschen ernst meinst, denn das halte ich für ein zentrales Problem.

Zur Geschwindigkeit von Interpretern wie PHP: Bist du sicher, dass es heute noch ein Interpreter ist? Aber abgesehen davon, zumindest in älteren Versionen war es auch so, dass man deutlich gespürt hat, wenn ein rechenaufwendigere Algorithmus in PHP implementiert war. Einigermaßen schnell wird es erst dadurch, dass für vieles die Standardbibliothek benutzt wird, die in C geschrieben ist. Genau das willst du bei deinem OS natürlich so weit wie möglich vermeiden, sonst schenkst du die ganze Sicherheit wieder her.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 29. December 2010, 22:16 »
Ja genau, so weit wie möglich sollte auf C verzichtet werden.
Naja, dass ganze war jetzt erstmal nur eine grobe Idee, ich muss das ganze noch mal ein paar Tage im Kopf auswachsen lassen und schauen was das Ergebnis meiner Überlegung dann sein wird.

Vielleicht habt ihr noch Ideen oder Anregungen?
Oder habt Tipps für die Umsetzung?

Gruß
Remake

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 29. December 2010, 22:30 »
Naja, das ganze ist ein Projekt in einer Größe, wie es wahrscheinlich die wenigsten von uns schon umgesetzt haben. Statt "einfach" nur einem OS baust du gleichzeitig noch eine Programmiersprache, einen Compiler und eine VM. Das sind alles Dinge, die jede für sich sauber geplant sein sollten, wenn die Komponenten am Ende zu einem lauffähigen System zusammenspielen sollen und du nicht irgendwann feststellen willst, dass dein Design manche Features (wie z.B. das Austauschen von Modulen zur Laufzeit) gar nicht hergibt.

Anfangen würde ich erstmal bei der Spezifikation der Sprache (kannst du auch gern mal hier herzeigen, da werden sicher einige drüberschauen und Kommentare abgeben). Anschließend wahrscheinlich den Compiler unter einem existierenden OS, also z.B. Linux schreiben. Teilweise parallel dazu die VM anfangen und ebenfalls unter Linux testen, aber darauf acht geben, dass sie portabel geschrieben ist, so dass du sie später ohne größeren Aufwand in deinen Kernel einbauen kannst. Und erst dann, wenn das alles halbwegs tut, würde ich tatsächlich mit dem klassischen OS-Dev-Teil anfangen und den Kernel bauen, die VM draufsetzen und einen ersten Hello-World-Treiber in deiner Bytecode-Sprache schreiben.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 29. December 2010, 22:40 »
Es gibt schon sowas, kannst du ja mal als Anregung nutzen:

https://github.com/mosa/MOSA-Project

Die haben nen eigenen C# Compiler geschrieben, ob das jetzt alles in einer VM läuft weiß ich nicht mehr. Jedenfalls ist managed code.

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 29. December 2010, 23:04 »
Ja C# ist mir schon wieder ein tick zu weit von der Hardware entfernt. Naja ich werd mir die Tage mal einen kleinen Befehlssatz usw. einfallen lassen und davon hier berichten. Eine Compiler werde ich wohl in c++ zusammen mit qt schreiben, damit es leichter zu Portieren ist ^^ wird wohl eine Asm ähnliche Sprache, aber auch Basic Sprachen sollte man leicht zu diesem bytecode compilieren lassen. Muss mir das ganze mal morgen nach Feierabend anschauen und schauen was ich da zu Stande bekomme.

gruß
Remake

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 30. December 2010, 09:25 »
Guten Morgen,
hab gerade mal einwenig im Zug an der Idee gearbeitet. Was dabei heraus kam ist folgendes. Die Programmiersprache soll Anlehnungen an Assembler, Basic und BrainFuck haben. Der Interpreter soll ähnlich wie ein Brainfuck interpreter in C programmiert sein oder wie eine einfache Virtuelle Maschine (einfach mal in den Bochs Quelltext hineinschauen).

Es soll eine Art managed Assembler entstehen das in einer VM läuft und Basic ähnliche befehle bietet.

Hab mir überlegt verschiedene Virtuelle Register mit unterschiedlichen größen bereit zustellen, aber eventuell sollte ich diese Idee verwerfen... das sollte vll. doch die VM alles lösen.

Hier meine groben Überlegungen zu der Bytecodesprache:

;register
0x00 to 0x09 10x 8  bit register
0x10 to 0x19 10x 16 bit register
0x20 to 0x29 10x 32 bit register
0x30 to 0x39 10x 64 bit register


;relational operator
0x00 >
0x01 <
0x02 >=
0x03 <=
0x04 ==
0x05 !=



;managed bytecode
0x00 close programm
0x01 to 0x10 reserved
0x11 add (register, value)
0x12 sub (register, value)
0x13 mul (register, value)
0x14 div (register, value)
0x15 inc (register)
0x16 dec (register)
0x17 mov (register, egister)
0x18 for (operator, register"value left", register"value right", register"step")
0x19 endfor
0x20 if (operator, register"value left", register"value right")
0x21 elseif (operator, register"value left", register"value right")
0x22 else
0x23 endif

Beispiele:

IF reg0 >= reg1 THEN ... ENDIF
{0x20, 0x02, 0x00, 0x01, ..., 0x23}

FOR reg0 < reg1 STEP reg2 ... ENDFOR
{0x18, 0x01, 0x00,0x01,0x02, ..., 0x19}



Gruß
Remake

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 30. December 2010, 10:35 »
Morgen nochmal,
eventuell sollte ich die virtuellen Register rauswerfen und lieber eine Möglichkeit einbauen um Variablen mit Typen zu deklarieren. Somit könnte wie VM ordentlich den Arbeitsspeicher Managen... und es gäbe keine 32 bzw. 64 bit probleme bzw. keine unterschiede bei der Programmierung (außerhalb des Kernels).

Mit dem Befehlssatz von Post vorher sollte sich schon ein einfaches Basic realisieren lassen das zu diesen Managed Bytecode kompilieren kann... Was klar fehlt sind String, Text sowie Grafikausgabe. Da bei diesen Managedcode kein direkter zugriff auf dem Speicherstatt finden soll, muss ich mir noch eine Art und Weise ausdenken wie man methoden implementieren könnte.

So das die Kernel funktionen usw. per methode irgendwie aufgerufen werden kann.

Gruß
Remake

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 30. December 2010, 10:55 »
Nichts für ungut, aber dieser "Sprache" fehlt alles interessante. In vierzig Registern kriegst du unmöglich die gesamten Daten unter. Zumindest sowas wie Arbeitsspeicher wäre als Konzept noch ganz nett. Nächstes Problem ist, dass Integer zwar ein nützlicher Datentyp sind, aber eigentlich will man auch anderes haben, insbesondere Strukturen und Arrays. Du hast keinerlei Möglichkeit, Funktionen zu repräsentieren, außer du inlinst sie komplett (was irgendwie den Zweck einigermaßen verfehlt).

Ein Opcode für endif ist auch gelinde gesagt merkwürdig - das würde ja bedeuten, dass die VM den Code beim Ausführen erstmal aufwendig parsen muss. Es hat seinen Grund, warum richtige Architekturen keine if- und endif-Instruktionen sondern bedingte und unbedingte Sprünge haben. Deine Vergleichsoperatoren mappen auch schlecht auf die des Hosts, aber das ist dagegen fast schon ein Detail.

Wie du damit zur Laufzeit Code ersetzen können willst, ist mir ein Rätsel.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 30. December 2010, 11:46 »
Zitat
Nichts für ungut, aber dieser "Sprache" fehlt alles interessante. In vierzig Registern kriegst du unmöglich die gesamten Daten unter. Zumindest sowas wie Arbeitsspeicher wäre als Konzept noch ganz nett.

Ach quatsch xD Sowas nimm ich doch nicht böse auf ;-) Du hast ja auch Recht mit deinen Aussagen, wie in meinem letzten Post schon gesagt sollte ich die Idee mit den Virtuellen Registern verwerfen und stattdessen variablen mit Typen integrieren die von der VM verwaltet werden.

Ja, wegen funktionen muss ich mir noch genau Gedanken machen, da habe ich etwas im Kopf aber das ist noch total unausgereift. Aber mit dem funktionen Mechanismus soll man dann auch mit dem Kernel/Hardware kommunizieren.

Ja, ein Opcode für if/endif usw. ist merkwürdig hat in meiner Überlegung seinen Sinn und wüsste auch schon wie man dies gut umsetzen könnte.


kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 30. December 2010, 12:47 »
Magst du das mit if/endif mal näher erläutern? Also sowohl wozu du es brauchst als auch wie du es effizient umsetzen willst?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 30. December 2010, 13:24 »
Also if/endif usw. finde ich ganz nützliche Befehle, und da alles eh von einer VM interpretiert wird gibt es weniger gründe es weg zulassen als gründe es einzubauen.
Kann mir vorstellen das wenn die Bytecode sprache diese Befehle schon unterstützt es einfacher ist dafür eine Hochsprache zu entwickeln.

Hab mir nochmal Gedanken bezüglich Methoden und Variablen gemacht...
Das ist der erste Entwurf..
;managed bytecode
0x24 Variable deklarieren
0x25 Methode deklarieren
0x26 End Methode

;Datentypen
0x01 byte
0x02 int
0x03 float
0x04 string
usw. usw...


;Eine Variable vom Type Byte mit der ID 1 deklarieren
0x24(opcode) 0x01(Datentype) 0x01(id)

;Eine  Variable vom Type Byte mit der ID 257 deklarieren
0x24(opcode) 0x01(Datentype) 0xFF(id) 0x01(id)

;Eine Methode mit der ID 1 deklarieren, welche ein Byte als Rückgabewert liefert
;Parameter könnte man über einen Stack der Methode mit geben
0x25(opcode) 0x01(Datentype 0x01(id) ... 0x26(opcode)
« Letzte Änderung: 30. December 2010, 13:26 von remake »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 30. December 2010, 14:08 »
Das was du dir da ausdenkst, ist kein Bytecode, sondern einfach eine Kodierung von Quelltext mittels Zahlen. Dein Compiler wäre dann nichts anderes ein Komprimierer.

Vielleicht solltest du dir mal anschauen wie Java und .Net funktionieren.
Dieser Text wird unter jedem Beitrag angezeigt.

remake

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 30. December 2010, 14:40 »
Zitat von: Wikipedia Bytecode
Der Bytecode ist in der Informatik eine Sammlung von Befehlen für eine virtuelle Maschine. Bei Kompilierung eines Quelltextes mancher Programmiersprachen oder Umgebungen – wie beispielsweise Java – wird nicht direkt Maschinencode, sondern ein Zwischencode, der Bytecode, erstellt. Dieser Code ist in der Regel unabhängig von realer Hardware und im Vergleich zum Quelltext oft relativ kompakt.
Ansonsten wäre es nett mir zu erklären wo du den Unterschied siehst!?

Die Hochsprachen die später zu diesen Bytecode kompilieren sollen sehen ganz anders aus, bzw. gibt es nicht für alles einen Opcode, so dass bestimmte Befehle und auch spätere Objekt Orientiertung irgendwie anders und komplexer im Bytecode dargestellt werden.

Gruß
Remake

 

Einloggen