PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Heute schreiben wir ein Betriebssystem - wer macht mit?



i_hasser
12.10.2003, 03:32
Hi

Da ich schon immer recht gerne sehr nah an der Hardware geproggt habe bin ich irgendwann mal auf diese Idee gekommen... und hab irgendwann auch mal aus Spaß damit angefangen ;)

Am Anfang war es nur ein einfacher Bootsektor, der ein typisches "Hello World" ausgegeben hat ohne viel Planung dahinter, dann kamen kleine Ansätze zu einem Realmode OS (ist deutlich einfacher).

Das ist nun inzwischen ein paar Jahre her und ich hab in der Zeit immer mal wieder darüber nachgedacht, und ich denke mir sind auch recht gute Ideen dazu gekommen.
Aber ein 32bit OS allein zu machen ist ein bisschen viel ;) Abgesehen davon kenn ich mich auch net in allen Bereichen aus was den Protected Mode betrifft (bin zb. durch Paging und die LDT noch net komplett durchgestiegen) und man kann ja auch net alles wissen.

Desswegen wollt ich hier einfach mal fragen, ob wer Lust hat mitzumachen. Aber bitte nur wenns auch ernst gemeint ist.
Vorkenntinisse? Naja, also Assembler müsste man schon können, oder sich wenigstens mal angeschaut und nachvollzogen haben.

Wenn Interesse besteht einfach eine Mail schreiben: i#nte#l##_has##ser@g#m##x.net (ohne # ;))

MfG

sir_max
12.10.2003, 03:48
hört sich interesant an. dazu gleich mal ne frage. ich hab mir überlegt im nächsten symester kurse in Computer Science zu belegen. hab selber aber kein plan wo ich anfangen soll und ich kenn mich auch null mit programieren aus. wie könnte also so eine reienfolge aussehen. also womit anfangen und dann weiter machen. ich hab bereits so ein standard IT kurs (Information Communication Technology) Kurs gemacht. so nen allgemeiner IT Kurs. würde mich aber interessieren mehr programmieren zu können.

i_hasser
12.10.2003, 04:27
ist zwar jetzt etwas OT, aber was solls ;):

Willst du programmieren lernen oder verstehen?

Ist eine wichtige Frage dabei. Wenn du es nur lernen willst, es gibt genug C/++ Tutorials im Netz.

Das Verstehen, was dabei abläuft etc ist aber finde ich die schönere Sache. Da geht es zwar erstmal relativ Praxisentfernt zur Sache, aber danach weist du, was programmieren bedeutet, was unten drunter passiert etc.

Da solltest du dir erstmal ein bisschen Assembler anschauen. Du musst da nicht Assembler können, sondern das Prinzip verstanden haben. Dazu vielleicht auch noch was über den RealMode, der ist schön einfach und von der Funktionsweise her ist der Weg zum Protected Mode nicht weit.

Nun gehts erstmal zu den einfachen Hochsprachen, zb. wäre da Turbo C (1.0 gibts kostenlos) interessant. Vor allem weil du damit Binärdateien erzeugen kannst, die du später wieder disassemblieren kannst -> so sieht ein Hochsprachenprog in Assembler (also letztendlich für die CPU) aus.

Dann vielleicht ein bisschen was über Betriebssystemarchitektur - DOS ist zwar einfach, bietet aber auch einen guten Einstieg (und mehr brauchste net ;))

Dann weist du so ungefähr, wie die Dinge funktionieren, was du brauchst etc.

Jetzt geht das eigentliche Programmieren los, dazu zählt objektorientiertes Proggen etc......



Der Vorteil ist, dass du dann auch noch nachvollziehen kannst wie nun zb. deine Klasse die du in C++ erstellt hast in Assembler realisiert wird. Und Zeiger werden dir dann bestimmt keine Probleme bereiten ;)

Der Nachteil ist eben, dass du am Anfang relativ wenig sehen wirst. Aber wenn du ein bisschen über Assembler weist kannst du relativ schnell zb. einen Bootsektor schreiben der eine Meldung ausgibt und solche Sachen, das funktioniert ganz unten drunter eben ohne irgendwelche vorgefertigten Funktionen.



Ansonsten können wir ja auch per Mail weiterquatschen, da kann ich dir noch ein bisschen was dazu erzählen.

TiKu
12.10.2003, 04:41
Es geht auch ohne Assembler.;) Ich habe mir zum Beispiel das Programmieren erst mit dem Basic-Dialekt meines Taschenrechners und später auf'm PC mit Visual Basic beigebracht.
Es kommt drauf an was man später mal vorrangig programmieren möchte. Wenn man hauptsächlich Anwendungsprogramme schreiben will, ist die Assembler- und DOS-Geschichte im Grunde Zeitverschwendung. Viel wichtiger ist da, dass man die "Innereien" des jeweiligen Betriebssystems kennt. Geht man mehr Richtung Hardware (Treiberprogrammierung, Betriebssystementwicklung, High-Performance-Sachen wie Videobearbeitung), hast Du natürlich Recht, da ist es doch ganz hilfreich, wenn man Assembler kann und weiß wie die Hardware funktioniert.

sir_max
12.10.2003, 09:46
super danke...auch wenn das alles noch alles bahnhof fuer mich ist. ich wuerde es auch gerne lernen. womit waere also gut an zu fangen.

hier die moeglichkeiten:
QUOTEPROGRAMMING LOGIC
DATA STRUCTURES WITH C++
DATA STRUCTURES WITH JAVA
VISUAL BASIC .NET PROGRAMMING
Visual Basic .Net
DATABASE PROGRAMMING IN VISUAL BASIC.NET
C# PROGRAMMING
FORTRAN PROGRAMMING
OPERATING SYSTEMS
This course provides a functional understanding of operating systems. Topics include key hardware architecture concepts, computer interfaces, file systems, multiprogramming, resource management, and virtual memory. DOS and UNIX are used to demonstrate operating system internals, commands, and batch/shell programming languages.
C PROGRAMMING
JAVA PROGRAMMING
DATABASE CONCEPTS AND APPLICATIONS
This course provides an introduction to modern database concepts, emphasizing the relational database model. Topics include design methodologies, normalization of tables, referential integrity, SQL, security, and event driven programming. Principles are applied by performing exercises using Microsoft Access.
MICROSOFT SQL SERVER DATABASE
ORACLE PROGRAMMING
und weiter web-programming courses.

einiges kann ich nun schon verstehen, aber ich weiss nicht wie nuetzlich es waere z.b. zuerst java zu lernen oder gleich C. Was meinst du eigentlich mit assembler ???

projekt hoert sich gut an. das waere etwas fuer die naechsten jahre....

i_hasser
12.10.2003, 13:57
Da würd ich einfach mal bei Operating Systems reinschauen.

Auch wenn du später Datenbankanwendungen oder Spiele schreiben willst ist es nie schlecht zu wissen was unten drunter abgeht.
Und durch Assembler lernst du, was du eigentlich alles umsetzen kannst - was in Assembler net geht, geht auch in sämtlichen Hochsprachen nicht.

PS Will hier keiner bei einem OS mitmachen?


PPS @sir_max Wenn du privat erstmal ein bisschen anfangen möchtest schau dir mal Dev-C++ an - kostenloser port vom Gnu C Compiler zu Windoofs, da kannst du auch erstmal konsolenanwendungen schreiben bei denen du recht wenig drumherum wissen musst.

aths
12.10.2003, 22:46
Original geschrieben von intel_hasser
Vorkenntinisse? Naja, also Assembler müsste man schon können, oder sich wenigstens mal angeschaut und nachvollzogen haben. Imo sollte ein Betriebssystem vorwiegend in C (oder C++) geschrieben werden. Die Verbreitung von Lowlevel-Sprachen geht zum Glück immer weiter zurück.

Sir Ulli
12.10.2003, 23:02
ich hätte hier was, MMIX 2009 (http://www-cs-faculty.stanford.edu/~knuth/mmix.html)

ist allerdings bei einem Schwierigkeitsgrad von 1-10 auf Stufe 15 einzuordnen.

MFG
Sir Ulli

i_hasser
12.10.2003, 23:07
@aths

Klar, und ich habe auch nicht vor großartig Assembler zu nehmen.
Höchstens der Header für den Multiboot-kompatibelen Kernel wird in Assembler gemacht, aber das sind nur ein paar Zeilen - der Rest in C/++.

Allerdings müssen einige Dinge der Speicherverwaltung in Assembler gemacht werden, und ich denke der Speichermanager nutzt auch noch segmentierung (damit wird das zwar theoretisch ein reiner x86 Kernel, aber andererseits gehören Buffer Overflows damit der Vergangenheit an und man kann alles wirklich gut voneinander trennen).

Assembler muss man trotzdem können, zumindest in den Anfangsstadien - sonst versteht man einfach net was unten drunter abläuft. In C++ bekommst du zb. rein garnix von den einzelnen Segmenten mit, aber genau das ist gleich wieder ein komplexes Thema mit dem man sich gleich Anfangs auseinandersetzen muss (-> Speichermanager).

TiKu
12.10.2003, 23:12
Hmmm, verlockend klingt das ganze ja schon. Aber ich habe weder die Zeit noch ausreichende Kenntnisse, um an einem OS zu schreiben. Aber melde Dich später mal, wenn Du jemanden suchst, der für die GUI (ich hoffe, es wird eine geben;)) so Standardcontrols wie TreeView, TextBox usw. schreibt.

default-X
12.10.2003, 23:19
und wehe das OS wird nich OGL 2.0 fähig ;D

edit:
*hust* und das ganze biddä in 64bit 8)

Psycho-Dad
12.10.2003, 23:19
Ich könnte höchstens meine höchst unzulänglichen PERL Kenntnisse anbieten ;D. Na Intel_Hasser ein Interessantes Projekt ist es ja und selbst wenn daraus nicht das nächste grosse Super BS wird zum verstehn wie ein Computerfunktioniert ist es bestimmt toll.

Heute bei P3D "Wie schreib ich mir mein eigenes BS" ;-)

CU
P-D

i_hasser
13.10.2003, 00:23
Na das OS wird erstmal ganz einfach ;D

Das soll erstmal rein:
-> Prozessverwaltung (hier sind mir ein paar wie ich finde wirklich sehr gute Ideen gekommen, das enthält auch gleich sowas wie Treiberverwaltung etc)
-> Speichermanager (bestehend aus so ca. 5 Komponenten)
-> Video Treiber (Textmodus, nix besonderes)
-> Tastaturtreiber
-> eine einfache Konsole

Und damit würde das erstmal halbwegs laufen. Das ganze soll als 100%iger µ-Kernel entstehen, das bedeutet, dass der Kernel komplett aus Modulen besteht, und die Treiberverwaltung (oder wie auch immer Verwaltung, da kommen Treiber, Anwendungen und Dienste rein) hätte einen entscheidenden Vorteil: Nix da mit ein Modul für eine Kernel-Version, da würden alle Module immer laufen - sowas wie eine kernelversion gibt es nicht mehr weil eben der gesamte Kernel eine Sammlung von einzelnen Modulen ist.

Dazu würde die Treiberverwaltung auch noch ein paar andere Vorteile bieten, so könnte man problemlos ein wirklich gutes Multitasking realisieren. Gleichzeitig wären die einzelnen Komponenten wirklich getrennt.

Na mal sehen, ob ich das so auf die Beine bekomme. Bin halt im Protected Mode noch nicht Fit genug, da muss ich noch etwas Lektüre lesen.


Ach ja, übrigens werden alle Prozesse etc. nicht wie bisher üblich in Ringe einsortiert (so ist es zumindest bei OS/2 und Windoofs, bei Linux wird es ähnlich sein) sondern das ist alles in einem sehr verästeltem Baum organisiert.

sir_max
13.10.2003, 08:41
noch ein paar fragen:
wird alles in C/++ geschrieben. also auch treiber?

wie wichtig ist mathematik fürs programieren. ich mach zwar mathe ganz gerne, aber meine stärke ist das nicht. zur zeit bin ich einem finite math kurs. sachen wie wahr/falsch aussagen, linear programming und statistik.

würde es ein unterschied machen, das betriebsystem auf einem z.b windows, mac oder linux OS zu schreiben und aus zu probieren....logischer weise doch nicht ???

ist ja alles so spannend...kann es gar nicht erwarten bis zum nächsten symester, wenn ich mein (wahrscheinlich) OS und C kurs mache. ;D

TiKu
13.10.2003, 09:41
Original geschrieben von sir_max
noch ein paar fragen:
wird alles in C/++ geschrieben. also auch treiber?Meinst Du generell oder nur bei intel_hasser's OS? Treiber werden meistens in C/C++ geschrieben, das heißt aber nicht, dass es nur mit C/C++ möglich ist.


wie wichtig ist mathematik fürs programieren. ich mach zwar mathe ganz gerne, aber meine stärke ist das nicht. zur zeit bin ich einem finite math kurs. sachen wie wahr/falsch aussagen, linear programming und statistik.Mein Informatik-Studium besteht zum größten Teil aus Mathe. Zum Programmieren sehr wichtig sind Mathe und ein gutes Logikverständnis.


würde es ein unterschied machen, das betriebsystem auf einem z.b windows, mac oder linux OS zu schreiben und aus zu probieren....logischer weise doch nicht ???Schreiben: Nö, eigentlich nicht. Man programmiert ja jeweils ein fremdes OS - egal ob unter Windows, Linux oder Mac. Da sollte es ziemlich egal sein, was man nimmt. Zum Testen nimmt man wahrscheinlich anfangs eh eine Virtual Machine. Von daher müsste auch beim Testen das Host-OS egal sein.

i_hasser
13.10.2003, 18:35
Früher hab ich die OSs mit VMWare emuliert, das ist mir aber ein bisschen zu klobig - jetzt nehm ich Bochs (freeware PC Emulator für viele OSs, da laufen auch so ziemlich alle GastOS).

Letztendlich wird das OS praktisch komplett in eine Hochsprache entstehen. Zur Kommunikation mit den einzelnen Treibern wird es festgelegte Protokolle geben, daher auch die Unabhängigkeit von irgendwelchen Versionen. Der Vorteil ist eben die strikte Abkapselung, man kann hier mit C/++, da mit zb. Pascal, dort mit Java etc programmieren... ich selber werd aber nur C/++ nutzen (wer kommt schon auf die Idee ein OS in Pascal zu schreiben ;)).


Ob man Mathe braucht kommt drauf an, was man programmiert. Aber die Logik darf eben nie fehlen ;)
Ich hab vor einer Weile mit einem Image Editor angefangen (hab ich inzwischen aber auf Eis gelegt, weil ich auf Linux umgestiegen bin, sry@TiKu aber vll mach ich den irgendwann ja mal weiter - das Konzept kannst du von mir aber gerne haben, ist sehr modular aufgebaut), da braucht man so ziemlich 0 Mathe.
Wenn man dagegen irgendwas mit Graphik macht (und sei es nur ein einfacher 2D-Weltraumshooter wie Asteroids) braucht man recht viel Mathe.

Dann gibts da natürlich noch andere Bereiche wo Mathe nicht fehlen sollte.


Also in der Regel braucht man direkt Mathe nicht, aber in nicht seltenen Gebieten kommt man ohne nicht aus.

Chilli999
18.10.2003, 06:01
Hi würde mich auch dazu bereit erklären mitzumachen zudem ich im moment seeeehhhrrr viiielll zeit habe nur leider weiss ich auch nicht wo ich anfangen soll da ich mich mit solchen dingen wie programmieren nie befast habe obwohl mir das thema schon seit einigen jahren unterm nagel brennt wo fange ich an währe es sinvoll mit Visual Basic anzufangen?

Kannst ja mal ne pm schicken mit adressen wo man sich schlau machen kann die auch nicht so schwer zu verstehen sind


Jeder fängt mal klein an, ja aber wenns fertig ist dann .........

TiKu
18.10.2003, 13:45
Sorry, aber ohne Grundkenntnisse mit einem OS anzufangen geht schief. Wenn man nicht wenigstens 3 Jahre sich intensiv mit der Materie Softwareentwicklung auseinandergesetzt hat, braucht man IMHO nicht mit einem OS anfangen. Ein OS ist "etwas" komplizierter als "Hello world!"
Ich glaube, intel_hasser hat sich eher an die "alten Hasen" hier gewendet.

EDIT: Mit VB anzufangen ist prinzipiell sinnvoll. Allerdings wird VB in seiner bisherigen Form nicht mehr weiterentwickelt. Von daher empfehle ich, beizeiten auf C#, C++, Visual Basic .net, Delphi oder Java umzusteigen.

i_hasser
19.10.2003, 15:38
Original geschrieben von TiKu
Sorry, aber ohne Grundkenntnisse mit einem OS anzufangen geht schief. Wenn man nicht wenigstens 3 Jahre sich intensiv mit der Materie Softwareentwicklung auseinandergesetzt hat, braucht man IMHO nicht mit einem OS anfangen. Ein OS ist "etwas" komplizierter als "Hello world!"
Ich glaube, intel_hasser hat sich eher an die "alten Hasen" hier gewendet.

Genau.
Ich überleg jetzt auch schon 3 Jahre ein kleines OS zu schreiben, aber ich programmiere schon viel länger - trotzdem gingen die ersten Versuche vorn Baum. Das Problem ist auch, dass man am Anfang viel zu schnell was sehen will - im Realmode ist das noch halbwegs verzeihlich (immerhin hat es DOS ja auch lange geschafft *chatt*), bei einem Protected Mode OS braucht man erst garnet anfangen. Da merkst du dann auch, ob du wirklich ein OS schreiben willst oder ob es nur mal eben interessant klang - wenn ja fängst du immer wieder an darüber nachzudenken, selbst wenn du schon länger nichts mehr direkt programmiert hast. So ist mir auch ein großteil vom Design eingefallen, hier und da mal was aufgeschnappt oder eine Inspiration bekommen und das dann weitergedacht - nur sollte man sich das alles irgendwo aufschreiben, weil man es sonst schnell wieder vergessen hat.

Dj_Ninja
20.10.2003, 02:27
ist die frage, was das os können soll. was großes nützliches wird wohl nur im team gehen. spielereien wie 'nen bootsektor a la "das ist MEINE diskette" hab ich auch gemacht, auch probeweise ein os angefangen (funktionierte auch ganz gut), aber da sowas mit nichts kompatibel ist habe ich damit wieder aufgehört. meine, wenn ich dos nachschreibe, um die kompatibilität herzustellen, kann ich auch gleich dos verwenden.

i_hasser
20.10.2003, 13:31
Soll ein komplett modulares OS werden bei dem im Gegensatz zu allen mir bekannten Betriebssystemen die Komminukation aller Komponenten nicht direkt abläuft.

Das hat Vorteile und Nachteile... Vorteile:
Verschiedene Versionen verschiedener Komponenten laufen immer zusammen.
Support für verschiedenste Dinge (zb. USB) kann durch einfaches dazuladen eines Modules realisiert werden
Es wird echtes Multithreading möglich, da jede Anwendung von vornherein aus mehreren Threads besteht.
Es ist viel leichter zu kontrollieren ob eine Komponente zb. auf die Platte zugreift etc - das kann auch unterbunden werden.
Es gibt nicht einen großen Kernel mit einer Versionsnummer sondern sowas Zentrales existiert einfach nicht mehr
Es ließen sich auch Emulationsschichten für Windoofs und Linux Treiber implementieren
Man könnte auch Emulationsschichten für den Realmode implementieren -> Vorteil: Zb. laufen dann Pseudo-Hardware-Raids problemlos ohne passenden Treiber, wo Linux vor nicht allzulanger Zeit zb. noch einfach 2 IDE Kanäle erkannt hat
Die Baumstruktur wäre auch sehr gut für die Verbindung 2er oder mehrerer Rechner geeignet, der Rechner ist auch nur ein Element im Baum und nicht die Wurzel
Man könnte ein völlig anderes (und meiner Meinung nach besseres) Multitasking realisieren
Viel flexibler - möglich wäre auch eine Art Skriptsprache zur Treiberprogrammierung, damit wäre dann zb. ein verschlüsselndes Loopdevice überhauptkein Problem - ohne auch nur einmal einen Compiler zu benutzen

Nachteile:
Langsamer.


Vom Grund her soll das ganze so aufgebaut sein:
Es gibt einen Zentralen Manager für alle Prozesse/Treiber.
Jeder Treiber bekommt zu Kommunikation mit allen anderen Komponenten vom OS nur einige wenige Funktionsadressen vom Manager übergeben. Der Manager sortiert den Prozess in einen Baum ein, weist ihm also eine eindeutige, an der Baumposition festgemachte Nummer zu (bzw. den Pfad dort hin). Also zb. 051 könnte sowas bedeuten: 0 -> Rechner 0, 5 -> Blocktreiber, 1 -> 1. installierter Blocktreiber (zb. Festplattentreiber, vielleicht auch nur ein Loopdevice etc.).
Wenn nun ein Prozess zb. etwas ausgeben will muss er das dem Manager sagen. Dafür fordert der Prozess etwas speziellen Speicher an, schreibt da in einem Binärcode (kein MaschinenCode!) rein was er will und sagt dem Manager zu welchem Prozess im Baum das geschickt werden soll. Der Manager prüft, ob dieser Prozess zugriff auf diesen Dienst haben darf und leitet das Packet zum betreffenden Dienst weiter... von der Sache her wir früher das Telefonieren mit Vermittlungsstelle. Dann erzeugt der Manager eine neue Instanz eines bestimmten Threads vom Empfänger und übergibt dem das Packet. Der interpretiert den Binärcode und tut das was drinnen steht.

Alternativ könnte man auch nicht die Prozesse extra dort eintragen, sondern das nur als Device Tree nehmen. Oder man realisiert beides in diesem Baum.
Man könnte auch für jede Geräteklasse (zb. Blocktreiber) einen Verwaltungstreiber dazunehmen, dem werden dann die einzelnen Module (zb. Festplattentreiber) untergeordnet. Der "Kopftreiber" fasst dann alle diese Module zusammen, oder (was bei einem Konsolentreiber sinnvoll wäre) leitet alle Anfragen an ihn an ein definiertes Standart-Untergrerät weiter.

Der riesige Vorteil besteht darin: Die einzelnen Komponenten sind jetzt vollkommen voneinander getrennt. Wenn ein Programm eine Funktion aufruft wird bisher mit der Ausführung des eigentlichen Programms gestoppt, bzw. führt die Instanz ein anderes Programm aus (mit Instanz meine ich hier einen Task, also praktisch beim MultiTasking einer der Tasks der immer wieder für eine kurze Zeit ausgeführt wird).

Also so:
Programm -> Ruft externe Funktion auf
Externe Funktion arbeitet
Externe Funktion kehrt zurück
Programm arbeitet weiter

Mit dem Modell oben könnte man das deutlich eleganter lösen:
Programm -> Sagt dem Manger was bei welcher Funktion getan werden soll
Manager erzeugt eine neue Instanz und kehrt zum Programm zurück.
(von hier an gibt es 2 Parallel arbeitende Instanzen, 1 und 2)
1: Programm arbeitet weiter, wartet vielleicht auf das Resultat der Funktion... oder macht was völlig anderes
2: Führt in der Zeit die Funktion aus
.
.
.
2: Meldet dem Manager dass er fertig ist
Manager meldet 1, dass 2 fertig ist und beendet Instanz 2
1: Wertet das resultat aus und macht weiter


Da liegt ein großer Vorteil. Nach dem einfachen Prinzip weiter oben kann das eigentliche Programm solange die Funktion arbeitet nix machen - nach dem 2. Prinzip schon. Wenn die Funktion sich irgendwo verheddert und abschmiert ist bei dem 1. Prinzip das gesamte Programm abgestürzt, weil das Programm ja von der selben Instanz ausgeführt wurde wie die Funktion und bei zb. Zugriffsverletzungen die komplette Instanz beendet wird. Bei dem 2. Prinzip bekommt das eigentliche Programm einfach die Meldung vom Manager, dass die Funktion nicht so ganz richtig lief und das Programm arbeitet weiter.

Nochmal was zu den Binärprotokollen: Die müssen dann natürlich für jeden Gerätetyp/klasse festgelegt werden. Die Vorteile sind aber trotzdem finde ich überwiegend, da nicht mehr mit irgendwelchen Funktionszeigern rumgehandelt wird ist sowas dann komplett Versionsunabhängig.




Tja, das fällt mir jetzt dazu noch ein. In den Jahren sind mir auch noch einige Ideen mehr gekommen. So ungefähr könnte ein Prozess aussehen:

-> Dem Empfangsteil. Wenn dieser Prozess/Dienst eine Nachricht empfängt wird eine neue Instanz erzeugt die diesen Code ausführt. Parallel läuft der 2. Teil, nämlich
-> Das eigentliche Programm - kann auch aus mehreren Threads etc. bestehen, kein Prolem. Muss auch nicht immer im Hintergrund laufen, bei einem Treiber der nur auf Anfrage etwas machen muss wäre es sinnlos den alle paar ms auszuführen damit der dann gleich wieder aufhört weil nix zu tun ist.

Noch ein kleiner Nachteil ist, dass 350 Threads wie bei Windoofs nich zu unterbieten sind. Das werden dann eher einige tausend Threads und Instanzen, was das alles eben etwas herunterbremst. Aber in Zeiten von 2GHz CPUs macht das denke ich wenig Unterschied. Dafür ist das ganze wirklich extrem modular.

Dj_Ninja
20.10.2003, 13:57
alles schön und gut - und wie schaut's mit der sicherheit aus ? damit ich das system nicht unterwandern kann, müßte man verhindern, daß ausgeführte programme deinen "manager" simulieren und prozesse direkt ansprechen. solange niemand das system angreifen will, mag das wunderbar funktionieren, aber es gibt immer noch ein paar zeitgenossen, die dem anwender da stress machen wollen.

übrigens sollte das os auch absturzsicherheit bieten. eine zerstörung der manager-daten z.b. hätte fatale folgen für die systemstabilität - du kannst ja mal spaßenshalber unter dos booten und das erste kb des dos-speichers überschreiben... ;)

i_hasser
20.10.2003, 14:12
Das ist bei jedem OS so - du brauchst nur den Speichermanager zerballern und jedes OS ist übern Jordan (auch Linux/Unix).

Für sowas gibt es außerdem geschützten Speicher, der sowas verhindern soll. Damit kann man auch gleich den Manager schützen, sowie natürlich auch den Speichermanager.
Andere Prozesse direkt aufzurufen geht immer schief - einfach weil ein Prozess niemals eine Funktionsadresse eines anderen Prozesses mitbekommt. Und dank des veränderten MultiThreadings werden einzelne Funktion nicht mehr durch einen Return Befehl beendet, sondern durch einen Befehl an den Manager die betreffende Instanz zu löschen bzw. auszusetzen.
Und wie gesagt, bei 4gb Speicher bekommt man nicht so schnell eine Funktionsadresse raus. Die für den Manager könnte man noch an einer konstanten Position im Speicher, oder bei einem konstanten Segment speicher... oder beim Prozessaufruf neu übergeben.

Gerade auch sicherheitsmäßig bietet dieses Konzept viele Möglichkeiten. Unter Windoofs reicht ein aufruf an die falsche DLL und die PLatte ist leer.


PS Du bekommst DOS aus einem ganz einfachen Grund zum Absturz wenn du etwas in die ersten 1024bytes des Speichers schreibst: Da liegt nach dem booten die Interrupt Vektor Tabelle, und die wird in der Regel auch nicht mehr verschoben. Wenn ein Interrupt aufgerufen wird (sei es durch einen Tastendruck, oder zb. die Systemuhr die 18.2mal pro Sekunde einen Int aufruft) steht in der Interrupt Vektor Tabelle ein Zeiger auf eine zugehörige Position, wo sich eine Funktion die den INT Aufruf verarbeitet befinden sollte.
Geht das ins leere ist Sense mit dem System, im Realmode wird dann einfach quer im Speicher Code ausgeführt, auch wenn da vielleicht eigentlich Daten gelegen haben.

Das Format der Int Vektor Tabelle sieht so aus:


struct IntVektor {
16bit Integer CS;
16bit Integer IP;
} IntVecTable[256];


Da wird dann der entsprechende Wert ins Code Segment und den Instruction Pointer geladen - wenn da irgendwas steht, wird auch irgendwas ausgeführt... da im Speicher meißt mehr Daten als code ist meißt irgendwas sinnloses.
Als Schmankerl hat der Realmode ja auch noch eine überlappende Adressierung (1230:0008 ist die selbe Adresse wie 1000:2308) - also da kann CS:IP selbst auf eine Funktion oder auf sinnvollen Code zeigen, wenn nicht genau CS und IP stimmen gehts trotzdem schief (dann kommen meißt lustige Meldungen die einem die gesamte Fülle der ASCII Zeichen eröffnen ;))

Dj_Ninja
20.10.2003, 14:28
hmm... vielleicht hätte ich erwähnen sollen, daß ich jahrelang in assembler programmiert habe ? :]

habe aber immer noch keine ahnung, wie deine multitasking-engine funktionieren soll. wenn ich eine funktion durch ein kommando an den manager aufrufe (analog zu einer dos-funktion), dann muß das programm selber warten (multithreading) oder vom manager angehalten werden, bis das angeforderte ergebnis vorliegt. bei dos kein problem, da die funktion per interrupt return beendet wird, nachdem die ergebnisse vorliegen. aber mir scheint bei dir muß jedes modul oder programm vollständiges multithreading unterstützen...

i_hasser
20.10.2003, 14:36
Klar, das Programm muss dann wirklich Multithreading können. Aber ein Prog kann zb. schon Dateien laden wärend es noch was anderes macht, also im Hintergrund. Ist zwar mehr Programmieraufwand aber ich denke es lohnt sich.
Man kann ja auch noch eine Funktion in den Manager machen, dass der auf Wunsch die Instanz vom Programm anhält bis die Funktion fertig ist -> Vertane Zeit mit Warten strebt gegen 0.

Dj_Ninja
20.10.2003, 15:01
die zeit ist erst vertan, wenn sie dem leerlaufprozess zugeführt wird. obwohl, dann spart sie strom... ;)

multithreading macht nur sinn, wenn man mehrere (auch virtuelle wie beim p4) prozessoren zur verfügung hat. ansonsten ist's nichts weiter als multitasking, und da werden teile der einzelnen tasks nacheinander abgearbeitet. wie auch sonst, der prozessor kann ja nicht code von mehreren programm(teilen) gleichzeitig verarbeiten. er kann vielleicht mehrere befehle oder daten (sse) in einem takt verarbeiten, aber die reihenfolge steht dabei trotzdem fest. also blöde gesagt wenn ich ihm die frage stelle, welchen befehl er im moment verarbeitet, könnte er mir immer einen einzigen befehl nennen (die adresse dieses befehls).

zu deinem os. welches dateisystem willst du verwenden ? einige user würden es sicher begrüßen, wenn sich unter INHAOS (INtel_HAssersOperatingSystem ;)) formatierte datenträger auch unter anderen betriebssystemen bearbeiten lassen.

wenn das ganze groß funktionieren soll (daß man damit arbeiten oder spielen kann) müssen außerdem kompatibilitäts-schnittstellen her, die normalen dos- oder win32-code ausführen können. sprich ein modul einer virtuellen maschine, die gebräuchlichen code einlesen, verstehen und auf inhaos umsetzen kann. sowas habe ich mal in form eines tracers angefangen, um abstürze durch fehlerhafte programme (ram-kanonen) verhindern zu können und fehlerhafte befehle (invalid opcode) abfangen zu können. ganz am rande sollte es auch schutzmechanismen aushebeln, das programm sollte nicht merken, daß es unter einem tracer ausgeführt wird. die fertigen teile haben auch ganz gut gefunzt, aber das ist EXTREM langsam, da jeder befehl erst interpretiert, kontrolliert und dann erst ausgeführt wird. also z.b. einen raid-treiber in scriptsprache kannste vergessen, du würdest alle geschwindigkeitsvorteile von raid und (u)dma zunichte machen.

i_hasser
20.10.2003, 16:41
Da hast du mich etwas falsch verstanden.

Mit Scriptsprache meinte ich zb. ein Loop Device. Und da kann man dann natürlich nicht irgendwelche vorhandenen Treiber nutzen, dafür gibts dann Emulationstreiber.

Ein Loopdevice ließe sich recht einfach gestallten. Man muss einfach nur jede Anfrage auf das BlockDevice umsetzen in einen Lese/Schreibzugriff auf eine Datei - das wars schon.
Für solch einfache Zusammentackerei von einzelnen Treibern könnte man eine Scriptsprache machen, ist aber natürlich auch nur eine Idee.

Das mit dem Raid meine ich eher so: Im Realmode ist das BlockDevice von dem gebootet wurde immer ansprechbar - über den Interrupt 13h. Dazu zählen eben auch USB Sticks, Raid Controller etc. - alles ohne zusatztreiber weil die einzelnen Karten ihr Bios ja schon mitbringen, bzw. ein USB Stick vom Bios selbst eingebunden wird. Also im Realmode kann man auf sowas immer zugreifen.
Das Problem ist nur, dass die ganzen Zugriffsfunktionen eben für den Realmode geschrieben sind - also im Protected Mode nicht funktionieren. Desswegen könnte man so eine kleine Realmode-Treiberschnittstelle reinbasteln, damit sowas wenn auch provisorisch erstmal funktioniert - besser als garnix. Später kann man dann natürlich auch einen richtigen 32bit Treiber nehmen, aber den muss man ja erstmal schreiben.

Das OS wird wohl kein natives Dateisystem haben. Der Kernel, bzw. das was so aussieht wird ein Container sein. Da drinnen ist ein normales Dateisystem (aber sehr abgespeckt, damit die Zugriffe möglichst einfach werden - könnte man zb. KernelFS taufen) und da liegen die Module die zum booten unbedingt erforderlich sind - auch der Dateisystemtreiber der Root Partition. Und das kann dann sein was es will - Fat, Ext, ReiserFS, etc... erstmal werd ich nur FAT reinnehmen, weil es noch das so ziemlich einfachste ist. Vielleicht noch HPFS weil es FAT sehr ähnlich ist, nur eben viel besser ;)
Den Container desswegen weil der Kernel Multiboot kompatibel werden soll. Das hat als Endkonsequenz dass man den Kernel direkt mit zb. Grub oder Lilo laden kann - die können aber nur eine einzige Datei laden.
Den KernelContainer könnte man im OS zb. mounten und so problemlos Kernelmodule entfernen und andere dazukopieren. Der Container ist also eine reine Formsache, damit zb. Grub alle zum weiterbooten unbedingt erforderlichen Module in einem Rutsch laden kann - die restlichen, nicht so wichtigen Module können dann von der RootPartition geladen werden, wenn der Dateisystemtreiber für die RootPartition im KernelContainer ordentlich initialisiert wurde.

Multithreading lohnt sich auf jeden Fall. Heutzutage ist Multitasking nicht so weit durchgesetzt - es können zwar mehrere Programme "auf einmal" laufen (die einzelnen Programme sind jeweils ein Task, das OS führt dann zb. abwechselnd alle Tasks je 50µs aus) aber die Programme selbst sind alle noch nicht Multitasking, also Singletasking.
Es gibt da nicht sehr viele Ausnahmen, weil es eben zur Zeit recht schwierig zu implementieren ist und die Vorteile nur minnimal sind.

Das kannst du dir ganz einfach mal anschauen - nimm ein VBasic Programm und pack in den Init Code einer Form eine einfache Endlosschleife - ohne "DoEvents". Das Resultat wird sein, dass du eventuell vorhandene Buttons etc auf der Form nicht mehr nutzen kannst - weil die eine Instanz von dem Programm an der Schleife festhängt, und es pro Programm eben immer nur eine Instanz geben kann.
Und genau da hat das Prinzip von mir eben seine Vorteile. Wenn das Programm etwas ackert kommst du dir nicht mehr wie auf einem 486er vor, sondern die Oberfläche etc. läuft trotzdem genausogut weiter. Wenn du irgendeine große Textdatei im Editor öffnest blockiert nicht gleich der gesamte Editor, bis der die große Datei geöffnet hat.
Und wenn ein Spiel eben im Hintergrund noch Texturen nachladen muss hängt das Spiel nicht, man könnte einfach was reinbauen, dass die Texturen erst angezeigt werden wenn sie geladen sind - besser als wenn das Spiel für einige 100ms steht.

Nebenbei bringt da natürlich auch Vorteile für SMP Systeme ;)

HarryP
22.10.2003, 17:00
hey,

ich wollt jetz auch ma mit programmieren anfangen.

und wollt dann fragen ob ich das auch mit .net machen kann? also nich nur programmieren sondern auch das mit dem os programieren

TiKu
22.10.2003, 18:20
Original geschrieben von HarryP
hey,

ich wollt jetz auch ma mit programmieren anfangen.

und wollt dann fragen ob ich das auch mit .net machen kann? also nich nur programmieren sondern auch das mit dem os programieren Du kannst Visual Studio .net 2003 als Editor für das OS nutzen, aber Du kannst mit dem .net-Framework kein OS basteln.
Und wie gesagt: Stell Dir das mit dem OS-schreiben nicht so einfach vor. Einige hier hinterlassen bei mir den Eindruck "Och, ich lerne mal eben programmieren und nächste Woche schreibe ich an einem Betriebssystem." Das wird so nichts.
Ohne jetzt angeben zu wollen: Ich programmiere jetzt seit 6 Jahren in Visual Basic und seit 4 Jahren in Visual C++ und habe auch mit diversen anderen Sprachen Erfahrung. Seit 2 Jahren studiere ich Informatik und habe dort auch die Fächer Betriebssysteme, Technische Informatik und Rechnerarchitektur auf Anhieb bestanden - alles Fächer, die man für ein OS braucht. Nebenbei arbeite ich seit 1 Jahr als Programmierer. Was die Fähigkeiten als Programmierer angeht, würde ich mich als fortgeschritten bis angehenden Profi bezeichnen. Und trotzdem glaube ich nicht, dass ich ein Betriebssystem designen (den Aufbau, nicht die Oberfläche ;)) und implementieren könnte. Zumindest hätte ich arge Probleme.
Also: Lernt erstmal programmieren. Wenn ihr nach 1 Jahr noch Spaß dran habt, setzt euch nebenbei mit der Hardware auseinander. Und in einigen Jahren könnt ihr nochmal über ein OS nachdenken.
Sollten hier Genies unterwegs sein, die auch gleichmal ein paar Klassenstufen überspringen und Sachen nach 1x Lesen kapiert haben, brauchen die sich jetzt nicht unbedingt angesprochen fühlen.;)

i_hasser
22.10.2003, 19:13
@HarryP

Erstmal Thx für die Beteiligung, aber es ist schon wie es Tiku erklärt hat.

Das Folgende sollte so ungefähr auf dich zutreffen, damit du mitschreiben kannst:
[ ] Du hast viel Assemblerkentnisse, vor allem im Protected Mode
[ ] Du kennst dich mit der x86 CPU gut aus, weist also welche Register es wofür gibt... auch im Protected Mode
[ ] Du hast schonmal versucht eine Hochsprache mit Assembler zu versüßen
[ ] Durch C (nicht C++) solltest du dich mit geschlossenen Augen finden und absolut sicher in der Anwendung sein
[ ] C++ kann auch net schaden, ist aber net so wichtig - ohne Speichermanager sowieso kein C++ ;)
[ ] Du kennst dich gut bei der Hardwareprogrammierung aus, bzw. kannst dich selbstständig darüber informieren (wie man zb. den HDD Controller ansteuert - hast also vll schonmal selbst den Versuch zu sowas unternommen)
[ ] Real Mode, Protected Mode, Virtual86 Mode... du weist was das ist
[ ] Du hast ausreichende Kenntnisse von 80386 Assembler (bzw. >=80386... in den meißten Büchern gehts nur um 8086 Assembler und Real Mode)

So, also wenn mindestens 4 Punkte davon zutreffen können wir anfangen ;)
Ein OS ist nicht eben mal geschrieben, das ist auch nicht sowas mit *klick**klick**klick* und ich hab wieder was neues im OS drinnen.
Anfangs siehst du so ziemlich genau garnix von dem was du machst. Oder bekommst du bei Windoofs den Sheduler, den MemManager, oder vll den Device Tree mit? Über jedes dieser Teile gibt es mehr als nur 3 Bücher.
Das wird auch nicht eine Sache von vielleicht 3 Monaten und dann ist das OS fertig. Dann steht vielleicht das Grundgerüst, und selbst das wäre schon ziemlich viel. Desswegen ist das alles ziemlich langfristig geplant.
In knappen 2 Jahren hab ich zb. etwas mehr Zeit - bis dahin könnte man noch die theoretische Planung ausfeilen, und sich dann dransetzen. Ich muss mich eben bei einigen Dingen auch schon schlau machen (hab dazu aber auch schon recht gute Lektüre bekommen/gefunden (thx@Tiku ;))).

MAjbO
22.10.2003, 22:28
sehr interessantes Prjekt, intel_hasser :)

nicht, dass ich dich in irgendeiner Weise unterstützen könnte, aber mir gefällt es trotzdem ;D

lerne seit diesem Sommer C# und daher sind meine Programmiererfahrungen noch sehr bescheiden...

aber trotzdem wollte ich mich schon immer mal mit dem "Mythos" Assembler auseinander setzen
deshalb frage ich jetzt dich, wo gibt finde ich ein par Tutorials dafür?
ein Buch möchte ich mir eigentlich nicht extra kaufen
ein par gute Links reichen mir schon ;)
es geht mir nicht dadrum, Assembler nacher zu beherschen, muss erstmal C# lernen...
aber ich würde halt gerne wissen, was das überhaupt ist und wie es geht

ich hoffe, du verstehst was ich meine ;)

i_hasser
22.10.2003, 22:34
Such mal nach "The Art of Assembly Language" - ist englisch, aber sehr gut. Das geht auch auf die Architektur bis zum 486er ein, danach weist du also auch was eigentlich unten drunter (in der CPU) vorgeht.

Aber du musst da natürlich dann auch etwas anders rangehen - Ziel ist nicht alles zu verstehen und zu beherrschen (könnte etwas länger dauern ;)), sondern so viel wie möglich mitzunehmen.

Das Buch hat glaub ich 100 A4 Seiten und ist kostenlos.

MAjbO
23.10.2003, 08:13
danke :)
werde ich mir heute Abend mal anschauen

@all
hier noch ein par Links dazu

http://webster.cs.ucr.edu/AoA.html -> Page, Beschreibung

http://webster.cs.ucr.edu/Page_AoAWin/aoahtml.zip -> HTML-Download

http://webster.cs.ucr.edu/Page_AoAWin/aoapdf.zip -> PDF-Download

Dj_Ninja
23.10.2003, 13:12
hmm... in c bin ich nicht so gut, kann dir dabei aber große teile in assembler schreiben (da bin ich spezi), oder deine module in php scripten... *fg* basic kann ich auch noch, wird sich wohl aber genausowenig eignen wie php.

i_hasser
23.10.2003, 13:26
Na Assembler ist wichtig um das unten-drunter zu verstehen. Schreiben will ich darin eigentlich so wenig wie möglich, aber komplett wird es sich net vermeiden lassen.

Dj_Ninja
23.10.2003, 13:38
tjoa... dann ist's kein wunder, daß das oc 'nen fetten athlon braucht...

der kern meines super-tracers (die vm) war komplett in assembler geschrieben und trotzdem kriechend langsam... !

i_hasser
23.10.2003, 14:02
So ein Super Tracer ist ja auch was völlig anderes, solche Emulatoren wie Bochs und VMWare sind zb. keine solche Interpreter, die führen den Code auch direkt aus.

Dj_Ninja
25.10.2003, 15:11
der thread heißt "HEUTE schreiben wir ein betriebssystem" - isses denn schon fertig ? ;D

i_hasser
25.10.2003, 15:20
der Thread.Titel war eher ironisch gemeint ;)


Ehrlich gesagt schreibe ich momentan an einem Image Editor, also sowas wie das Loop Device unter Linux nur eben in Java, damits auch woanders läuft.
Den Kernel will ich ja wie gesagt in einem Image verpacken, weil man nach Multiboot Spezifikationen nur eine Datei laden kann. Und daher brauch ich was um den Kernel komfortabel verpacken zu können.
Und ich will nicht erst einen FS Treiber für Linux schreiben, weil ich mich darüber noch ganz genau überhauptnicht belesen hab. Und so ein Image Editor ist eine feine Sache, weil man dann zb. auch unter Windoofs auf zb. ReiserFS zugreifen kann.

TiKu
25.10.2003, 15:33
Also ich weiß nicht so recht, ob mit Java sowas möglich ist. Außerdem ist Java nicht gerade die schnellste Sprache.;) Es ist zwar inzwischen doch schon ziemlich flott, aber an C++, VB, Delphi usw. kommt's sicher nicht ran.

i_hasser
25.10.2003, 15:36
Der Zugriff auf ein Image ist auf jeden Fall möglich (ist ja nur ne einfache Datei).

Und die Dateisystemtreiber lassen sich auch problemlos implementieren. Hatte schonmal sowas in Java irgendwo runtergeladen, aber das war nur für irgendein Unix Dateisystem auf dessen Namen ich beim besten willen nicht mehr komme :P (irgendwas mit SystemV)



Den Zugriff auf eine reale HDD könnte man notfalls mit einem kleine extraProg realisieren, welches dann zb. in C++ geschrieben ist.

Chip-Ripper
26.10.2003, 17:14
:o :o ?? wo bin ich..???

`....boah !!...ich will auch mitmachen !!

Meine Kenntnisse : Donkey Kong 21er Level !!
Packman ! ;D

....wie..?.,.wie soll ich das verstehen..,..meine Vorbildung sei hier nicht ganz ausreichend..?..jajaaa,..wenn ich jetzt ne Grienkard hätt`,........ ;D


....VIEL ERFOLG !!!

i_hasser
26.10.2003, 17:18
Danke :)


PS Du machst in vielen Jahren dann mal die Standart-Games ;)

i_hasser
07.01.2004, 17:33
So, inzwischen sind mir wieder ein paar Ideen durch den Kopf gegangen ;D

Man könnte mal versuchen das komplette Betriebssystem mit einem (bzw. sowas ähnlichem) Dateisystem aufzubauen.

Die Idee ist mir bei meinem Image Editor gekommen (der noch net fertig ist :] - der 486Bench will auch noch weitergeschrieben werden).

Beim normalen Dateisystem gibts ja Verzeichnisse, Dateien und Links (ok, bei Fat und Ntfs sind die Links etwas armseelig ;) /e: nein, bei NTFS sind sie doch nicht so armseelig sondern genauso Leistungsfähig wie bei anderen FSs, aber Win nutzt diese Links nicht bzw. kann der User sie nicht nutzen/).

Wenn man da die Links als Spezialobjekt rausnimmt gibts nur Dateien und Verzeichnisse, beide sind statisch, bzw. non-volatile - bleiben also dauerhaft erhalten (mal von Ramdisks abgesehen).

Unter Linux haben wir auch noch Devices. Die verhalten sich grundlegend zwar auch wie normale Dateien (man kann Daten lesen/schreiben), aber sind schonmal in die Richtung meiner Idee.


Theoretisch könnte man ja zb. die komplette Speicherverwaltung über ein Dateisystem realisieren - es gibt eine Ramdisk mit der Größe des gesamten Rams, ein simples und effizientes Dateisystem sorgt für die Speicherverwaltung (natürlich ließe sich da auch eine Mammut-Rechteverwaltung implementieren), und Zugriffe auf Dateien allgemein erfolgen über Speichermapping (allgemein für alle Dateien - für Dateien > 4gb könnte man einfach auf Paging zurückgreifen, so dass man zb. mit einem einzelnen 32bit Integer entscheidet welchen Bereich man gerade sieht, da der x86 ja nur 4gb adressieren kann - macht immerhin max. 16 Exabyte pro Datei).

Der Zugriff auf Dateien per Speichermapping muss sein, weil man so ohne Leistungsverlust auf die "Dateien" (reservierten Bereiche) im Ram zurückgreifen kann, das soll ja auch wie ein Dateisystem aufgebaut sein. Bei Win32 läuft das bei Dateien zb. so ab, dass das Programm ein Speichersegment mit Dateigröße bekommt - greift das Programm auf Byte xyz zu gibts eine Exception (weil dem Offset kein Speicher zugeordnet ist), daraufhin wertet der Kernel die Exception aus und reserviert einen 4kb Block, ließt den Datenblock aus der Datei dahin und mappt den Block zum Offset xyz des Segments. Dann wird die letzte Anweisung des Programms wiederholt und das Programm ließt vom Adresse xyz das, was letztendlich in der Datei an Position xyz steht.

Wenns um Ram geht kann man per Paging gleich den Rambereich in das übergebene Segment mappen und die Exception fällt weg - das Programm greift dann ohne Leistungsverlust auf den Ram zu.


Tja, nun kann man die Geschichte aber noch weitertreiben. Sämtliche Devices sind ja volatile, also beim Ausschalten weg - dafür gibts auch spezielle "Dateisysteme" (bei Linux zb. devfs und sysfs), die auch mit Devices umgehen können.

Theoretisch wäre es ja nun kein Problem wirklich sämtliche Devices/Treiber in ein FS auszulagern. Und zwar so wie zb. beim devfs oder sysfs bei Linux, denn normalerweise schwirrt bei /dev aller möglicher Mist rum.

Also um mal ein schönes Beispiel zu geben: Auswertung der Partitionstabelle und aus zb. /dev/hda die einzelnen Devices /dev/hda1 /dev/hda2 ... erzeugen.

Man könnte einfach einen neues Device erzeugen - das Device ist ähnlich einem Verzeichniss und enthält auch Objekte. In dem Device gibts dann einen Link auf dein Blockdevice dessen Partitionstabelle ausgewertet werden soll - den muss man dann auf zb. /dev/hda setzen.
Startet man nun das Device gibts im Device neue Blockdevices, die dann die einzelnen Partitionen darstellen.


Nun könnte man das noch weiter treiben ;D

Prozesse könnte man auch in einem "Dateisystem" darstellen. Wieder ein Verzeichniss, das einen Link auf den Code enthält. Man müsste also erst den Prozess laden (Prozess-Device wird erzeugt) und dann den Link zum Code im Prozess-Device aufrufen.

Damit könnten mehrere Threads problemlos miteinander über solche Links kommunizieren. Ein schönes Beispiel wäre ein Timer - ein Prog möchte, dass eine Funktion alle x Sekunden von einem Timer aufgerufen wird. Dazu enthält das Timer-Device (ich nenns einfach mal so) Links die auf Code zeigen - das Programm setzt nun einfach einen der Links auf seinen eigenen Code-Link und das Timerdevice ruft den gesetzten Link dann einfach bei jedem Durchlauf auf.




Die Sache kann man nun beliebig weiter ausbauen - ein "Dateisystem" muss ja net Daten der Platte oder so enthalten (bei Linux muss / ja zb. auf die Rootpartition zeigen) - nach / könnte man ein rein virtuelles "Dateisystem" mounten - da erzeugt man dann einige (volatile - sind beim nächsten mal weg)-Verzeichnisse (oder besser Mount-Points) und da wird dann das DevFS, die Dateisysteme usw. hingemountet.


Die Devices kann man auch noch deutlich aufbohren, Linux kennt für sowas zb. relativ wenige verschiedene Devices.





Der Vorteil der Sache: Man hätte wirklich alles unter einem Hut und trotzdem wäre alles Modular aufgebaut. Die komplette Verwaltung - Speichermanagement, Interprozesskommunikation, Datenaustausch zwischen Anwendungen und natürlich das komplette Rechtemanagement wären alles über "Dateisysteme" realisiert. Es gibt nicht einen Schuh dafür und einen dafür. Und wenn man eben mal einen neuen Speichermanager will wechselt man einfach das (achtung Eigenschöpfung! ;)) RamFS.


Man könnte auch ganz einfach Cache-Stufen realisieren (auch wieder nur ein Beispiel).

Wenn man ein Blockdevice Cachen will (schreib/lesecache) lädt man einfach ein Cache-Device. Im Cache Device gibts ein Link auf das BlockDev und ein neues BlockDev - das Cache Device puffert dann alle Zugriffe über das neue BlockDev.



Damit kann man auch einfach das Prinzip von dem Baum, das ich oben schonmal angesprochen hatte erweitern - beim booten ertstellt man einfach einige virtuelle (da nicht auf der HDD vorhandene) Verzeichnisse, in die sortiert man dann die einzelnen Devices rein.

Sargnagel
07.01.2004, 18:16
Man, das sind doch mal Ideen! :D
Da bekomme ich direkt Lust, ebenfalls OS-Programmierung zu erlernen. Aber leider läßt mir meine Diplom-Arbeit dazu keine Zeit. :(

@Baum-Prinzip:
Fügst Du Daten in einen sortierten Baum ein? Ich habe letztens was von wahnsinnig effizienten Fibonacci-Heaps gelesen; kann man die dafür anwenden? Die erreichen eine geringe Komplexität, weil sie die eingefügten Daten erst bei einer Lese-Anforderung sortieren und nicht bei jedem Schreibvorgang.

@RamFS:
Ich bin begeistert! Das hört sich alles verdammt gut an. Mir fehlt nur leider die nötige OS-Erfahrung, um diese Ansätze 100ig einordnen und weiterentwickeln zu können. :(

Ich wünsche viel Erfolg weiterhin! Ich frage mich nur, wie lange es wohl dauert, bis man meint, das neue OS-Konzept steht und man sich ans Implementieren machen kann ... aber "Gut Ding will Weile haben". :)

i_hasser
07.01.2004, 18:41
Die nächste Zeit werd ich wohl keine Zeit fürs Praktische haben - in 1 1/2 Jahren dürfte ich dafür aber genug Zeit haben. Bis dahin wird fleißig weitergesponnen, mal sehen was wir hier noch so zusammenbekommen ;)

Die Baum-Geschichte ist ja praktisch nur eine vereinfachte Version vom DevFS - die Idee dahinter war, dass jedes Device durch einen Pfad im Baum zu erreichen ist, also wie eine individuelle Telefonnummer.
Ein Dateisystem bietet ja genau dieses Feature - jedes Objekt (in dem Fall Device) ist durch einen individuellen Pfad zu erreichen.

Der Baum bot die Vorteile, dass die einzelnen Devices nicht mehr ineinander verlinkt werden um zu kommunizieren (und wenn ein Device den Bach runtergeht, schwimmen alle hinterher) sondern über eine Zwischenstelle - wenn ein Device abschmiert bleiben alle anderen davon unberührt.

Zum Bleistift hab ich bei meinem Notebook ein Device für den Lüfter - wenn ich "force_on: 1" in das Device schreibe (ist ein Stream-Device bzw. Char Device) läuft der Lüfter immer, wenn ich "force_on: 0" reinschreibe läuft er nur wenns zu warm wird. Genau so soll das auch mit dem Baum ablaufen (bzw. jetzt mit dem Dateisystem) - momentan ist es nämlich eher so, dass ein Thread einen Zeiger auf eine Funktion bekommt und der Lüfter würde in dem Fall über diese Funktion gesteuert werden.

Nachteil: Wenn der Prozess der diese Funktion enthält entladen wird (oder zb. abschmiert) wird der Funktionszeiger ungültig. Ruft nun ein anderer Prozess diese Funktion auf schmiert der andere Prozess auch ab.
Bei der Baum/DevFS Geschichte bekäme der andere Thread einfach die Info, dass der Schreibzugriff auf das Device fehlgeschlagen ist. Hier gehts jetzt nur um den Lüfter, aber das geht eben auch mit so ziemlich allem - vom Speichermanager (der aber dank RamFS überflüssig wird bzw. sich nicht vom normalen Dateizugriff unterscheidet) über Maus/Tastatureingaben über Graka-Funktionen, Drucker etc. bis zum Lüfter ;)

Also ein sortierter Baum wirds net - aber wenn du da Ideen hast immer her damit.

Sargnagel
07.01.2004, 19:02
Original geschrieben von intel_hasser
Also ein sortierter Baum wirds net - aber wenn du da Ideen hast immer her damit.
Ah! Jetzt wird's klarer! :)

Der Baum sollte aber schon derart sortiert sein, daß oft benötigte Devices sich nahe der Wurzel befinden. Vielleicht kann man auch eine dynamische Neustrukturierung des Baumes einbauen. Vielleicht sollte man in bestimmten Zeitabständen Nutzungsstatistiken der einzelnen Knoten abfragen und Knoten, die häufiger genutzt wurden als ihre Vorgänger, in der Hierarchie nach oben verfrachten. Ganz primitiv könnte man diese Statistik nutzen, um den Binärbaum zu sortieren bis hin zum balanced binary tree vielleicht. Inwiefern das die Performance verbessern oder eventuell verschlechtern würde, weiß ich nicht.

Vielleicht muß man auch nicht den gesamten Baum neu ausbalancieren, sondern kann es auf Teilbäume beschränken, wobei das von der Strukturierung des Baumes abhängt.

i_hasser
07.01.2004, 19:24
Man könnte auch dem... ich nenns mal Komplex-Dateisystemtreiber eine Cache-Stufe verpassen.

Meinen tue ich damit das hier: Ein normaler FS Treiber muss nur die simplen Operationen beherrschen. Also Datei erzeugen, Größe ändern, schreiben/lesen (ohne Größenänderung), Datei löschen (selbes nochmal für Verzeichnisse) und ein paar Spielereien für Attribute.
Mit Komplex-Dateisystemtreiber meine ich den Teil, der diese einzelfunktionen zusammenfasst - also der zb. dafür sorgt, dass leseoperationen von /mnt/cdrom an den CDRomFS-Treiber weitergeleitet werden, der die Dateigröße bei Zugriffen über die Dateigrenze hinweg ändert usw.

Da könnte man eine Cache-Stufe einbauen. Wenn ich zb. cp xyz abc (oder im Dos Style copy xyz abc) mache, dass dann genau das gecached wird - und nicht erst sämtliche Schreiboperationen (wie zb. bei Linux der Fall) - da muss nämlich erstmal alles gelesen werden und solange braucht der Befehl (Lesezugriffe auf nichtgecachte Bereiche müssen ja ausgeführt werden).

In die Cachestufe könnte man auch aufnehmen, dass für Devices etc. auf die oft zugegriffen wird die Zugriffsdaten gecached werden. Natürlich kann man bei so einer Cachestufe auch eine dynamische aktualisierung reinsetzen (muss man dann sogar), also wenn das Device auf der Platte verschwindet erkennt das die Cachestufe (über die ja sowieso alle Zugriffe ablaufen) und meldet dann das Device beim nächsten Zugriff als nicht-existent.

Damit wäre ordentlich Speed gewonnen. Und die zusätzliche Cachestufe macht sich auch wunderbar.

Möglicherweise könnte man auch Threads mit in den Cache einbinden, also wenn ich zb. mit tar einen batzen Dateien entpacke wird dieser Prozess bei der Cache Stufe registriert (bzw. werden die Dateien die bearbeitet werden registriert) und entpackt im Hintergrund und ich muss erst warten wenn ich wirklich auf eine Datei zugreifen will (sie zb. lesen möchte) - oder er wird vorher im Hintergrund fertig. Für sowas muss die Cachestufe (die dann nach außen wie ein Dateisystem aussieht und selbst auf ein Dateisystem-Device aufsetzt) auch solche Komplexfunktionen kennen (wie zb. copy). Andererseits könnte man das auch wieder weglassen und der copy-Prozess registeriert die Datei wie zb. tar bei der Cachestufe.


Tja, so langsam kommt hier immer mehr zusammen. Aber das soll ruhig noch weitergähren, vielleicht kommt nochwas besseres raus ;)

Ach ja, nochmal zu der FS-Geschichte (wegen dem FS-Device oben). Ich meine das so, dass es für die simplen Zugriffe auch Devices gibt und man mountet nichtmehr irgendwelche Blockdevices (wie unter Linux), sondern erzeugt ein (jetzt kommt ein finaler Name dafür) SimpleFS-Device (hab ich von meinem Image Editor geklaut ;D) der auf ein Blockdevice aufsetzt.
Und dieses SimpleFS-Device kann man dann irgendwo einmounten. Die Cachestufe setzt dann eben auf ein SimpleFS-Dev auf und bietet selbst ein SimpleFS-Dev an.

Da fällt mir ein Nachteil ein... obwohl nein, es geht auch so. Um das Cache-Konzept oben nochmal zu erläutern: Ein Prozess registriert sich zb. bei der Cachestufe und sagt, dass der die Datei abc bearbeitet (kann ja zb. copy sein). Der kann nun solange im Hintergrund langsam arbeiten, bis man direkt auf abc zugreift (sich zb. den Inhalt anzeigen lässt) - dann schickt die Cachestufe ein Kommando an den Prozess, dass der sich doch etwas beeilen soll bzw. diese Datei fertigstellen soll. Und wenn das passiert ist kann man darauf zugreifen.

Wenn ich zb. den Linux Kernel entpacke rödelt erstmal recht lange die Platte, weil das entpackt so 200mb sind. Aber die werden erst beim compilieren gebraucht (und auch da nur die Hälfte), und entpacken kann er ja im Hintergrund, solange ich den Kernel noch konfiguriere - da ist genug Freizeit. Das tar xvfz abc.tar.gz (nur mal zb. das Entpackkommando) wäre damit sofort erledigt, und ich muss erst warten wenn ich wirklich auf die Dateien zugreifen will. Da ich aber nicht sofort auf die ganzen 200mb zugreifen will (sondern eher erstmal auf einige wenige mb) wäre damit ordentlich Zeit gespart.




Mal sehen, vielleicht mach in irgendwann mal noch eine kleine Umsetzung davon mit Java - da kann man die Sachen schonmal testen und bekommt auch gleich mit ob alles so problemlos läuft - bevor man dann richtig mit dem OS anfängt und merkt, dass irgendwas net so richtig will.



PS Ich seh gerade, das letzte mit dem Simple-FS deckt sich net mit der ersten Zeile (Cachestufe beim komplex-FS Treiber). Natürlich wandert die Cachestufe zum SimpleFS, es soll ja nur ein einziges komplex-FS geben (was zb. bei Linux alles in / enthält - also wirklich alles, auch die eingemounteten SimpleFSs).


/e Die zusätzlichen Objekte und Device-Typen kann man ja jetzt schonmal zusammentragen und bei Bedarf ergänzen - ich hab mir dazu auch schon ne Platte gemacht, wegen dem Image Editor.
Ich trag im nächsten Beitrag einfach mal zusammen.

Sargnagel
07.01.2004, 19:40
Die Cachestufen/Hintergrundoperationen gefallen mir sehr gut. Es wird wirklich oftmals sehr viel Rechen-/Festplattenzeit verschwendet, die man doch sinnvoll nutzen könnte. Angenommen, man kann eine Datei in einem tar-Archiv direkt extrahieren, ohne alle vorherigen Dateien entpacken zu müssen, so kann man schon - während das Archiv noch im Hintergrund entpackt wird - bestimmte Dateien dieses Archives öffnen bzw. sogar bearbeiten (Cache ;D ).
Das ganze gefällt mir immer besser! :)

i_hasser
07.01.2004, 19:45
So, hier kommen jetzt einfach mal alle Dinge zusammen, die neu ins Dateisystem kommen. Jedes SimpleFS-Dev muss dann auch praktisch eine Liste anbieten, in der drinnen steht welche der Objekte unterstützt werden (auf einem FAT Dateisystem dürften sich relativ schlecht Treiber speichern lassen *chatt*).


Also fang ich einfach mal damit an, was ich schon in meinem Image Editor implementiert hab.

Grundsätzlich könnte man zwischen Objekten und Containern unterteilen - die Container schimpfe ich jetzt einfach mal Superobjekte.

Objekte enthalten Daten, Superobjekte enthalten andere Superobjekte oder Objekte.
Eine Datei ist zb. ein Objekt, ein Verzeichniss ein Superobjekt.

Die Objekte müssten unterstützt werden (stand: 7.1.2004):
- Dateien
- Links (auf andere Objekte oder Code oder auf positionen von Devices)
- Devices (unten kommen noch Device-Typen)

Und die Superobjekte bräuchten wir (stand: 7.1.2004):
- Links (auf andere Superobjekte)
- Verzeichnisse
- Mountpunkte (hier werden SimpleFS-Devices eingehängt)
- Device-Container (kapseln die Objekte von einem Device ab)
- Prozess-Container (kapseln die Objekte von einem Prozess/Thread ab)

Alle Objekte müssten noch eine Eigenschaft haben, ob volatile oder non-volatile (dauerhaft oder beim nächsten Auschalten weg) - ich nenns einfach mal real und virtual.

Ein Treiber könnte sich zb. so präsentieren:
Der Treiber erzeugt ein virtuelles Verzeichniss, darin enthalten sind Links auf die Devices auf denen der Treiber aufsetzt und Devices, die der Treiber anbietet. Zusätzlich gibts noch ein Device, mit dem man einstellt ob der Treiber läuft oder ob der net laufen soll (man muss ja zb. erstmal die Links auf die Devices setzen auf denen Aufgesetzt wird - die Links wären dann zb. schreibgeschützt wenn der Treiber läuft).

Den Treiber kann man in einem beliebigen virtuellen Verzeichniss erzeugen. Oder man könnte auch ein spezielles virtuelles Superobjekt für den Treiber machen, in dem das Zeugs drinnen liegt.


So, die Devices könnte man brauchen:

- Blockdevices
Daten in einer normalen Blockorganisation, begrenze Größe. Blockgröße kann auch 1 Byte sein, also eine einfache Häufung von Bytes. Wichtig ist, dass die Anzahl der Blöck und deren Größe konstant ist (wie zb. bei einer HDD oder einer Partition).

- Streamdevices
In einen Stream kann man beliebige Daten reinschreiben. Streams können auch Daten ausspucken, da könnte man noch zwischen Input und Output Streams unterscheiden.
Wer Java oder C++ kennt wird auch Streams bestens kennnen ;)
Sowas gibts auch schon bei Linux (Character Devices) und DOS (glaub Cooked Device) - Stream Device scheint mir besser klingend, weil die Dinger in Java und C++ auch so heißen ;)

Hier könnte man auch noch zwischen Streams mit konstanter Datenrate (zb. Modem) und welcher mit variabler Datenrate unterscheiden.

Man könnte auch Streamdevices definieren, die nur bestimmte Daten (zb. eine Zahl in einem bestimmten Bereich) annehmen und alles andere zurückweisen.

- Packet Device
Wie ein Streamdevice, nur dass eben komplete Packete durchgeschickt werden - TCP/IP könnte so ein Device sein - man schickt den Stream vom Ethernet Protokoll in den TCP Treiber, und der bietet ein Packet Device, das komplette Daten-Packete ausspuckt.

- SimpleFS Device
Oben hab ich das ja schon beschrieben - bietet eher einfache Dateisystemzugriffsfunktionen, diese Devices können gemountet werden.



-------------------


Tja, soviel fällt mir dazu erstmal ein. Das soll nur ein Vorschlag sein - wenn ihr gute Ergänzugen dazu habt werd ich das oben abändern und aktualisieren. Das wird also praktisch immer weiterentwickelt.

Für Tipps bin ich natürlich auch dankbar ;)

i_hasser
07.01.2004, 20:01
Mir ist nochwas eingefallen - ist noch recht unausgegohren, aber bietet wirklich Potenzial:

Man könnte das Multitasking auch per "Dateisystem" realisieren. Heutige Programme bestehen aus Code und Daten, in jeweils getrennten Segmenten. Wenn man normale Programme lädt werden die auch erstmal wie ein Device eingebunden (werd ich oben noch ergänzen, ein Prozess als Superobjekt) und dieses Superobjekt enthält dann eine Datei mit Code und eine Datei mit den Daten (oder mehrere Dateien jeweils). Man könnte da irgendwie Zeiger auf Codepositionen reinbasteln, und der Multitasker speichert sich dann immer nur wo er im Code gerade war - den Code selbst gibts ja dann auch im "Dateisystem". Die Position könnte er sich als Link speichern, und wenn er 10 Prozesse hat liegem im Multitasker-Device-Superobjekt (bzw. in einem Unterverzeichnis davon) eben 10 Links auf Codepositionen - und die werden immer nacheinander abgearbeitet.
Man könnte da auch zu jedem der Links noch Prioritätsinformationen dazupacken (vielleicht als Stream - wieder ein neues Objekt, ein Stream der nur bestimmte Daten annimmt, zb. eine Zahl zwischen 0 und 10) und die dann eben auch ändern.

Einen neuen Thread könnte man dann dadurch starten, indem man einen Prozess lädt, und den Zeiger auf die Startroutine mit in das Verzeichniss vom Multitasker packt (für jeden Zeiger kann man dann ja auch noch Speichern, ob er abgearbeitet werden soll oder net).



Na mal sehen was mir dazu noch einfällt. Aber da wäre dann schon wieder was verallgemeinert. Das find ich ja an den Cache-Stufen so schön - der User bestimmt, wie gecached wird. Der User kann auch mehrere Cache-Stufen hintereinanderpacken, also sozusagen ein L1 und ein L2 Cache (der Sinn davon ist fraglich, aber der User kann auch auf ein Device ungecached zugreifen - und wenn er auf ein Simple-FS keine Cachestufe aufsetzt wird auch da net gecached).

i_hasser
07.01.2004, 20:52
Mir ist noch was eingefallen - Stack Overflows oder Underruns gehören damit auch der Vergangenheit an, man kann ja Problemlos dank RamFS für jeden einzelnen Prozess ein extra Stacksegment einrichten. Und wenn da die Ober oder Untergrenze überschritten wird gibts ne nette Fehlermeldung und der Thread wird abgeschossen. Irgendwozu müssen die 8192 Einträge in der GDT ja gut sein ;)

Sargnagel
07.01.2004, 23:22
@Multitasking:
Klingt gut. Alles schön einheitlich und übersichtlich strukturiert. Ich weiß leider nicht, wie bei aktuellen OS das Multitasking gehandhabt wird, somit fehlt mir da eine direkte Vergleichsmöglichkeit.

@Stack:
Die Möglichkeit Stack-Overflows bzw. Underruns zu detektieren, gefällt mir sehr. Ich frage mich nur, ob das auch auf eine Ebene darunter, d.h. Bufferoverflow und Konsorten, übertragbar ist? Es wäre schön, wenn dieses weitere Sicherheitselement in das OS integriert werden könnte, zumal M$ und die Linux-Gemeinde ähnlich leisten wollen.

i_hasser
07.01.2004, 23:45
Buffer Overflows/Unterruns sind ja Stacküberläuft/Unterläufe (afaik)

Momentan ist es so (zumindest bei win32), dass der Stack ganz am Ende vom Datensegment anfängt (und dann wird nach unten gezählt).

Und irgendwann überschreibt man dann eben die eigenen Daten. Komischerweise nutzt win32 afaik auch nicht die Trennung von Daten und Code - der Protected Mode bietet hier wunderbare Möglichkeiten, die aber seltenst genutzt werden. Man kann Segmente entweder mit Schreibzugriff versehen (dann kann man keinen Code darin ausführen) oder man kann eben Code ausführen (dann hat das Segment nur Lesezugriff).

Bei einfachen Assembler-Progs nimmt man einfach 2 Segmente die genau den selben Speicher adressieren, eins ist das Datensegment, eins das Codesegment. Und wenn man da eben etwas ins Datensegment schreibt beeinflusst das logischerweise auch den Inhalt vom Codesegment am selben Offset. Win32 läuft unten drunter genauso, und desswegen sind die Stack Overflows/Unterruns auch so gefährlich - der Stack, der eigentlich keinen Code verändern könnte überschreibt so auch vorhandenen Code aus dem Code Segment (obwohl sich der Stack ja im Datensegment befindet, aber das liegt nunmal an der selben Stelle wie das Code Segment) und damit kann man doch machen was man will.

Ob Linux das trennt weis ich net. Ich glaub nicht, weil jedes Prog zwar für sich 4gb Speicher hat, aber wenn man es trennen würde hätte jedes Prog für sich 8gb (virtuellen) Speicher - 4gb Code und 4gb Daten. Mir wäre es lieb, wenn jedes Programm 12gb Speicher bekommen würde - 4gb Code, 4gb Daten und 4gb Stack.



Das Multitasking läuft heute so ähnlich ab, nur ist der Zugang dazu eben alles andere als einheitlich. Da gibts die Funktionen für Multitasking, die anderen für die Graphik, dort mal wieder welche für den HDD zugriff (bei linux ist der aber schon schön ins Dateisystem integriert) usw - das alles könnte man mit den "Dateisystemen" (die dann wirklich für alles da sind) unter einen Hut bringen und unter einer einheitlichen Schnittstelle zusammenfassen.

Dj_Ninja
07.01.2004, 23:54
hmm... wieviel terabyte ram hast du denn, daß du einen 4 gb großen stack brauchst ?? :o
ich wäre mehr für eine sinnvolle dynamische trennung. code und stack werden so schnell sicher keine 4 gb brauchen. diese trennung könnte das programm beim start einmal festlegen (noch bevor der eigentliche code gestartet wird) und danach nicht mehr verändern. das würde den stack overflow auch wirksam verhindern.

ans wirklich sichere OS glaub ich sowieso nicht - oder glaubt irgendwer daß TCPA nicht angreifbar (hackbar) sein wird ? :] *buck*

i_hasser
08.01.2004, 00:09
Das ist doch nur virtueller Speicher - also Adressraum. Ein Programm kann auf nicht mehr als diese 12gb zugreifen (verteilt über 3 Segmente), darunter kommt dann die Speicherverwaltung vom Protected Mode, das Paging. Da kann man dann den Speicher in 4kb Blöcken auf realen Speicher mappen, oder auch garnet mappen (dann gibts eben einen Adressraum dem kein Speicher zugeordnet ist).

Also ein Programm kann zb. im Datensegment alles bis zum Offset 1000h an Speicher belegen. Dann ist dem Offset 1001h kein Speicher zugeordnet, und beim Zugriff gibts ne Exception. Dann wäre der Auftrag vom Speichermanager diese Exception abzufangen, dem 4kb Block der 1001h enthält realen Speicher zuzuordnen und dann die Anweisung die die Exception ausgelößt hat nochmal durchzulaufen. Das Programm kann dann im Endeffekt auf 1001h zugreifen als wäre da schon immer Speicher gewesen, in Wirklichkeit ist aber nur da Speicher zugewiesen wo das Programm auch welchen braucht.

Nur nebenbei: Virtueller Speicher funktioniert dann so, dass das OS bei Speichermangel einige der 4kb Blöcke auf die Platte schreibt und den zugeordneten Speicher entzieht und einem anderen Programm gibt.
Will das Programm nun wieder auf den Speicher zugreifen gibts ne Exception und das OS lädt wieder einen 4kb Block an die Stelle und ließt die Daten von der HDD in den 4kb Block.



So, nun mach ich mich aber doch ins Bett, wollte da schon vor einer Stunde liegen :]

Dj_Ninja
08.01.2004, 01:15
mir ist schon klar, wie virtueller speicher funktioniert. nur ich wäre der meinung man sollte den ohnehin meist knappen speicher sinnvoll einteilen anstelle massiv performance dafür zu verschwenden welcher der zig millionen 4kb-blöcke gerade gebraucht wird oder ausgelagert werden kann... nur ne meinung und alles hat vor- und nachteile. *noahnung*

i_hasser
08.01.2004, 12:02
Die Granularität beträgt 4kb - man kann aber mit einem Eintrag trotzdem 100mb umfassen (nur ist die Größe, die ein Eintrag umfasst eben ein Vielfaches von 4kb).

Sorry, ich seh keinen Nachteil - Virtuellen Adressraum kann man verschleudern wie man will (um es mal so zu sagen) und Physikalischer Speicher wird net verschwendet. Wenn das Programm irgendwo auf den Virtuellen Speicher zugreift schaut die CPU automatisch in der GDT und LDT nach, welcher Physikalischer Speicher zugeordnet wurde - und diese Infos werden im TLB (Transaction Lookaside Buffer) gespeichert. Das funktioniert heute auch schon so, nur dass eben bei win32 das Programm 2 Segmente bekommt (8gb, wobei die sich überlagern und so sinds 4gb). Die Speicherzuordnung unten drunter wird von win32 auch so erledigt (mittels Paging wird dem Datensegment da physischer Speicher zugeordnet, wo er gebraucht wird).

Leistungsmäßig bringt das keine Einbußen. Die Formulierung oben mit 4kb Blöcken war ein bisschen unglücklich - Granularität passt besser (wird eben nur seltener verwendet).

TiKu
08.01.2004, 23:57
Original geschrieben von intel_hasser
Beim normalen Dateisystem gibts ja Verzeichnisse, Dateien und Links (ok, bei Fat und Ntfs sind die Links etwas armseelig ;)).Da intel_hasser es scheinbar doch nicht ändert (;)), muss ich mal NTFS in Schutz nehmen. NTFS kennt (vermutlich ab Version 3, also ab Win2k) sehr wohl Hard Links (darum ging es hier). Allerdings gehen die bei den aktuellen Windows-Versionen etwas unter.

i_hasser
09.01.2004, 00:05
Ist geändert ;)

Interessant wäre auch die Möglichkeit die CPU mit in das FS einzubinden - damit könnte man im Endeffekt wunderbare Cluster extrem modular und einfach aufstellen. SMP wäre dann auch nur eine kleine Hürde, mit xbeliebig vielen CPUs.


/e: Hardwareressourcen (Interrupts, IO Ports etc) kann man dann natürlich auch gleich mit reinpacken. Dann wäre sogar der Hardwarezugriff mit über das FS vereinheitlicht (ioports könnte man zb. als Streamdevice darstellen).

TiKu
09.01.2004, 00:33
Original geschrieben von intel_hasser
Ist geändert ;)Fein!;D;D;D :-*

NemesisTN
16.02.2004, 22:18
@intel_hasser:
Hast du dir mal das Volume 3 des Software Developers Manual von Intel zu Gemüte geführt?
Da steht der ganze Mist mit dem Memory Management im Protected Mode eigentlich ziemlich gut erklärt drin.

Ansonsten tolle Idee mit dem eigenem BS. =)

i_hasser
16.02.2004, 22:56
Nein noch nicht - werd ich aber auf jeden Fall, danke ;)

Tja, in letzter Zeit hatte ich wieder weniger Einfälle - man könnte sämtliche Codefetzen im Ram in ein FS integrieren, dementsprechend dann auch den gesamten Sheduler und das Multitasking.

Inzwischen hab ich mich aber mal ein bisschen mit der Umsetzung beschäftigt, hab mir mal GRUB auf einer Diskette gezogen und mir die Multiboot Kernel Spezifikationen angesehen.

Vorraussichtlich wird der Kernel dann wirklich eine Containerdatei mit einem kompletten (aber einfachen) FS, wo dann Konfigurationsskripte und die nötigsten Module drinnen lagern.

Dj_Ninja
17.02.2004, 00:04
hmm...

weil ich gerade so gut in php drin bin... man könnte ja mal ein bs in php schreiben! :]

i_hasser
17.02.2004, 01:42
:]

Man könnte auch ein OS in BrainFuck schreiben... *chatt*

Aber bei interpretierten Sprachen macht sich ein OS immer am allerbesten *aufOSdefinitionschau*



;)

i_hasser
17.02.2004, 20:36
Mir ist wieder ein bisschen was eingefallen ;)

Da der Protected Mode ja eh in Daten und Codesegmente unterscheidet und man um wenigstens ein bisschen Segmentierung sowieso nicht dumherum kommt könnte man jedem Datensegment von Haus aus einen 32bit Selektor für Paging zur Seite stellen.

Damit könnte man auch Dateizugriff auf große Dateien komplett über den virtuellen Speicher abhandeln (2^32*4GB macht 16 Exabyte, das dürfte erstmal reichen *buck*), man könnte die Geschichte mit dem RamFS noch weiter treiben und den Ram zu einem Blockdevice verwandeln (wo man dann ein beliebiges FS aufsetzen kann - natürlich müsste das ein spezielle auf die Bedürfnisse zugeschnittenes FS sein) ohne großartig Leistung zu verlieren, und AMD64 wäre dann auch schnell implementiert, da die Speicherverwaltung dann intern sowieso schon in 64bit abläuft.

Der Vorteil vom Dateizugriff über den Ram liegt eben darin, dass man dann relativ leicht so weit am Paging optimieren kann, dass bei einer Datei im RamFS nicht irgend eine Exception die Aufrufe behandeln muss, sondern der Zugriff wie normalerweise bei Ram gewohnt direkt auf den physikalischen Speicher erfolgt.

Man könnte das RamFS auch noch erweitern und den Ram selbst zu so einer Art Realtime Area wie bei XFS umgestallten, und der Rest liegt dann in einer Swap Datei irgendwo auf der HDD. Alles zusammen ergibt ein einziges FS, und alle Reservierungen etc. werden erstmal im Realtime Bereich abgelegt - wird es dort voll wird automatisch auf die HDD oder sonstwas ausgelagert.

Dj_Ninja
17.02.2004, 21:46
Original geschrieben von intel_hasser
Damit könnte man auch Dateizugriff auf große Dateien komplett über den virtuellen Speicher abhandeln (2^32*4GB macht 16 Exabyte, das dürfte erstmal reichen *buck*),...
hmm hat nich irgendwer mal was gesagt wie "kein mensch wird jemals mehr als 64kb ram brauchen" ? :]

i_hasser
17.02.2004, 22:38
Man könnte das Ganze natürlich auch nach oben offen auslegen - zb. eine Funktion, die zurückgibt welche Features vom Kernel supportet werden und welche nicht.
Dann könnte man einen 32bit Integer dazupacken, der die größe in Bit des Selektors angibt - theoretisch wären dann 4 Milliarden Bits für den Selektor machbar, was doch eine recht große Zahl an andressierbarem Speicher macht (in dezimaler Schreibweise hat die Zahl dann läppische 1.3 Milliarden Stellen vor dem Komma *buck*).

Aber das war sowieso so eine Idee, jedes Device etc. muss einen Funktion beinhalten die darüber Auskunft gibt welche Funktionen von dem Device unterstützt werden - so kann man später immer noch etwas reinfrickeln, ohne an Kompatiblität einzubüßen :)

NemesisTN
17.02.2004, 22:59
Wenn du allerdings 4.2 Milliarden Bits für den Selektor hast, dann ist der ja auch schon 512MByte groß.
Wie groß werden dann all deine anderen Daten sein? *chatt* *lol*

//edit:
@Dj_Ninja:
Manchmal hilft auch nur eine Bus-Transplantation... 8)

i_hasser
02.03.2004, 15:40
So, nun gibts mal wieder ein bisschen Gesülze von mir ;)

Da es bei der reinen Theorie ja erstmal nicht viel weiter zu sagen gibt (so wie es aussieht wird das OS so schon 100% experimentell *buck*) gehts mal etwas mehr um die Praxis bzw. die Umsetzung.


Der OS Kern selbst (bzw. der monolithische Teil vom OS) wird ja relativ klein werden. Hauptsächlich müssten da die ganzen FS-Funktionen rein.
Den Kern kann man denke ich Single Tasking gestallten - besser gesagt denke ich, dass es reicht 2 sich abwechselnde Prozesse reinzunehmen.
Das wäre einmal die Behandlung der FS Aufrufe etc. und zum anderen ein Sheduler-Prozess, der dann das Multitasking außerhalb vom Kern zur Verfügung stellt.

Die Prozesse kann man denke ich recht problemlos ins FS integrieren. Ich stell mir das so vor, dass dann bei einem Prozess der Code und die Daten (usw.) als separate Files in einem speziellen Prozess-Verzeichniss vorliegen. Man könnte auch mehrere Code-Files in ein Programm packen, das wäre dann irgendwo das Gegenstück zu den shared libs unter Linux und den DLLs in Windoofs.

So, und der im Kern befindliche Sheduler legt sich auch irgendwo ein Verzeichniss an (oder bekommt gleich ein spezielles FS) - da drinnen liegen dann Links zu den einzelnen Prozess-Verzeichnissen und Informationen vom Sheduler für den Sheduler, wo die Prozesse zuletzt ausgeführt wurden (also alle Register und sonst noch einige Sachen, wie zb. die Prozesspriorität).


Allerdings könnte man hier auch gleich das Multitasking-Konzept etwas abändern.
Normalerweise enthält ein Prozess ja einen oder mehrere Threads, wobei jeder Thread für den Sheduler ein Eintrag ist (also ein Thread nicht mehrmals gleichzeitig ausgeführt wird).
Momentan spricht gegen Multitasking ja hauptsache die Komplexität - es ist viel mehr Aufwand mehrere Threads zu synchronisieren etc. Bei Verzweigungen zb. in DLLs verzweigt der Task auch wirklich - also es gibt einen Sprung zum Code der DLL und dieser Task führt die DLL aus (und kehrt idealerweise irgendwann zum Aufrufprogramm zurück - ist ein Fehler in der DLL wird das Aufrufprogramm auch abgebrochen, weil der Task vom Aufrufprogramm den Fehler erzeugt hat).

Man könnte das alles ja erstmal soweit abkapseln, dass der Task nicht zu der externen Funktion springt, sondern der Sheduler den Task anhält und einen neuen Task erzeugt, der die externe Funktion ausführt - den alten Task könnte man so lange anhalten (oder was eben auch immer).

Das könnte man jetzt auf alle Funktionen im Programm ausweiten (oder von mir aus auch nur auf beliebige Funktionen) - wenn man eine Funktion aufruft wird ein neuer Task erzeugt und der alte solange angehalten.

Bei Realtime Sachen könnte das durchaus einen Vorteil bringen, auf jeden Fall wären die einzelnen Programme aber viel weiter abgekapselt. Bei der Kommunikation der Tasks miteinander müsste man dann natürlich noch was ändern, man könnte zb. beim Task-start Parameter übergeben (die dann auf einen Speicherbereich mit den Verwaltungsinfos zeigen).


... naja, ich schätze da werd ich noch ein bisschen weiterüberlegen müssen, so ganz ausgegoren ist das noch nicht. Am besten sag ich erstmal, was ich mit den Begriffen meine ;)

Prozess -> Programm, das ausgeführt wird.
Task -> Eintrag im Sheduler (sagen wir die Register mit CS:IP) - praktisch ein kleiner Single-Tasking Rechner, wie ein Thread bei zb. Windoofs. Allerdings kann der Task alles mögliche ausführen, ist also nicht auf einen Prozess beschränkt.
Thread -> Teil eines Prozesses, ein Thread kann nicht mehrmals gleichzeitig ausgeführt werden.



Aber mal wieder etwas zur Praxis. Problematisch wird wohl das booten, denn da sind die ganzen Kernel-externen Sachen ja noch garnet geladen (obwohl man zb. einen Speichermanager doch recht schnell braucht).

Das heist, es muss entweder ein großer Loader her, oder wir integrieren das ganze doch wieder soweit, dass es von alleine auf die Beine kommt. Das Kernel-File kann man ja wie schon gesagt als Container gestallten, wo die wichtigsten Module drinnen liegen (der Container könnte zb. ein einfaches FAT Dateisystem haben). Die wichtigsten Sachen wären:

- OS Kern (FS Funktionen und einfacher Sheduler)
- Sheduler und ProzessFS Treiber
- RamFS Treiber und Ramblocktreiber (der ist ja winzig)
- DeviceFS
- Die wichtigsten Treiber (Bildschirm ;))
- Irgend eine art Shell, Skript oder Loader, der das alles so zusammenfrickelt, dass es erstmal läuft ;)

Das müsste alles in den Kernel-Container rein (nebst später Treiber zum Zugriff auf die HDD und sowas).

PuckPoltergeist
03.03.2004, 12:33
Original geschrieben von intel_hasser
Und damit würde das erstmal halbwegs laufen. Das ganze soll als 100%iger µ-Kernel entstehen, das bedeutet, dass der Kernel komplett aus Modulen besteht, und die Treiberverwaltung (oder wie auch immer Verwaltung, da kommen Treiber, Anwendungen und Dienste rein) hätte einen entscheidenden Vorteil: Nix da mit ein Modul für eine Kernel-Version, da würden alle Module immer laufen - sowas wie eine kernelversion gibt es nicht mehr weil eben der gesamte Kernel eine Sammlung von einzelnen Modulen ist.

Dazu würde die Treiberverwaltung auch noch ein paar andere Vorteile bieten, so könnte man problemlos ein wirklich gutes Multitasking realisieren. Gleichzeitig wären die einzelnen Komponenten wirklich getrennt.

Wir hatten die Diskussion zwar schon, aber hier nochmal: Bei einem Mirokernel laufen Treiber und ähnliches (eigentlich alles was möglich ist) im Userspace. Im Kernelspace bleibt nur noch ein minimaler Rest. Eine modulare Aufteilung hat erst einmal noch nichts mit µ-Kernel zu tun. Auch Linux ist modular aufgebaut, aber trotzdem streng monolithisch. Überleg dir das zweimal, ob du wirklich einen µ-Kernel durchziehen willst. Das wird reichlich aufwändig und schlägt auf die Performance.

i_hasser
03.03.2004, 17:38
Der Kernel soll doch nicht zusammengelinkt werden (so wie das bei Modulen bei Linux der Fall ist), sondern der Kernel soll wirklich komplett getrennt werden und auch die Kernelsachen die bei zb. Linux fest mit drinnen sind werden als Treiber ausgelagert - wie zb. auch der Speichermanager.

Und wie war das nochmal mit Linux und µ-Kernel? Linus hats damals nicht gemacht, weil sein 386er dafür einfach zu langsam war? ;)

PuckPoltergeist
03.03.2004, 19:46
Wieso reden wir eigentlich immer aneinander vorbei? ???

Linux ist vollständig monolithisch, aber modular.

Den Speichermanager kannst du nicht auslagern, der muss im Kern bleiben. Genauso die Prozessverwaltung. Davon könnte man zwar Teile in den User-Space verlagern, aber das würde keinen Sinn machen.
Wie schon geschrieben, du bürdest dir eine Heidenarbeit auf, dass als µ-Kernel zu realisieren. Sicherlich ist sowas elegant, sauber, durchdacht, aber das ist EPIC auch. Eleganz um jeden Preis ist eine schlechte Lösung.

i_hasser
03.03.2004, 20:38
Das einzige was monolithisch sein muss und nicht modular aufgebaut sein kann ist der Teil, der die FS Funktionen zur Verfügung stellt, nebst einem kleinen integrierten Sheduler.

Der FS Teil braucht so gut wie keinen Speicher - dem können wir beim booten sagen wir fest 1mb Speicher zuordnen und dann reicht das für immer und ewig, der FS Teil sitzt also in einem Segment für sich allein wo er 1mb (oder von mir aus auch mehrere MB) Speicher zur verfügung hat. Natürlich spricht nichts dagegen den FS Teil so zu gestallten, dass er, wenn ein Speichermanager installiert ist darauf auch zugreift (was aber selten passieren dürfte, überschlag mal kurz wie viele Verwaltungsdaten man in einem MB Speicher unterbringen kann ;)).

Diese Segmentierung für den FS Manager muss der OS Loader erledigen (da es kein Kernel-Image in dem Sinne gibt muss ja ein Loader her, der den Kernel erstmal lauffähig zusammenfrickelt).

So, der FS Manager (nennen wir es einfach mal so) stellt ein paar öffentliche Funktionen bereit, die sich nur um den FS Zugriff drehen - mehr nicht. Schöner wäre es sogar, wenn die Funktionen über den integrierten Sheduler laufen würden - so würden die Tasks die die FS Funktionen aufrufen diese nicht ausführen, der Sheduler könnte einfach einen neuen Task kreieren und den Aufrufer solange anhalten.

So - der Teil vom Speichermanager der sich den anderen Prozessen zeigt ist ja selbst nur ein FS Treiber, den Teil den die anderen Prozesse nicht sehen übernimmt auch der FS Treiber. Das wären nämlich die Funktionen um auf Dateien zuzugreifen. Wenn ein Prozess eine Datei öffnet geht das über den FS Treiber - der mappt dann einen Speicherbereich, in dem sich der Dateiinhalt befindet. Die Zugriffe auf diesen Inhalt laufen dann entweder über eine Exception ab (normale FS), oder werden direkt auf bestimmte Ram Positionen gemappt (RamFS). Das Auswählen der Speicherregion übernimmt dabei der RamFS Treiber, in Kooperation mit dem Ram Blocktreiber.

Für ein Programm sieht die Sache dann so aus:

Einfache Datei:

Zeiger = Öffne "Datei xyz"

*(Zeiger+1 byte)=0x12
// Hier gibt es eine Exception die abgefangen wird -
// der FS Manager sagt dem FS Treiber er soll den entsprechenden Block lesen und mappt ihn an die Position vom Zeiger
// Der Block selbst wird dann in eine Datei irgendwo im RamFS gelesen (und praktisch nur diese Datei gemappt)

Speicher allokieren:

Zeiger = Erstelle Datei "/ramfs/prozesssowieso/neuerBereich" Größe 1234 Byte
// Nun wird dieser Bereich im RamFS allokiert, also einfach eine Datei dieser Größe erstellt
// Der FS Manager mappt diese Datei in den Specherbereich vom erstellenden Prozess

*(Zeiger+1byte)=0x12

// Nun gibt es keine Exception, da (da es sich um eine Datei im RamFS handelt) der FS Manager den Bereich vom Zeiger gleich zur richtigen Stelle im physikalischen Speicher gemappt hat


... naja, ich hoffe es wird ersichtlich, was ich meine. Der Ram Blocktreiber stellt praktisch alle Bereiche des physikalischen Speicher dar. Also Offset 0x12345 zeigt auf das Physikalische Byte 12346 hex im Speicher.

Das RamFS sollte nun natürlich nicht irgend eins sein, sondern ein extra auf die Bedürfnisse zugeschnittenes FS. Es ginge theoretisch aber auch ein einfaches Fat Dateisystem *buck*


Der Vorteil der Sache liegt darin, dass ein großteil vom physikalischen Speicher garnicht gemappt werden muss - es muss wirklich nur der Speicher vom FS Manager und vom gerade laufenden Prozess gemappt sein.
Dann kann man hier natürlich auch viel einfacher ein eigenes Sicherheitskonzept einführen und ist nicht auf das x86 Sicherheitskonzept angewiesen (der Speicher auf den nicht zugegriffen werden darf ist ja idR garnicht gemappt). Tja, und welche Sicherheitsfeatures da möglich sind bestimmt allein das RamFS (bei Fat wären es eher wenige Features ;)).


Ok - der Speichermanager ist nicht komplett modularisiert. Aber irgendwo dann doch wieder ;D
Der FS Manager muss nur mappen, managen tut er den Speicher nicht ;)

i_hasser
17.03.2004, 23:32
Mir ist noch ein bisschen was eingefallen (kann sein, dass ich das schonmal aufgegriffen hatte).

Man könnte mal wirklich versuchen auf stark verschachtelte Scheduler zu setzen. Also nicht nur 2 Scheduler, sondern vielleicht so um die 10 (je nach Bedarf) in verschachtelten Ebenen. Der Vorteil wäre eine viel bessere Lastverteilung, wenn ein einzelner Prozess mal die CPU frisst. Dann könnte man auch einfachere Algorithmen für die Scheduler nehmen (so dass der Overheat möglichst gering bleibt).

Das könnte man auch ins FS integrieren. Aber so richtig bis zum Schluss durch hab ich die Prozessintegration ins FS noch nicht, irgendwie fehlt da noch was. Wie werden die einzelnen Bereiche (Code, Daten, Stack usw.) dargestellt, wie bastelt man das möglichst so zusammen, dass sich daraus auch ein Nutzen ergibt, wie implementiert man das in einen FS-basierten Scheduler...

PuckPoltergeist
18.03.2004, 00:02
Als Spielerei ok, aber wenn man das OS wirklich nutzen will (nicht nur als Design-Studie), ist der Ansatz, alles über Files zu machen nicht wirklich sinnvoll. Ist ein viel zu großer Aufwand, man geht viel zu viele Kompromisse ein, etc.

Was den Scheduler betrifft, nicht schachteln, kombinieren. Mehrere Scheduler sind nur bei mehreren CPUs sinnvoll.

i_hasser
18.03.2004, 00:10
Man könnte die Schedulerschachtelung natürlich wieder auf einen einzenen Scheduler zurückführen, der die Schachtelung intern vornimmt... das könnte man in einem FS schön darstellen *chatt*

Ich denke die FS Geschichte bringt alles in allem mehr Vorteile als Nachteile. Sicher, es ist irgendwo ein recht großer Aufwand das alles passend zu machen (vor allem bei den Prozessen und dem Scheduler). Aber andererseits ist der Vorteil auch enorm - es gibt nicht mehr tausende APIs, sondern nur noch eine einzelne - alles läuft über eine einzige Schnittstelle ab, damit gehören viele Sonderlösungen der Vergangenheit an.

Beispiel: Man will ein einheitliches Rechtemanagement mit ACLs (? glaub das waren Access Controll Lists, kann mich aber auch täuschen - auf jeden Fall meine ich das) implementieren. Dazu enthält ein FS einfach jeweils die ACLs und man jagt das FS Device durch einen ACL Treiber, der wiederum ein FS Device bereitstellt. Da filtert das ACL Device sämtliche ACL-Dateien raus und setzt die Rechte derer entsprechend. So elegant bekommt man das sonst nirgends geregelt.

Oder NUMA könnte man sehr schön über mehrere RamFS realisieren - auch sehr elegant.

PuckPoltergeist
18.03.2004, 13:02
Original geschrieben von intel_hasser
Beispiel: Man will ein einheitliches Rechtemanagement mit ACLs (? glaub das waren Access Controll Lists, kann mich aber auch täuschen - auf jeden Fall meine ich das) implementieren. Dazu enthält ein FS einfach jeweils die ACLs und man jagt das FS Device durch einen ACL Treiber, der wiederum ein FS Device bereitstellt. Da filtert das ACL Device sämtliche ACL-Dateien raus und setzt die Rechte derer entsprechend. So elegant bekommt man das sonst nirgends geregelt.

Was machst du auf x86 mit mehr als vier unterschiedlichen Privilegien?

i_hasser
18.03.2004, 13:36
ACLs sind doch für Rechte auf Dateisystembasis zuständig. Also man kann selbst einem Fat Dateisystem ein Rechtemanagement beibringen.

Das hat mit den PVLs doch nix zu tun, die sind doch auf einer ganz anderen Ebene verankert und stehen für ganz andere Dinge... oder hast du bei Ext3 etwa PVLs? ;)

PuckPoltergeist
18.03.2004, 14:31
Original geschrieben von intel_hasser
ACLs sind doch für Rechte auf Dateisystembasis zuständig. Also man kann selbst einem Fat Dateisystem ein Rechtemanagement beibringen.

Das hat mit den PVLs doch nix zu tun, die sind doch auf einer ganz anderen Ebene verankert und stehen für ganz andere Dinge... oder hast du bei Ext3 etwa PVLs? ;)

Ja, ich war vorhin auf dem falschen Dampfer. Deswegen vergessen wir den Mist, welchen ich da schrieb ganz schnell wieder. :]

Ich bleibe trotzdem dabei, dass die Probleme bekommst, wenn du wirklich alles als Datei behandeln willst.

i_hasser
18.03.2004, 15:06
Man muss sich eben erst alles neu überlegen - nicht FS-basiert gibts schon viele Lösungen wo man einfach abschauen kann ;)

Man müsste die Grundlage auch etwas abändern - nicht alles ist Dateisystem basiert, sondern das Dateisystem lässt sich mit dem System auch darstellen - nebst eben den ganzen anderen Sachen wie Devices, Threads, etc.

PuckPoltergeist
18.03.2004, 15:21
Original geschrieben von intel_hasser
Man muss sich eben erst alles neu überlegen - nicht FS-basiert gibts schon viele Lösungen wo man einfach abschauen kann ;)

Für Speichermanagement genauso wie für Prozessverwaltung. Das ist also kein Argument. Und wenn ich ein neues OS schreibe, ist es gerade Sinn der Sache, dass ich mir gewisse Sachen neu überlege, und nicht auf altes zurückgreife. Dafür bräuchte ich auch nichts neu schreiben.

i_hasser
18.03.2004, 15:33
Hier hast du was neues. Ich denke eher es ist besser sich ein komplett neues Konzept zu überlegen als nur einzelne Sachen zu verändern - Linux hat auch einen neuen Scheduler bekommen, für solche "kleinen" Änderungen braucht man kein neues OS.

Ich denke der Sache mit den Prozessen im FS darstellen fehlt noch der entscheidende Schliff, dann wird auch die Umsetzung wieder deutlich einfacher.

PuckPoltergeist
18.03.2004, 15:43
Ich habe ja auch nichts gegen neues. Ich bin nur der Meinung, für einen sinnvollen Einsatz wird das nicht zu gebrauchen sein. Du kannst mich ja gerne vom Gegenteil überzeugen. ;) Ich glaube halt nicht, dass es wirklich Vorteile bringt, wirklich alles auf Dateien zu reduzieren/abzubilden. Aber vielleicht irre ich mich ja auch, und das OS wird der neue Stern am Softwarehimmel. ;D

i_hasser
18.03.2004, 15:51
:P

Ich mach das aus persönlichem Interesse und nicht um einen neuen Stern am Himmel zu schreiben... wenns das aber trotzdem wird wäre mir das auch recht *buck*

Ich hab ja schon geschrieben, dass sich zb. NUMA über ein RamFS viel leichter realisieren ließe. Genauso eine Ramdisk (die dann sowieso überflüssig wäre, man würde einfach eine Datei im RamFS erstellen und die per LoopDevice in ein BlockDevice verwandeln, wo man dann ein normales FS draufziehen kann).

Für mich ist entscheidend, dass sich die Sache ohne größeren Performanceverlust implementieren ließe, und dass dadurch gleich mehrere APIs komplett eingespart wären, was das Ganze dann auch ohne große Umwege modular macht.

Wenn das nicht per FS realisiert wäre müsste noch eine API her für die Prozess und Speicherverwaltung, und dann könnte das beides nicht mehr als Modul ausgelagert werden sondern wäre fest im Kernel drinnen - will ich net.

PuckPoltergeist
18.03.2004, 16:03
Original geschrieben von intel_hasser
Ich hab ja schon geschrieben, dass sich zb. NUMA über ein RamFS viel leichter realisieren ließe.

Also das mußt du mir jetzt näher erläutern. Geschrieben hast du das, aber erklärt noch nicht.



Wenn das nicht per FS realisiert wäre müsste noch eine API her für die Prozess und Speicherverwaltung, und dann könnte das beides nicht mehr als Modul ausgelagert werden sondern wäre fest im Kernel drinnen - will ich net.

Du kannst Speicher- und Prozessverwaltung grundsätzlich nicht auslagern. Bestenfalls den Scheduler, aber das macht keinen Sinn.

i_hasser
18.03.2004, 16:17
Zur NUMA Geschichte:

Es gibt mehrere RamFS, jedes RamFS steht dabei für den lokalen Speicher einer einzelnen CPU.
Wenn nun neuer Speicher allokiert wird kommt es auf die CPU die den Prozess ausführt an, in welchem RamFS der Speicher reserviert wird. Falls das lokale RamFS aber doch mal voll sein sollte kann man immernoch auf ein anderes RamFS ausweichen.

Der Aufwand das zu implementieren ist minnimal.


Den Speichermanager (da haben wir ja schonmal drüber geredet) kann man auslagern, nämlich indem man dem Kernel zur Bootphase einen fixen Speicherbereich zuteilt mit einem provisorischen Speichermanager, der dann später deaktiviert wird (und dessen Daten optional in den neuen Speichermanager importiert werden, damit man auch die letzten paar kB wieder frei bekommt).


Speichermanager ist bei mir das, was den Speicher verwaltet - das Paging wird vom FS Treiber realisiert. DOS hatte auch schon einen Speichermanager, obwohl es da kein Paging gibt (bzw. war die begrenzte Segmentierung statisch).


Den Scheduler kann man auf ähnliche Weise auslagern, oder man macht doch einige wenige Verschachtelungen - dann gehts ganz Problemlos (wenn der Root-Scheduler nur 2 oder 3 Einträge hat kann der auch sehr schlank gestalltet werden).

PuckPoltergeist
18.03.2004, 16:29
Erklär mir erst einmal, was du unter Modul und unter auslagern verstehst.

i_hasser
18.03.2004, 16:34
Noch ein Vorteil wäre, dass man viel einfacher Cluster realisieren könnte.

Man schaltet die FS 2er verschiedener Systeme einfach komplett zusammen (auf dem einen exportiert man den Root, auf dem anderen mountet man diesen export irgendwo hin und dann nochmal umgekehrt). Dazu muss man praktisch nichts ändern. Dann ist es kein Problem Sound zb. über die Soundkarte eines anderen Rechners auszugeben, oder einen neuen Thread in den Scheduler des anderen Rechners einzufriemeln und all sowas - da verschmelzen die Rechner unten drunter komplett miteinander.

i_hasser
18.03.2004, 16:37
Original geschrieben von PuckPoltergeist
Erklär mir erst einmal, was du unter Modul und unter auslagern verstehst.

Damit meine ich, dass der Treiber nichts mit dem OS Kern (eigentich nur der FS Verwaltungsteil) zu tun hat. Der Treiber wird später irgendwo ins FS eingehangen und kommt mit dem Kern nicht in Berührung.

PuckPoltergeist
18.03.2004, 16:45
Ich bin mir absolut sicher, dass du damit eine Bauchlandung machst, wenn du so die Speicherverwaltung auslagerst. Na gut, mach es. Ich lass mich überraschen. ;D

i_hasser
18.03.2004, 16:57
Hast du das Prinzip noch nicht verstanden?

Wie reserviert ein Prog Speicher: Es erzeugt im Mountverzeichnis vom RamFS einfach eine Datei und öffnet diese (das öffnen der Datei läuft über den Kernel, das RamFS hat mit dem Kernel selbst nix am Hut).
Da alle Speicherzugriffe über Memory Mapped IO (mit Paging Support (im alten Sinne), also es können mehrere Pages gewählt werden) stattfinden, und der Kernel aber sieht, dass es sich um ein RamFS handelt wird (in Kooperation mit dem RamFS) kein Exception-basierter Zugriff ausgeführt, sondern es wird gleich auf den entsprechenden Bereich im Ram gepaged.

Für Userprogs und Treiber und überhaupt alle laufenden Prozesse gibt es keine andere Möglichkeit Speicher zureservieren. Natürlich ist es trotzdem kein Problem das als klassisches malloc() zu verpacken (hinter malloc muss dann eine Funktion stehen, die die Datei anlegt usw.).


Der Kernel enthält ja praktisch nix und braucht daher auch nur sehr begrenzt Speicher (und bekommt zb. 1mb fest mit einem sehr kleinen Speichermanager). Wenn ein RamFS geladen wird ist der Kernel aber auch in der Lage die weitere Speicherverwaltung über das RamFS laufen zu lassen (man könnten das RamFS sogar wieder umounten, dann muss der Kernel Speichermanager erstmal alles aus dem RamFS wieder in den Kernelspeicher verschieben).

Ich hab nicht gesagt, dass ich dem Kernel keinen Speichermanager geben würde - auch beim Scheduler etc. trifft das net zu.
Die integrierten Sachen sind aber darauf ausgelegt abgeschaltet zu werden, sowie das passende externe Modul geladen wird. Da die integrierten Module desswegen sowieso wenig zu tun bekommen (nur durch den Kernel und den Bootup Code) können die auch sehr schlank ausgelegt werden - während der Bootup Phase könnte man zb. komplett auf Multitasking verzichten (damit meine ich aber nur das laden und initialisieren des Kernels selbst und nicht das laden der zusätzlichen Module und Treiber).

PuckPoltergeist
18.03.2004, 18:16
Zuerst einmal, schmeiß bitte nicht so schamlos die Begriffe durcheinander (MMIO). ;)

Du vereinfachst bei deinem Konzept nicht. Ganz im Gegenteil, du fügst zusätzliche, unnötige APIs ein. wie hast du dir das vorgestellt? Für jeden Prozess ein RamFS? Für jeden Speicherbereich (Variable z.B.) ein file? Du ersetzt Adressraum durch RamFS bzw. Speicherbereich durch file. Was versprichst du dir davon?
Dazu kommt noch die Frage, schreibst du dafür den Compiler, Linker, Assembler?

i_hasser
18.03.2004, 20:05
Das MMIO passt wirklich nicht so ganz... aber es ist relativ ähnlich ;)

Es gibt bei einem normalen Rechner nur ein einzelnes RamFS - das umspannt den gesamten nutzbaren Ram.
Die Prozesse reservieren sich da drinnen Speicherblöcke wie mit einem malloc() - der Speichermanager kann von der Sache her sogar genauso gestalltet sein wie im Moment, nur die Ansteuerung erfolgt eben über das RamFS statt über irgendwelche API Funktionen (man braucht nach wie vor nur die Methoden um Dateien zu erstellen/öffnen usw.).
Der letzte Unterschied besteht darin was passiert wenn ein Speicherbereich reserviert werden soll, danach gibts keinen Unterschied mehr - auch bei der Performance nicht.
Von der Sache her könntest du sowas erreichen, indem du in Linux ein MemFS einführst, was einfach nur alle Handles im Speichermanager als Dateien auflistet - dann sähe es schonmal wie das RamFS aus.

In der Praxis laufen auch immer mehrere Speichermanager kaskadiert zusammen, also ein malloc() in C muss sich keinesfalls an das Betriebssystem richten. Da Pages sowieso eine größe von 4kb haben wäre es blödsinnig für jedes char 4kb zu opfern nebst einem Eintrag im Speichermanager - der OS Speichermanager kann nämlich nur mit 4kb Pages umgehen, alles andere ist ihm zu klein.

Und genauso würde es auch über das RamFS ablaufen, eine einzelne Variable würde da niemals reserviert werden.
Dafür wäre der Overheat einfach viel zu groß - wie bei aktuellen OSs eben auch. Der Vorteil wäre jedoch gegenüber den aktuellen Lösungen, dass jeder Prozess nicht direkt auf spezielle Funktionen des Speichermanagers zugreifen muss, sondern auch dafür die FS-Funktionen nutzt (wie für alle anderen Sachen eben auch).

Die Prozesse bzw. der Code wird untereinander also garnicht mehr wie bei Windows oder Linux zusammengelinkt (DLLs in Windows, Kernel Module in Linux) sondern bleibt stets getrennt. Das schafft nicht nur platz für deutlich mehr aber kleinere Threads (ohne Overheat), sondern trennt das alles auch im Fall von Fehlern besser ab.


Am Compiler ändert sich da nichts großartig. Die Standart Includes müssen natürlich alle neu geschrieben werden (malloc usw. muss alles auf die FS-Funktionen übersetzt werden) - und so viel ist es dann nicht mehr. Viel kann man auch in einem anderen OS zusammensetzen, der gcc ist da ja sehr variabel. Man könnte dem OS auch direkt ELF Files oder dergleichen geben, die Möglichkeiten sind da extrem vielfältig. Endziel wäre natürlich ein portierter gcc, der auch ohne irgendwelche Umwege direkt ausführbare Progs für das OS erzeugt.

Assembler muss da sehr wenig herhalten. Der Kernel wird ein Multiboot Image, da ist nur ein Assembler Header erforderlich. Ansonsten gibts hier und da mal inline assembler, und an einigen Stellen muss für den Kernel sicherlich assembler herhalten. Aber die Programme die letztendlich für das OS geschrieben werden sollen brauchen keinerlei Assembler, ich denke es ist auch kein so großes Problem das alles POSSIX konform hinzubekommen (also ein einfaches ./configure;make;make install tuts dann auch - so in etwa, nicht dass ich hier jetzt über irgendwelche POSSIX-Definitionsfallen stolpere ;)).

PuckPoltergeist
18.03.2004, 20:31
Original geschrieben von intel_hasser
Es gibt bei einem normalen Rechner nur ein einzelnes RamFS - das umspannt den gesamten nutzbaren Ram.
Die Prozesse reservieren sich da drinnen Speicherblöcke wie mit einem malloc() - der Speichermanager kann von der Sache her sogar genauso gestalltet sein wie im Moment, nur die Ansteuerung erfolgt eben über das RamFS statt über irgendwelche API Funktionen (man braucht nach wie vor nur die Methoden um Dateien zu erstellen/öffnen usw.).

Ich gehe mal davon aus, dass du dich hier nur etwas ungeschickt ausdrückst, sonst würdes du dem Kind nur einen anderen Namen geben, und alles bleibt so wie es ist.


In der Praxis laufen auch immer mehrere Speichermanager kaskadiert zusammen, also ein malloc() in C muss sich keinesfalls an das Betriebssystem richten.

Hä? Wo soll denn der Speicher sonst herkommen?


Da Pages sowieso eine größe von 4kb haben wäre es blödsinnig für jedes char 4kb zu opfern nebst einem Eintrag im Speichermanager - der OS Speichermanager kann nämlich nur mit 4kb Pages umgehen, alles andere ist ihm zu klein.

Diese Einschränkung besteht auf Hardwareebene. Da kommst du auch mit einem dateibasiertem Speichermanager nicht drumherum.



Und genauso würde es auch über das RamFS ablaufen, eine einzelne Variable würde da niemals reserviert werden.

Sondern? Du öffnest eine Datei und schreibst da hinein?



Die Prozesse bzw. der Code wird untereinander also garnicht mehr wie bei Windows oder Linux zusammengelinkt (DLLs in Windows, Kernel Module in Linux) sondern bleibt stets getrennt. Das schafft nicht nur platz für deutlich mehr aber kleinere Threads (ohne Overheat), sondern trennt das alles auch im Fall von Fehlern besser ab.[QUOTE]

Wie willst du denn bitteschön ein Programm zur Auführung bringen?

[QUOTE]
Am Compiler ändert sich da nichts großartig. Die Standart Includes müssen natürlich alle neu geschrieben werden (malloc usw. muss alles auf die FS-Funktionen übersetzt werden) - und so viel ist es dann nicht mehr. Viel kann man auch in einem anderen OS zusammensetzen, der gcc ist da ja sehr variabel. Man könnte dem OS auch direkt ELF Files oder dergleichen geben, die Möglichkeiten sind da extrem vielfältig. Endziel wäre natürlich ein portierter gcc, der auch ohne irgendwelche Umwege direkt ausführbare Progs für das OS erzeugt.

Da halte ich mich erst einmal zurück. Compilerbau steht noch auf meiner ToDo-List.



ich denke es ist auch kein so großes Problem das alles POSSIX konform hinzubekommen (also ein einfaches ./configure;make;make install tuts dann auch - so in etwa, nicht dass ich hier jetzt über irgendwelche POSSIX-Definitionsfallen stolpere ;)).

Das Teil nennt sich POSIX, mit einem S. Du solltest vorsichtig damit sein, dir irgendwelche Kompatibiliäten ans Knie zu nageln. POSIX kann ganz schön widerlich werden.

i_hasser
18.03.2004, 20:45
Original geschrieben von PuckPoltergeist
Ich gehe mal davon aus, dass du dich hier nur etwas ungeschickt ausdrückst, sonst würdes du dem Kind nur einen anderen Namen geben, und alles bleibt so wie es ist.


Wo denn genau?
Denkbar wäre ein RamFS gemountet nach zb. /ram. Wenn ich dann die Datei /ram/irgendwelcheProzessInformationenoderwasauchimmer/bereich1 mit 10mb erstelle hab ich 10mb Speicher reserviert.



Hä? Wo soll denn der Speicher sonst herkommen?
Klar kommt der irgendwo vom OS - aber der jeweilige Prozess enthält nochmal einen kleinen Speichermanager nur für sich allein. Der Prozess reserviert sich von OS bei einem malloc(1) beispielsweise 4kb Speicher - und im internen (wirklich sehr einfach gestrikten) Speichermanager reserviert er sich 1 byte.
Beim nachsten malloc(1) reserviert er sich im internen Speichermanager ein weiteres Byte. Und das geht solange weiter, bis die 4kb voll sind - dann werden vom OS weitere 4kb angefordert.
Der Vorteil ist, dass der OS Speichermanager dadurch nur einen sehr geringen Overheat hat, da er nicht so viele Einträge verwalten muss (die komplette Speicherverwaltung läuft also kaskadiert ab).



Diese Einschränkung besteht auf Hardwareebene. Da kommst du auch mit einem dateibasiertem Speichermanager nicht drumherum.
Ja - und diese Einschränkungen haben trotzdem Vorteile und die will ich mit dem RamFS auch garnicht umgehen, das ist (wie auch jetzt) Sache der jeweiligen Prozesse.



Sondern? Du öffnest eine Datei und schreibst da hinein?
Ich hoffe das erübrigt sich damit ;)




Da halte ich mich erst einmal zurück. Compilerbau steht noch auf meiner ToDo-List.
Schwierig wäre es nicht, der gcc spuckt ohne Probleme Binärcode aus, und damit kann man sowieso alles zusammenbasteln wie man will. FreeDOS wird zb. mit WatCom compiliert - das geht auch problemlos.




Das Teil nennt sich POSIX, mit einem S. Du solltest vorsichtig damit sein, dir irgendwelche Kompatibiliäten ans Knie zu nageln. POSIX kann ganz schön widerlich werden.

Ok, werds mir merken ;) - ich meinte damit eigentlich nur, dass ich die Sache im Endeffekt möglichst ähnlich zu Linux halten will, so dass man ein Linux Programm ohne großen Aufwand auch portieren kann (viele Progs kann man ja unter Linux sowieso schon für so ziemlich jede Plattform compilieren, und mit Cygwin kann man vieles auch gleich mit für Windows compilieren).

PuckPoltergeist
18.03.2004, 20:55
Original geschrieben von intel_hasser
Wo denn genau?
Denkbar wäre ein RamFS gemountet nach zb. /ram. Wenn ich dann die Datei /ram/irgendwelcheProzessInformationenoderwasauchimmer/bereich1 mit 10mb erstelle hab ich 10mb Speicher reserviert.

So hatte ich das verstanden.




Klar kommt der irgendwo vom OS - aber der jeweilige Prozess enthält nochmal einen kleinen Speichermanager nur für sich allein. Der Prozess reserviert sich von OS bei einem malloc(1) beispielsweise 4kb Speicher - und im internen (wirklich sehr einfach gestrikten) Speichermanager reserviert er sich 1 byte.
Beim nachsten malloc(1) reserviert er sich im internen Speichermanager ein weiteres Byte. Und das geht solange weiter, bis die 4kb voll sind - dann werden vom OS weitere 4kb angefordert.
Der Vorteil ist, dass der OS Speichermanager dadurch nur einen sehr geringen Overheat hat, da er nicht so viele Einträge verwalten muss (die komplette Speicherverwaltung läuft also kaskadiert ab).

Also genauso wie jetzt auch schon. Darum hat sich der Compiler zu kümmern.



Ok, werds mir merken ;) - ich meinte damit eigentlich nur, dass ich die Sache im Endeffekt möglichst ähnlich zu Linux halten will, so dass man ein Linux Programm ohne großen Aufwand auch portieren kann (viele Progs kann man ja unter Linux sowieso schon für so ziemlich jede Plattform compilieren, und mit Cygwin kann man vieles auch gleich mit für Windows compilieren).

Da werden aber nicht alle Verwaltungsstrukturen über den Haufen geworfen. Jedes mir bekannte OS orientiert sich am Hardwareaufbau. Dadurch, dass du das umbaust, fügst du mind. eine weiter Abstraktionsschicht ein, die sich wahrscheinlich auch nur sehr schwer beherrschen lassen wird.

i_hasser
18.03.2004, 21:06
Ein malloc() zb. wird unter Linux oder Windows ja jeweils völlig anders umgesetzt - und genauso würde das auch auf dem OS passieren.
Genauso alle anderen speziefischen Funktionen, was die Standart Libs eben alles hergeben ;)

Klar müsste man ab und zu mal an ein paar kleinen Stellen umbauen - aber das lässt sich wohl kaum vermeiden. Aber ein simples grep dürfte man auch ohne Änderungen compilieren können.


Der Vorteil der FS Geschichte läge eben wie gesagt in der guten abkapselung von Code - nur noch sehr wenig ist miteinander verbunden... eigentlich ist alles mit den FS Funktionen verbunden, und mit nichts weiter (grob gesagt).


Momentan kümmert sich übrigens nicht der Compiler um den kleinen Speichermanager - der ist auch irgendwo in den Standart Libs festgehalten, den muss man nur umschreiben. Der Compiler an sich ist ja ziemlich "dumm", der kann nur einfachsten C Code in Assembler übersetzen. Die Stärke liegt darin Symbole aufzulösen usw. und desswegen gibts auch immer so einen riesigen Schwap an Include Files, bzw. gibts den Code in den Standart Libs dazu ja meist schon compiliert - der Source dazu wäre nicht gerade wenig, und den muss man ändern um das an ein anderes OS anzupassen (neben dem Linker für zb. Win32).

MingW32 ist zb. ein Port von gcc auf Win32 - eine völlig andere Umgebung. Aber der Kern ist ein nicht so stark veränderter gcc, "nur" mussten eben so ziemlich alle Standart Libs neugeschrieben werden und umgeändert werden.

PuckPoltergeist
18.03.2004, 21:09
Wie wird denn in deinem OS ein

int x;

realisiert?

i_hasser
18.03.2004, 21:14
Lokale Variablen laufen bei gcc immer über den Stack, und der ist Hardware implementiert ;)

PuckPoltergeist
18.03.2004, 21:18
Das meine ich nicht. Der Compiler reserviert für die Variable einen entsprechenden Speicherbereich. Wie soll das bei deinem OS gehandhabt werden?

i_hasser
18.03.2004, 21:24
Wenn du eine lokale Variable meinst - es gibt mehrere Techniken mittels BasePointer den Stack als variablen Speicherbereich zu benutzen ohne die normale PUSH/POP Funktionalität einzubüßen.

Wenn du eine globale Variable meinst - die Programme werden intern in bestimmte Abschnitte unterteilt, es gibt zb. 1mal Daten und 1mal Code. Globale Variablen werden in den Datenteil gepackt und dann entsprechend werden beim Laden des Progs die Teile in den Ram sortiert.

PuckPoltergeist
18.03.2004, 21:33
Womit du wieder auf Speicheradressen arbeitest, nicht auf Dateien. Das kannst du kapseln, wird aber ein Heidenaufwand. Du mußt damit alle deine Entwicklerwerkzeuge anpassen. Machst du das nicht, verletzt du dein Konzept, alles ist eine Datei.
OS-intern bringt dir das nichts, als zusätzliche Komplexität und somit Fehlerquellen. Extern hast du natürlich eine einheitliche Schnittstelle zur Hardware, aber ist das den Aufwand wert?

i_hasser
18.03.2004, 21:53
Nein, wir reden immernoch aneinander vorbei!

Der Stack ist für lokale Variablen zuständig. Das ist unter Dos so, unter Win16, unter Win32, unter Linux und eigentlich überall sonst auch - auch auf nicht x86 Architekturen.

Wie die Sache mit dem RamFS funktioniert hab ich schonmal geschrieben, das Programm öffnet die Datei einfach - mehr ist es nicht. Der Dateizugriff ist immer... jetzt fällt mir nichts passenderes ein, ich nenn es memory mapped io - so läuft der Zugriff auf jede Datei ab. Sei es eine auf der HDD oder eben eine im RamFS.
Auf der HDD funktioniert das dann wie bei einigen 64bit Server Betriebssystemen, die Datei wird in den Adressraum vom Programm eingeblendet. Ein Zugriff löst eine exception aus (weil an die entsprechende Stelle kein Ram gepaged ist) und veranlasst den FS Treiber dazu den entsprechenden Block von der Quelle in den Ram zu lesen und an die entsprechende Position im Ram zu pagen - dann wird an die Aufrufposition zurückgekehrt und der Befehl wiederholt, mit dem Ergebniss dass der Zugriff auf die Page erfolgreich verläuft (weil ja dort jetzt Ram hingepaged wurde).

Das erfordert unten drunter so ziemlich keine Modifikationen - du musst zwischen der x86 Architektur, dem was ein Compiler erzeugt und dem OS unterscheiden. Das sind 3 verschiedene Dinge die nichts miteinander zutun haben.

Klar läuft im Endeffekt irgendwo alles über Speicheradressen, was anderes ist auch garnicht möglich, weil x86 (wie auch viele andere Architekturen) nichts anderes anbietet.

PuckPoltergeist
18.03.2004, 21:59
Ich habe dich schon verstanden. Entweder du verwässerst dein Konzept (alles ist eine Datei), oder du baust wirklich alle Werkzeuge um.
Du sagst, das Programm öffnet einfache eine Datei, wenn es Speicher benötigt. Was für Speicher? Der Stack ist auch Speicher. Nimmst du den aus, und betrachtest dabei nur den Heap, hast du OS-intern ein noch viel größeres Chaos zu bändigen.

PuckPoltergeist
18.03.2004, 22:07
Original geschrieben von intel_hasser
Auf der HDD funktioniert das dann wie bei einigen 64bit Server Betriebssystemen, die Datei wird in den Adressraum vom Programm eingeblendet. Ein Zugriff löst eine exception aus (weil an die entsprechende Stelle kein Ram gepaged ist) und veranlasst den FS Treiber dazu den entsprechenden Block von der Quelle in den Ram zu lesen und an die entsprechende Position im Ram zu pagen - dann wird an die Aufrufposition zurückgekehrt und der Befehl wiederholt, mit dem Ergebniss dass der Zugriff auf die Page erfolgreich verläuft (weil ja dort jetzt Ram hingepaged wurde).

Bei welchem OS funktioniert denn das so?

i_hasser
18.03.2004, 22:12
Nein - ein Programm, das geladen wird, wird im ersten Schritt irgendwohin ins RamFS kopiert. Dann wird das Programm in die einzelnen Bestandteile (Code Teil, Daten Teil etc... uA eben auch Stack) zerlegt (also in Files gesplittet - die Ausführbare Datei vom Programm enthält ja all diese Teile nur je nach Format anders verpackt) und in einen Adressraum gepaged - und dann kanns losgehen.

Beispiel:

Die ausführbare Datei ist prog.elf

Als erstes wird dann also prog.elf nach /ram/xyz/prog.elf kopiert.
Dann wird die Datei gesplittet (praktisch wird das linken wieder rückgängig gemacht - das passiert auch bei Win32 und Linux so, sieht man es eben nicht im Dateisystem).
Jetzt haben wir sagen wir prog.elf.code und prog.elf.data .
Dazu wird jetzt noch eine prog.elf.stack erzeugt - den Stack kann man aber auch in den Datenteil legen (idR gibts noch viel mehr Teile - siehst du, wenn du dich mit compilern beschäftigst).

Nun kommt der große Schritt - es wird ein neuer Adressraum vom FS Device erzeugt, dahinein werden diese Teile gepaged (ich hab oben ja schon geschrieben, dass der Paging Teil auch fest in den Kernel muss und direkt mit dem FS Teil verbunden ist) und dann kann es losgehen.

An Werkzeugen muss man da nix umbauen (sag mir doch einfach wo du meinst man müsse umändern).


Möglich wäre auch eine kleine Startroutine (die vom FS Teil für jeden neuen Thread erstmal als Programm in einen leeren Adressraum geladen wird) die dann durch einfache fopen die anderen Teile nachlädt und diese dann auch ausführt (und sich selbst dann aus dem Ram wieder rauswirft... eigentlich könnte man da direkt eine einzige Routine im RamFS verankern die dann bei jedem neuen Thread zum Einsatz kommt... da diese Routine keine Variablen Daten braucht die sich nicht über einen Stack realisieren ließen kann da sogar immer die selbe Routine gepaged werden).


Das Grundmodell für einen Prozess sieht immernoch sehr ähnlich aus, es gibt einen virtuellen (4GB bei x86) Adressraum in den alles gepaged wird was nötig ist. Aber eine gewisse Segmentierung ließe sich auch hier problemlos unterbringen (ohne was an den Werkzeugen zu ändern) - so dass bei 32bit x86 zb. 4GB Code und 4GB Daten zur Verfügung stehen (und vielleicht noch 4GB Stack).

PuckPoltergeist
18.03.2004, 22:17
Einen Interpreter für x86-Binärcode. *lol*

War dein Argument nicht, dass du das ganze vereinfachen wolltest? Du baust nur eine zusätzliche Abstraktionsschnittstelle ein, welche das ganze noch viel komplexer macht.

i_hasser
18.03.2004, 22:23
hä ???

Sorry, wovon redest du? Es war nie von einem Interpreter die Rede. Zeig doch mal genau, was du meinst - falls es das ist was ich denke: Die Routine zum Starten von einem Prog ist kein Interpreter! Der paged nur die Daten entsprechend und führt dann das eigentliche Programm aus.

PuckPoltergeist
18.03.2004, 22:31
Halt, nein, nicht mal interpretiert. Du fügst nur eine zusätzliche Dartstellungsschicht ein. Was soll das denn bitteschön bringen? Irgendwie wird das langsam witzlos. ???

i_hasser
18.03.2004, 22:34
Kannst du mir mal bitte sagen was du eigentlich meinst? Ich kann dir in keinster weise folgen, aber es klingt nicht danach als würden wir über die selben Dinge reden :]

Sicher ist die Sache mit den FSs vorwiegend eine Darstellungssache. Aber so ziemlich alle Dinge werden über das FS gesteuert, alle Treiber werden irgendwo im FS eingebunden... die komplette Steuerung des Betriebssystems geht über das FS.

PuckPoltergeist
18.03.2004, 22:55
Ich sehe das Konzept dahinter nicht (so wie du es beschreibst).

Des weiteren macht es in meinen Augen keine Sinn, alles als Datei darzustellen, wenn es intern doch in seiner ursprünglichen Form bleibt.

i_hasser
18.03.2004, 23:02
Das Konzept ist, dass alles über eine einheitliche Ebene abläuft. Damit lassen sich viele Dinge derart einfach und elegant realisieren weil man so gut wie nichts dazuprogrammieren muss und die einheitliche Ebene für so ziemlich alles ausgelegt ist... das ist der Vorteil ;)

Beschäftige dich mal ein bisschen mit Compilern und vor allem x86 und OS Desings in der Tiefe (nicht mit irgendwelchen theoretischen Skripten sondern schnapp dir einfach ein kleines OS wie DOS oder sowas und schau dir an wie es funktioniert), dann merkst du sicherlich was ich die ganze Zeit meine.

PuckPoltergeist
18.03.2004, 23:07
Die einheitliche Ebene hast du eben nicht, weil du es intern nicht ändern kannst. Wenn es ganz unten in der alten Form weiter besteht, hast du gar nix gekonnt, wenn du eine Abstraktionsschicht draufpappst.

Bei dir merkt man im Gegenzug, dass du dich mit den theoretischen Grundlagen noch nicht beschäftigt hast. Auch ein Linus Torvalds hat nicht einfach drauf los programmiert (auch wenn man das manchmal denken möchte).

i_hasser
18.03.2004, 23:17
Ok, jetzt halten wir uns gegenseitig vor, was wir nicht wissen :P

Es ist egal ob das unten drunter alles einheitlich abläuft oder nicht (was genau meinst du damit eigentlich? 2 verschiedene Dinge können wohl kaum auf identische Weise funktionieren, das geht nicht).

Fakt ist: Für Steuerung und Datenein/ausgabe werden abstrakte und vor allem immer einheitliche Funktionen zur Verfügung gestellt. Das FS Prinzip ist sehr abstrakt, aber trotzdem geht da nichts über mehrere Abstraktionsebenen, das hängt alles am FS Baum.

Diesen Weg ging auch schon Linux - schau dir mal die Devices an. Das ist genau das selbe was ich mit allen Bereichen wo es möglich ist machen will. Linux ist genau desswegen so leistungsfähig, weil es weniger Ebenen gibt auf die sich die Funktionsgruppen aufteilen (als zb. bei Windows).

Und nun schau dir mal an wozu Skripte unter Linux alles in der Lage sind! Skripte sind auf eine Ebene beschränkt - nämlich die FS Ebene. Und alles was auf dieser Ebene implementiert ist kann man mit Skripten beeinflussen. Sei es die Helligkeit des LCDs meines Schleppis, das auslesen der verbleibenden Batteriekapazität, die Temperatur meiner CPU... . Das alles geht unter Linux nur, weil die Funktionen über eine einheitliche Ebene erreichbar sind - über einen Dateisystemartigen Baum.

Und genau das greife ich auf und treibe es noch weiter, wodurch folgt, dass man noch mehr Dinge auf einfachem Wege erledigen kann (genug Beispiele hab ich ja gebracht).

... da hast du wohl in der entsprechenden Vorlesung geschlafen? ;)

PuckPoltergeist
18.03.2004, 23:29
Original geschrieben von intel_hasser
... da hast du wohl in der entsprechenden Vorlesung geschlafen? ;)

Ich war nur einmal in der Vorlesen (das erste mal).

Linux bietet mit den device-files eine Schnittstelle für den Userspace zu den Geräten. Du willst die Geräte darüber steuern (sofern ich dich richtig verstanden habe). Das wird nicht funktionieren.
Ich füge nur eine weitere Abstraktionsebene ein, wenn ich wirklich Nutzen daraus ziehe. Jede Abstraktionseben bedeutet weiter unten mehr Aufwand.

i_hasser
18.03.2004, 23:45
Nein, das tut sie nicht. Schau mal Linux an, schau dir zb. das neue sysfs an, schau dir /proc an... das alles hat schon einen Sinn ;)

Relativ ähnlich denke ich mir das - nur dass ich unten drunter das alles so abändere, dass es eben nicht mehr einen großen Aufwand bedeutet das alles auf einen dateisystemartigen Baum zu abstrahieren (ich nenn die Sache jetzt einfach mal SysTree - ist nervig das immer zu umschreiben ;)).

Im SysTree ist alles enthalten was es im Rechner (Hardware und Softwaremäßig) gibt. Im gegensatz zu Linux wird hier auf eine einzige Ebene abstrahiert und nicht auf einige wenige (also praktisch wird der Trend fortgesetzt).
Windows sieht da zb. völlig anders aus - da gibt es tausende von APIs und Schnittstellen für die verschiedensten Sachen, desswegen ist das OS auch bei weitem nicht so flexibel wie zb. Linux.

Linux bietet übrigens noch deutlich mehr als nur eine Schnittstelle zu den Geräten... oder wie auch immer du Gerät definierst. Die Devices und Steuerungsdateien sind keine Schnittstellen zu den Geräten, sondern zu den Treibern die die Geräte steuern - im Endeffekt also zu einfachen Prozessen (bzw. speziellen Prozessen - eben den Treibern).

Und genau da ist ein Punkt wo man sehr gut verallgemeinern kann und nichts an Funktionsumfang einbüßt -> ergo lohnt es sich (der Geschwindigkeitsverlust hält sich sehr stark in Grenzen).
Lohn der Mühe ist ein sehr viel größerer Funktionsumfang (verallgemeinerungen haben ja meißtens erstmal zur Folge, dass Nuancen verloren gehen). Am einfachsten ist es eben wenn ich dir das mit Beispielen zeige. Einen anderen Rechner per Remote Desktop steuern? Kein Problem, ist ähnlich wie ein Cluster - nur dass nur ein Rechner den SysTree exportiert und der andere den eben irgendwo einmountet.

PuckPoltergeist
18.03.2004, 23:52
Über ProcFS und SysFS wird nichts gesteuert. ProcFS war ursprünglich nur dazu da, Laufzeitinformationen von Prozessen verfügbar zu machen. Mit der Zeit kam da dann immer mehr dazu, was da eigentlich gar nicht rein gehört. Deswegen wurde SysFS geschaffen, eine Möglichkeit, um Kernelobjekte zu exportieren. Man kann sicherlich ein paar Verhaltensweisen darüber beeinflussen, aber die Funktionalität der Treiber wird damit nicht wirklich angefaßt.
Außerdem sprachen wir über devices. :-*

i_hasser
18.03.2004, 23:52
Ein OS ist eine Abstraktionsebene zur Hardware - so könnte man OS definieren. Problem heute: Die OS selbst stellen wieder eine Vielzahl von verschiedenen Ebenen bereit (Linux weniger, Windows mehr), wodurch wir zwar die Probleme durch verschiedene Hardware beseitigen, jetzt alles aber OS Speziefisch anlegen (da Linux weniger verschiedene Ebenen bereitstellt als Windows (was gut ist) lassen sich zb. Anwendungen auch einfacher auf andere OSs portieren, die anderen UNIXe haben ja auch weniger Ebenen als Windows).

Der Ansatz von mir würde das soweit wie es mir eben möglich war einschränken, ziel ist es die gesamte Hardware (wobei ich Software nicht ausschließen möchte) auf so wenig Ebenen wie möglich zu abstrahieren. Bei mir wären das der SysTree und die FS Funktionen - 2 Ebenen. Bei Linux sind es schon deutlich mehr.

Dass dadurch irgendwo ein bisschen Systemleistung verloren geht, und dass es die Sache auch nicht immer leichter macht ist doch klar - rate mal wieso Konsolen bei Spielen teilweise schneller sind als PCs, obwohl die Rechenleistung der Konsole deutlich geringer ist - bei einer Konsole kann man direkt die Hardware programmieren, weil diese immer dieselbe ist.

Aber eins ist klar - es macht die Sache immer Leistungsfähiger, und Leistungsfähigkeit macht ein gutes OS aus (was soll ich mit einem OS mit dem ich nix anfangen kann :P).

i_hasser
18.03.2004, 23:58
Original geschrieben von PuckPoltergeist
Außerdem sprachen wir über devices. :-*

Das ist doch völlig wurscht. Hab ja gerade eben nochmal was dazu geschrieben.

Wenn ich die Display Helligkeit meines Schlepptops steuere geht das über einen Treiber - sicher. Aber ein Treiber ist nichts anderes als ein normaler Prozess mit einigen Sonderrechten (Hardwarezugriff) und (je nach OS) einer speziellen Position (bei Linux zb. Ring0 woraus die Sonderrechte resultieren).

Oder andersherum: Normale Progs sind wie Treiber Prozesse, jedoch mit eingeschränkten Rechten.

Und im Endeffekt: Sowohl Treiber als auch normale Software und alles was eben so auf den Rechner läuft (Kernel ausgeschlossen - jetzt werden wir uns sicherlich gleich wieder mit irgendwelchen Kernelsachen beharken, desswegen schließe ich jetzt alle Sachen die modular sind aus) sind Prozesse mit jeweils unterschiedlichen Zugriffsrechten.

Ergo ist ein Device in Linux ein Interface zu einem handelsüblichen Prozess, und das kann man nun andersherum realisieren - ein jeder Prozess hat Devices/Files als Interface. Und genau das will ich machen.

PuckPoltergeist
19.03.2004, 00:05
Es geht mir nicht um die Rechenleistung deines Rechners, sondern die des Schwamms zwischen deinen Ohren. ;) Du willst viele kleine Abstraktionsschichten durch eine große ersetzen. Das ist ok, das ist gut, das... hat ein Problem. Die vielen kleine Abstraktionsschichten lassen sich nicht ersetzen. Evtl. lassen sie sich verkleinern, aber sie bleiben vorhanden. Das Resultat ist, dass du auf die vielen kleine Abstraktionsschichten eine große fette draufsetzt. Von außen sieht das klasse aus, wunderbar. Aber innen hast du einen riesen Haufen Komplexität hinzugefügt. Du erreichst genau das Gegenteil vom dem, was du eigentlich willst. Das ganze Ding wird fehleranfälliger und schwerer zu warten.
Nun, ich will dich nicht davon abhalten. Versuche dich daran, realisiere es. Irgendwann wirst du zu dem Punkt kommen, an dem du sagst "Das wars, das lohnt nicht".

PuckPoltergeist
19.03.2004, 00:08
Original geschrieben von intel_hasser
Und im Endeffekt: Sowohl Treiber als auch normale Software und alles was eben so auf den Rechner läuft (Kernel ausgeschlossen - jetzt werden wir uns sicherlich gleich wieder mit irgendwelchen Kernelsachen beharken, desswegen schließe ich jetzt alle Sachen die modular sind aus) sind Prozesse mit jeweils unterschiedlichen Zugriffsrechten.

Auch der Kernel ist ein Prozess. Es gibt nichts anderes als Prozesse. Man kann einen Prozess noch in Threads unterteilen, aber alles darunter ist alleine nicht mehr lebensfähig.

i_hasser
19.03.2004, 00:17
Original geschrieben von PuckPoltergeist
Es geht mir nicht um die Rechenleistung deines Rechners, sondern die des Schwamms zwischen deinen Ohren. ;) Du willst viele kleine Abstraktionsschichten durch eine große ersetzen. Das ist ok, das ist gut, das... hat ein Problem. Die vielen kleine Abstraktionsschichten lassen sich nicht ersetzen. Evtl. lassen sie sich verkleinern, aber sie bleiben vorhanden. Das Resultat ist, dass du auf die vielen kleine Abstraktionsschichten eine große fette draufsetzt. Von außen sieht das klasse aus, wunderbar. Aber innen hast du einen riesen Haufen Komplexität hinzugefügt. Du erreichst genau das Gegenteil vom dem, was du eigentlich willst. Das ganze Ding wird fehleranfälliger und schwerer zu warten.
Nun, ich will dich nicht davon abhalten. Versuche dich daran, realisiere es. Irgendwann wirst du zu dem Punkt kommen, an dem du sagst "Das wars, das lohnt nicht".

Und es geht doch ;D

Ich hab ein paar Beiträge vorher schonmal geschrieben was für Device-Typen ich für sinnvoll halte (uA sind dabei auch Streams dabei - ein großteil von Java setzt auf Streams auf, willst du mir sagen das funktioniere auch nicht? ;) Inzwischen ist mir auch noch eine etwas bessere Einteilung eingefallen, aber da arbeite ich im moment auch noch dran... es gefällt mir noch nicht).

Also es ging um die Devices :P. Es gibt bei allen Dingen eine Ebene ab der man damit alles darstellen kann. Bei Programmiersprachen wäre BrainFuck ein gutes Beispiel - so simpel, trotzdem kann man algorithmisch damit alles realisieren (es gibt Progs die mit BrainFuck PI berechnen usw.).

Genauso sieht es auch mit der Abstraktionsebene SysTree aus. Mit den verschiedenen Devices, einer kleinen Interrupt implementierung (besser Event Handler, bei Interrupts denke ich immer an den guten alten PIC), Links (auf alles mögliche) usw. ist es durchaus möglich alles darzustellen.
Und das wird dann kein Aufsatz auf die vielen keinen APIs, sondern wirklich nur eine große - die Vorteile davon dürften klar sein.


PS Ist der Scheduler auch ein Prozess? Sicherlich... jedoch wäre es sinnlos den auch immer so zu betrachten, weil das alles in einem Baum sitzt und nicht in einer einfachen Liste. Mit Prozessen lässt sich ein Baum nicht so ohne weiteres darstellen.

PuckPoltergeist
19.03.2004, 00:24
Original geschrieben von intel_hasser
PS Ist der Scheduler auch ein Prozess?
Ein eigener Prozess wohl nicht, aber möglicherweise ein eigener Thread


Mit Prozessen lässt sich ein Baum nicht so ohne weiteres darstellen.

Wieso denn nicht? Natürlich lassen sich Prozesse in einem Baum anordnen. Wird unter Unix auch gemacht.

Du versuchst hier das VFS auf die Spitze zu treiben. Bis jetzt sieht ein Dateizugriff unter Linux so aus:

Prozess -> VFS -> Dateisystemtreiber -> Controllertreiber

Wie soll das bei dir aussehen?
Prozess -> VFS -> Dateisystemtreiber -> VFS -> Controllertreiber?

i_hasser
19.03.2004, 00:31
Ich nenn die Funktionen zum Zugriff auf das FS jetzt einfach mal SysTreeCtrl ;)

Prozess -> SysTreeCtrl -> FS Device -> SysTreeCtrl -> BlockDevice(=IDE Controllertreiber)... tja, also von der Sache her so wie du es beschrieben hast.

Der Dateisystemtreiber enthält dann zb. einen Link, der auf das zu benutzende BlockDevice gesetzt werden muss. Wird der Treiber dann aktiviert (zb. durch etwas in der Art echo 1 > driverstate) wird der Link schreibgeschützt und der FS Treiberprozess erzeugt ein neues FS Device im SysTree. Und das kann dann per SysTreeCtrl irgendwohingemountet werden (das könnte man auch anders lösen ohne das SysCtrl zu bemühen... ist mir eben nur so eingefallen).


So, ich mach mich dann ins Bett.

stav
20.03.2004, 15:11
ich könnte Testsystem(e) zur Verfügung stellen ;) von AMD über VIA bis Intel... alles steht hier rum. (geil so nen PC verrückten Vadder zu haben *lol* )

i_hasser
20.03.2004, 15:16
Danke für das Angebot - aber da wirds im nächten halben Jahr wohl noch so ziemlich keinen Code geben, also nix was man testen könnte ;)

Die Sache ist eher längerfristig angelegt, momentan schreib ich so ziemlich alles auf was mir an Design-Sachen einfällt (ok, das mach ich schon seit über einem Jahr) und gehe das erstmal theoretisch durch.

i_hasser
05.04.2004, 14:09
Naja, falsch gedacht - es gibt ein bisschen Code.

Hab mich jetzt mal durch die GRUB Multiboot Spezifikationen gelesen und einen klitze kleinen Multiboot-Kernel den man über Grub oder Lilo booten kann erstellt - nebst Sourcetree für den kompletten OS Loader.

Da das hier sowieso auch als Notiz-Sammelstelle dienen soll mal ein paar Gedanken über das Aussehen:

Das Kernel-Image fängt mit dem Multiboot Krempel an (Header, ein bisschen Startup Code), danach kommt der OS Loader und danach ein FAT Image in dem sich erstmal das nötigste für einen komplett lauffähigen Kernel befinden soll (nötigsten Module, sehr kleine Shell und die nötigsten Kommandos wie cp, rm, mv usw. - dazu noch etwas zum Module Laden und FS Einbinden).

Damit würde der Kernel erstmal komplett aus dem Ram laufen, ohne dass irgend ein zusätzlicher Dateisystemtreiber oder gar Blocktreiber reinmüsste.

Der Kernel selbst (bestehend aus den Paging Mechanismen und den FS Funktionen) wird auch erstmal einen kleinen Speichermanager und ein KernelImage Dateisystemtreiber enthalten.
Die sollen aber später durch Module ersetzt werden (vorher werden natürlich die Informationen über vergebenen Speicher usw. ausgetauscht).

i_hasser
08.04.2004, 14:42
So, ich war in letzter Zeit auch nicht ganz Faul.

http://www.i-hasser.de.vu/hostos/img1.ima.gz

Das ist ein gziptes Floppy Image mit GRUB, einem kleinen OS Loader und darin eingebettet der Container für die Kernel Files.
Mometan gibts nur ein paar Meldungen, aber unten drunter ist die Basis schonmal da :)


Wer es sich mal anschaun möchte - einfach mit einem Packer entpacken (WinACE kommt afaik mit .gz klar) und dann mit WinImage auf eine Floppy ziehen... oder einfach als Floppy Image in VMWare oder Bochs einbinden.

Die Linuxer habens mal wieder einfacher, ein einfaches gzip -d und dd genügt ;)

i_hasser
14.04.2004, 19:06
Man könnte über das FS auch eine (strikte) Klassenstruktur realisieren. Also nicht nur so ein bisschen, sondern eben wirklich strikt - und dafür mit Vererbungen, Interfaces usw.

gipskopf
14.04.2004, 19:39
Ein richtiges Betriebssystem, wie Windows, oder Linux?? Wann ist es fertig? Verkauft ihr es? Wenn ja, nehm ich eins ;D

i_hasser
14.04.2004, 19:49
Na klar doch, ich nehme mir einen Tanklaster voll schwarzen Tee und programmiere die nächsten 3 Jahre durch (ohne zu Schlafen versteht sich).

Dann wären wir vielleicht bei der Funktionalität von OS/2 2.1 oder bei den einfachsten Linuxen.


Nein, das wird (erstmal ?) kein großes OS. Das soll erstmal recht klein werden, nur das absolut nötigste soll rein (eine simple Shell, kein HDD Zugriff also nur der KernelContainer im Ram... so dass es erstmal läuft).

Wichtig ist mir dabei das Design - also wie es unten drunter zugeht, vielleicht wird das OS eine Inspiration für irgend jemand anders oder (was der Idealfall wäre) es melden sich irgendwann mal noch andere Leute mit Erfahrung die auch mitproggen (schaut euch mal die Menge an kleinen OSs bei zb. osdev.net an, es gibt schon viele solche kleinen Projekte) dann wäre das natürlich ideal, aber mometan existiert ja (fast) alles nur hypothetisch.

Und eine GUI käme sicherlich zu allerletzt. Ich will das alles so kapseln dass es nicht "das große OS" gibt, sondern viele kleine voneinander wirklich unabhängige Module - so können auch viele Leute unabhängig daran programmieren... oder eben auch nicht ;)


Auf jeden Fall macht es Spaß ;D

SchliZzZa
15.04.2004, 00:22
haste viellleicht mal gute c++ anfänger tuts auf deutsch da? wäre supi ;)

i_hasser
15.04.2004, 00:28
Passt nicht ganz in den Thread, oder?

Mir fällt jetzt auch nix ein - das nächste mal bei sowas besser eine PN nehmen ;)



PS Nur weil das OS vielleicht Klassen zur Verwaltung nutzt heist das noch lange nicht, dass es in C++ geschrieben wird. Normalerweise macht man sowas in Assembler bzw. größtmöglichenteils in C (ohne ++) und ich werd da keine Ausnahme machen.

TiKu
15.04.2004, 00:34
Da Du so ein Java-Fan bist: Schreib doch ein Java-OS.;D Auf www.osnews.com wurde vor geraumer Zeit mal sowas vorgestellt.

@FrankWhite: Frag am besten mal im German Developer Network (http://www.planet3dgames.de/forum/forumdisplay.php?f=21) auf Planet 3d Games.

i_hasser
15.04.2004, 00:49
Tja, interessant wäre es sicher. Aber ohne Java fähige CPU wohl nicht wirklich schnell ;)

Mit Java kann man schon tolle Sachen machen, bin vor einer Weile mal über einen Java Scheduler gestolpert - den hat jemand geschrieben um mehrere Java Progs in einer VM ausführen zu können, weil die Ladezeiten einer VM immer realtiv hoch sind.

Also schreiben wir einfach mal einen Java Scheduler *buck*

TiKu
15.04.2004, 00:58
Original geschrieben von intel_hasser
Mit Java kann man schon tolle Sachen machen, bin vor einer Weile mal über einen Java Scheduler gestolpert - den hat jemand geschrieben um mehrere Java Progs in einer VM ausführen zu können, weil die Ladezeiten einer VM immer realtiv hoch sind.*g* Mit Java 1.6 wird das zum Glück endlich anders. Aber ich glaube, ich ziehe grad Deinen Thread ins OT...

i_hasser
15.04.2004, 16:51
Hab über das Klassenbasierte OS nochmal nachgedacht. Von der Sache her ist es genau das was ich mit dem FS darstellen wollte (und was darüber ja auch sehr gut geht).


also wenn wir zb. einen Treiber haben besteht der aus einer Klasse (mit optionalen Subklassen) der Form



class xyz : public abc::SimpleDriver
{
public:
xyz();
~xyz();

int start();
int stop();
int restart();


BlockDevice* parameter1;
BlockDevice output_device;

StreamDevice controll;
File status;

private:

(wasauchimmer)
};


Wenn der Treiber geladen wird wird eine neue Instanz der Klasse erzeugt und zur angegebenen Position im Dateisystem "verlinkt" (der Treiber befindet sich aber nur dort).

also das könnte dann so aussehen (filetree):

[...]/driverabc [DEVICE]
[...]/driverabc/parameter1 [LINK]

[...]/driverabc/controll [DEVICE]
[...]/driverabc/controll/[...] (hier ist dann das was bei jedem StreamDevice dabei ist)

[...]/driverabc/status [FILE] (kann man sich mit zb. cat anschauen - Statusinformationen eben)

[...]/driverabc/output_device [DEVICE]
[...]/driverabc/output_device/[...] (hier ist dann das was bei jedem BlockDevice dabei ist)

[...]/driverabc/start [FUNCTION] (das sind grundlegende Treiberfunktionen die über das FS auch dargestellt werden und auch ausgeführt werden können)
[...]/driverabc/stop [FUNCTION]
[...]/driverabc/restart [FUNCTION]

So. Das könnte zb. ein einfacher Cache auf Blockbasis sein. Mal ein Beispiel zum Umgang damit:

loaddevice xyz /dev/cache
cd /dev/cache
ln /dev/hda -s parameter1 (ist ein bisschen unsauber weil wir ja keinen Link neu erstellen sondern einen vorhandenen setzen, aber das ist der beste linux-befehl der mir jetzt eingefallen ist)
exec start
(so, das wars schon - jetzt können wir zb.)
mount output_device /mnt/abcdef - das BlockDevice mounten,
cat status - den Status vom Cache-Treiber anzeigen, oder
writetostream "Cachesize:1024kb" control - ein paar Parameter vom Device umändern.


So war das mit der FS Geschichte gemeint, und so macht es denke ich auch durchaus einen Sinn. Für die Kontrolle von irgendwelchen Treibern sind nicht mehr spezielle Libs erforderlich (wie zb. die sensor-libs für Zugriffe auf lm_sensors), sondern das kann man alles über die Shell machen.
Abgeleitete Klassen und sowas kann man hier auch wunderbar zum Einsatz bringen.

PuckPoltergeist
15.04.2004, 22:00
Es macht keinen Sinn Unterstützung für OO in einem Betriebssystemkern unterzubringen. Es verzichtet nicht ohne Grund so ziemlich jeder OS-Hersteller darauf. Gab mal eine hübsche Diskussion auf LKML darüber. Vielleicht finde ich das bei Gelegenheit wieder. Quintesenz ist, dass evtl. erworbene Vorteile bei weitem nicht den notwendigen Aufwand aufheben. Das soll aber niemanden hindern, objektorientiert zu programmieren, ganz im Gegenteil. Auch der Linux-Kernel ist objektorientiert aufgebaut (zumindest teilweise). Es erfordert nur wesentlich mehr Disziplin, da ja die Sprach keinerlei Hilfsmittel dafür gibt.

i_hasser
15.04.2004, 22:07
Du hast das denke ich ein bisschen falsch verstanden. OO ohne Hilfsmittel erzeugt einen recht großen Aufwand, das ist richtig - aber das will ich auch nicht machen.

Das FS ist praktisch die Objektverwaltung, darüber wird OO komplett abgewickelt. Der Aufwand das im Code zu implementieren ist von der FS Verwaltung (die man in einfacher Form sowieso immer braucht) nicht wirklich groß. Man könnte mit ein paar passenden Includes/Makros könnte man das wirklich problemlos auf so eine Klassendefinition reduzieren, nicht nur bei Programmen sondern eben auch bei OS-Sachen (da das ein µ-Kernel ist sind die Treiber ja sowieso näher am "OS" selbst als bei einem Monolithischen OS, da viele Sachen die bei einem monol. OS direkt im Kernel wären als Treiber realisiert werden).

Was spricht deiner Meinung nach dagegen das OS großteilig OO zu realisieren? Die Performance? Heute haben Bürorechner 3GHz und mehr, da ist das wohl eher unwichtig was vom OS verpulvert wird.
Außerdem - die OO Verwaltung wird ja auch neu geschrieben (bzw. ist Dateisystemorientiert), da kann man auch vieles optimieren. Optionen die Zugriffe ermöglichen (erstellen, öffnen, schließen, löschen usw.) dauern relativ lange, aber wichtiger ist, dass die eigentlichen Zugriffsfunktionen (lesen/schreiben) nicht lange brauchen (müssen), da kann man nämlich vieles gut optimieren.


PS Übrigens ist ein jedes Java-OS komplett OO, anders geht es ja garnet ;)

PuckPoltergeist
15.04.2004, 22:21
Original geschrieben von intel_hasser
(da das ein µ-Kernel ist sind die Treiber ja sowieso näher am "OS" selbst als bei einem Monolithischen OS, da viele Sachen die bei einem monol. OS direkt im Kernel wären als Treiber realisiert werden).

Das ist Dummfug. Was kann näher am Kern sein, als direkt im Kern? Im Gegensatz zum monolithischen Kernel laufen die Treiber im µ-Kernel ja in getrennten Adressräumen.



Was spricht deiner Meinung nach dagegen das OS großteilig OO zu realisieren?

Da hast du etwas falsch verstanden. ;) Ich bin nicht dagegen etwas objektorientiert zu realisieren, ganz im Gegenteil. Ich bin nur dagegen, die Unterstützung dafür in den Kern einzubauen. Der Aufwand für den ganzen Spaß wäre ganz einfach zu groß. Es müßte ja alles von Hand implementiert werden, angefangen bei der Datenkapselung (ok, vielleicht nicht wirklich schlimm), über Vererbung bis hin zu Ausnahmebehandlung, Templates, RTTI und dergleichen. Lohnt sich meiner Meinung nach nicht. Das gehört in höhere Ebenen, wie es z.B. mit der Standardbibliothek von C++ realisiert wird.

Nebenbei bemerkt, wo finden denn wirklich Java-basierte Betriebssysteme Anwendung? Sicherlich geht sowas, hatte ich auch schon vor einer ganzen Weile mal angemerkt, macht nur nicht sonderlich Sinn. Und auch bei 3GHz-Maschinen muss man die Leistung nicht verschleudern.

i_hasser
16.04.2004, 00:07
Du hast ein Detail überlesen ;)

Das OO wird über das FS realisiert. Damit ist der Kern eigentlich noch ohne OO, nur die komplette Treiberverwaltung (und dank µ-Kernel werden viele Dinge als externer Treiber realisiert, das meinte ich übrigens auch so, desswegen hatte ich es auch so geschrieben...).

Wie im Beispiel oben. In den Treibern selbst kann alles ohne OO zugehen, die Klassenstruktur hab ich nur hingeschrieben um die Ähnlichkeit zu verdeutlichen. Ein einfaches OO ist übrigens leichter zu realisieren als du denkst, da reicht ein einfaches struct mit Funktionszeigern aus - hab selbst auch schon ein OO Programm in C entworfen ;) (und bin dann auf Java umgestiegen weil es bequemer, einfacher aber vor allem portabler ist).

PuckPoltergeist
16.04.2004, 08:09
Original geschrieben von intel_hasser
Du hast ein Detail überlesen ;)

Das OO wird über das FS realisiert. Damit ist der Kern eigentlich noch ohne OO, nur die komplette Treiberverwaltung (und dank µ-Kernel werden viele Dinge als externer Treiber realisiert, das meinte ich übrigens auch so, desswegen hatte ich es auch so geschrieben...).

Wie im Beispiel oben. In den Treibern selbst kann alles ohne OO zugehen, die Klassenstruktur hab ich nur hingeschrieben um die Ähnlichkeit zu verdeutlichen. Ein einfaches OO ist übrigens leichter zu realisieren als du denkst, da reicht ein einfaches struct mit Funktionszeigern aus - hab selbst auch schon ein OO Programm in C entworfen ;) (und bin dann auf Java umgestiegen weil es bequemer, einfacher aber vor allem portabler ist).

Ich sage ja auch nicht, dass es unendlich schwer ist objektorientiert zu programmieren. Es braucht nur wesentlich mehr Disziplin des Programmierers, wenn die Sprache es nicht unterstützt. Wenn man da Mist baut, merkt man das meist erst zur Laufzeit. GTK+/GNOME ist auch oo entworfen, obwohl dafür "nur" C genommen wird. Genauso der Linux-Kernel, der ist auch in weiten Teilen oo, und da wird auch "nur" C benutzt. Es geht, gar keine Frage. Man hat halt nur keine Unterstützung durch das benutzte Werkzeugt (Compiler).
Wenn ich dich richtig verstanden habe, soll dein Programmiermodell ja eh nur intern greifen. Was dann draußen drum gebaut wird (shell, GUI...) wird davon eh nicht berührt. Insofern halten sich die Auswirkungen davon eh in Grenzen. Du mußt halt nur aufpassen, dass du dir selber kein Bein stellst. ;)

i_hasser
16.04.2004, 13:49
Ja, das muss ich wohl.

Das "besondere" an dem OO ist ja aber, dass der User es aktiv beeinflussen kann - sogar direkt über die Shell. Wenn man ein neues Device erstellt kann man die Befehle oben von einen Skript ausführen lassen oder auch selbst eingeben - und andere Sachen damit machen.

Ist dann eben einfacher einen Cache zb. für was anderes zu benutzen und sowas.

PuckPoltergeist
24.05.2004, 13:48
Kann das mal jemand ins Programmier-Forum verschieben? Da geht es nicht so schnell unter.

i_hasser
24.05.2004, 14:40
Gute Idee (ich darf leider net :()!

i_hasser
12.08.2004, 03:58
Bin vor einer Weile auf einen wirklich guten Text von Intel gestoßen. Deckt genau das ab was ich brauch - Segmentierung, Paging und Multitasking-Desingansätze.

Zu haben ist der Text in 3 Teilen von der OS-Seite überhaupt: http://www.nondot.org/sabre/os/articles/ unter Protected Mode -> Specific Protected Mode Flavors -> 386 Programmers Guide.

i_hasser
16.10.2004, 16:09
So, inzwischen hab ich mich wieder etwas damit beschäftigt und so einige Sachen konkretisiert.

Ich denke es wird eher ein kleiner Mix aus monolithischem Kernel und µKernel.

Konkret soll in den monolithischen Kernel der Scheduler, der Memory Manager auf Page Basis (hat nix mit malloc() zu tun), der Interrupt Handler und der OS Tree (habs einfach mal so getauft - der Baum, wo sich alle Prozesse mit allen Funktionen etc. eintragen und über den dann Treiber etc. auch miteinander kommunizieren).


Bin mir aber gerade bei einer Sache nicht sicher wie ich es machen will, nämlich wie Threads mit OS-Funktionen kommunizieren.

Gibt 2 Möglichkeiten, entweder per Call Gate oder per Software Interrupt. Wenn jemand mehr zu dem Thema weis - immer her mit der Meinung ;). Wäre vielleicht auch mal interessant zu wissen, wie Linux und Windoofs das machen (müsste irgendwo in der C-Lib verankert sein).


Momentan tendiere ich zu der Interrupt-Geschichte, weil das einerseits nicht nur meine Meinung ist und es andererseits imho sauberer ist und besser ins Konzept passt.

PuckPoltergeist
16.10.2004, 16:17
Original geschrieben von i_hasser
So, inzwischen hab ich mich wieder etwas damit beschäftigt und so einige Sachen konkretisiert.

Ich denke es wird eher ein kleiner Mix aus monolithischem Kernel und µKernel.

Kann ich nicht empfehlen, weil genau das der Punkt ist, an dem die ersten µKernel krankten. Entweder konsequent das µKernel-Konzept durchgezogen, sprich wirklich nur IPC in den Kern, oder gleich monolithisch. Alles andere ist nicht empfehlenswert.
Bei Bedarf kann ich zu den µKernel auch noch etwas ausholen, und das näher erläutern.



Bin mir aber gerade bei einer Sache nicht sicher wie ich es machen will, nämlich wie Threads mit OS-Funktionen kommunizieren.

Gibt 2 Möglichkeiten, entweder per Call Gate oder per Software Interrupt. Wenn jemand mehr zu dem Thema weis - immer her mit der Meinung ;). Wäre vielleicht auch mal interessant zu wissen, wie Linux und Windoofs das machen (müsste irgendwo in der C-Lib verankert sein).

Momentan tendiere ich zu der Interrupt-Geschichte, weil das einerseits nicht nur meine Meinung ist und es andererseits imho sauberer ist und besser ins Konzept passt.

Zu Windows kann ich nix sagen. Unter Linux läuft das via Interrupt.

i_hasser
16.10.2004, 16:33
Na dann werd ich das auch per Interrupt machen. x86 sieht dafür nämlich eigentlich explizit Gates vor.

Zum Mix aus monolithischem und µKernel: Also allgemein gesehen wird das schon ein vollständiger µKernel. Nur stellt der ja gewisse Anforderungen (vorhandenes Memory Mangament, vorhandener Scheduler etc.) - und das kommt zusammen in einen monolithischen Kern (der Memory Manager muss ja zB. auf der selben Ebene wie der Scheduler stehen, weil der Scheduler auch den Memory Manager braucht).

Eigentlich war ja mal angedacht das wirklich alles komplett und vollständig in Einzelteile zu zerlegen. Das geht beim Start nicht so ohne weiteres, wesswegen ich das ganz essenzielle doch erstmal in einen Kern packen will, möglicherweise können dann einzelne Threads aber doch noch die Funktion von den Kernkomponenten übernehmen, so dass es im Endeffekt garkeinen Kern mehr gibt (bis auf den Scheduler, aber wirklich nur den).

cr4wler
09.04.2006, 12:42
projekt eingeschlafen?