Autor Thema: Das Konzept der LAPI  (Gelesen 18590 mal)

T0ast3r

  • Gast
Gespeichert
« am: 27. August 2005, 10:44 »
Ein Wort zur API

Viele haben schon nach dem Konzept der API gefragt.
Nun möchte ich das Konzept hier veröffentlichen:

1. Die API besteht aus mehreren DLLs.
DLL steht für Dynamic Link Library, also für Librarys, die dynamisch in den Speicher geladen werden.
Bei der API werden aber viele DLLs beim Start in den Speicher geladen, also nicht dynamisch.
Dynamisch geladen werden nur DLLs der API, die NICHT wichtig für das System sind.
So würde eine DLL, die Funktionen für den Joystick unterstützt, NUR bei BEDARF in den Speicher geladen.

2. Jede DLL wird in den Speicher in ein Segment geladen, welches in der GDT beschrieben ist.
Die Art des Segmentes MUSS ein Call-Gate sein, welches bei "normalen" DLLs der API ein Call von einer Privilegstufe 3 erlauben muss.
Dann kann es je nach Anwendungsgebiet mit einer Privilegstufe 0 weiterarbeiten oder auch eine andere.

3. Jede DLL (bzw. Library) besitzt einen Header, in dem wichtige Informationen abgespeichert werden, die das System über Größe, Funktionen usw. informiert.
Weiters kann an dem Header erkannt werden, ob es sich bei der betreffenden Datei tatsächlich um eine DLL oder Library handelt, die eben ausführbar ist.
Der Header ist zu diesen Zeitpunkt noch nicht vollständig definiert, jedoch gibt es schon (von mir) erste Niederschriften und Überlegungen, die jedoch noch in Arbeit sind.

4. Um eine DLL zu laden, muss man den Interrupt 80h mit der passenden Funktionsnummer aufrufen. (Funktion: Load Library)
Die Dokumentation des Interrupt 80h (mit der Funktionsliste usw.) ist (derweil) bei mir zu kriegen.
Wenn sie fertig ist, und der Code dazu natührlich auch, werde ich sie dann auf den ftp Server posten.
(bis dahin sind sie ausschließlich bei mir zu bekommen)

5. Das mit den Fuktionen (bzw. Unterfunktionen) ist noch nicht so ganz geklärt.
Höchst wahrscheinlich ist folgendes Szenario:
Wer nun die Funktion XY der DLL "Drive" aufrufen will, muss als erstes die Library wie oben beschrieben laden.
Mit dem bekommten Handle, wird die Funktion GetProcAdress des Int 80hs aufgerufen, und schon griegt man den Einspringpunkt.
Den sichert man sich in einer Variable und man kann wie folgt die Funktion aufrufen:

call dword [Variable_die_Einspringpunkt_beinhaltet]

Das wird das Grundkonzept sein.
Wie nun genau Int 80h aussehen wird, plus die Fuktionsnummern und der ganze bla bla bla werde ich noch ausarbeiten.

Hier noch der aktuelle Stand der LAPI:

Derzeit exisitiert erst eine Library, die allerdings noch als DLL umgeschrieben werden muss, da ursprünglich von Interrupt-Handler Librarys die Rede war.
Wie gesagt, diese Lib heißt "Drive" und managed Laufwerkszugriffe mit oder ohne Handle.
Wer mehr wissen will oder die (schon längst fertige) Doku, der soll eine E-Mail an T0ast3r@gmx.at schicken oder hier im Forum das schreiben.

Übrigens leitet sich LAPI von CommOS API ab, also (eigentlich) LOST API.

@DDR_RAM: Wie sieht es eigentlich mit den Interrupts aus? Wann und wodurch werden die Interrutps initialisiert?
@hannibal: Ich erwarte noch eine Reaktion in Form von einer Mail.

Wer mit an der API proggen will, soll sich hier im Forum (eindeutig) melden!

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 27. August 2005, 12:05 »
Sollte LOST nicht eigentlich ein Microkernel werden? Dieses API Konzept ist ja eigentlich ein Monolitischer Kernel mit Modulen.

Welches Dateiformat wird denn für die Executables und Libraries verwendet? Wenn ihr ein eigenes benuzt, müsst ihr ja auch einen eigenen Linker für das Format schreiben.

T0ast3r

  • Gast
Gespeichert
« Antwort #2 am: 31. August 2005, 18:11 »
@SSJGohan:

LOST ist und bleibt ein microkernel.
Was soll daran (verdammt noch mal) exotisch sein? (exokernelhaft)
das ist es ja:
Die API han wir nicht in eine Kernel Datei, sondern in mehreren sogennanten DLLs.
Dateiformat?
Die Endung ist ja im  Grunde genommen *****egal.
(wir können ja .sys oder .lib nehmen)
Also kann man Dateiformat so nicht sagen...
Wie gesagt besitzt jede DLL einen HEader, so wie ihn auch exe Dateien unter Windows besitzen.
Und wegen des Linkers:
Wir leben in einer Assembler Welt!
Der Header wird einfach mit db, dd usw. eingefügt!
Das is nix mit Linker!
(ich mein wegen 512 Bytes einen eigenen Linker basteln?
- da kann man doch das ganze direkt am ANfang im Code reinschreiben)

beste Grüße,

T0ast3r

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 31. August 2005, 18:41 »
Das Konzept des Microkernels ist es, Treiber im Userlevel als eigene Prozesse laufen zu lassen, die dann über IPC/RPC kommunizieren. Das bringt den Vorteil, das ein Treiber nicht das gesammte System abstürzen lassen kann, und das System sicherer ist. Dein Design ist ein Monolitischer Kernel mit Modulen. Die Treiber laufen in Ring0 und werden als Module geladen.

Wenn man den Header mit dd und db einfügt werden keine Relocations möglich sein, die ihr für das dynamische Laden von Modulen aber braucht.

Mit Dateiformat war eigentlich nicht die Endung gemeint, sondern der Aufbau der Dateien.

mfg,
SSJ7Gohan

T0ast3r

  • Gast
Gespeichert
« Antwort #4 am: 03. September 2005, 09:56 »
Der Aufbau ist fest vorgeschrieben.
Da hab ich eine eigene Doku.
WEnnst sie haben willst schreib, dann schick ich sie dir per email

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #5 am: 03. September 2005, 10:42 »
Es ist absolut egal ob du Sachen nun einkompilierst oder später erst in den Kernelspace reinlädst, es bleibt ein monolithischer Kernel, einmal komplett statisch und einmal modularisiert! ;)
*post*

T0ast3r

  • Gast
Gespeichert
« Antwort #6 am: 04. September 2005, 09:56 »
also wenn das "modularisiert" ist, dann ist es ja eh gut, so kann man immer einzelne DAteien updaten, und muss nicht gleich den ganzen Kernel "auswecheseln", was ja auch nicht während der Betriebszeit des OSes gehen würde.
Also ich stehe zu diesen Konzept, eben das mit den DLLs.
Die DLLs sind ja eigentlich nur die API!
So machts ja auch Windows (ungefähr)!
Natührlich habe ich mir das Konzept eben von Windows angeschaut, und da ich es im Prinzip gut fand, hab ich es mehr oder weniger übernommen.
Sollte jemand ein besseres haben oder eine verbesserung finden, so soll er sie mir melden, ich überlege dann ob es besser passt.

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 04. September 2005, 11:37 »
Das DLL Konzept ist aber unsicher, da jeder Treiber alles machen könnte, was er möchte, wenn er in Ring0 läuft. Wegen eines Fehlers in einem Treiber kann so das gesammte System abstürzen.

Windows macht das ganze auch nicht so, wie du es machen willst.
Bei Windows laufen im Hintergrund Prozesse ("Dienste"), welche die Hardware Resourcen verteilen usw.
Die DLLs stellen soweit ich weiß nur das Interface für die normalen Programme bereit, um auf die Hardware zuzugreifen.

In einem Microkernel ist jeder Treiber ein Prozess. Falls eine Anwendung auf die Hardware zugreifen möchte, macht sie normalerweise einen RPC (Remote Procedure Call). Der Prozess wird gewechselt, die Parameter werden zwischen den Stacks kopiert, und eine Funktion im Treiberprozess wird aufgerufen. Den Prozessen können über die IO Bitmap des TSS ausserdem noch Zugriffsrechte auf bestimmte Hardwareteile gegeben werden.

In meinem OS benutze ich das folgende Konzept:
Zugriff auf Hardware erfolgt entweder:
1. Durch Module
2. Durch Treiber als Prozesse
3. Durch die Anwendung direkt

Immer wenn ein Prozess/Modul auf die Hardware zugreifen muss, benutzt er einen Systemaufruf namens ioRequest() und holt sich damit Zugriff auf einen bestimmten Hardwareteil. Nachdem er mit dem Zugriff fertig ist, ruft er ioRealese() auf, um den Hardwareteil wieder freizugeben. Treiber behalten den Zugriff normalerweise solange sie im Speicher sind, damit sie Exklusiven Zugriff haben, und damit nicht so oft Systemaufrufe benutzt werden müssen, da das ja nicht gerade die schnellsten Instructions sind. Falls eine Anwendung jetzt in einen Treiber springen will, kann sie den Systemaufruf threadEnter() benutzen, um in einen anderen Thread zu springen. In Module kann mithilfe eines normalen jumps gesprungen werden. Der Kernel stellt ausserdem noch Shared-Memory Funktionen bereit, um schnellen Datenaustausch zwischen den Prozessen zu ermöglichen.
Das eigentliche API wird entweder als Shared-Lib oder als Statische Lib in das Programm gelinkt. Das API lässt sich sehr leicht ändern, es kann z.B. ein POSIX kompatibeles API und ein Objekt Orientiertes API parallel existieren.
Ich hatte vor, als Modul einen CORBA ähnlichen Service bereitzustellen, um auf die Resourcen über Objekte leicht zugreifen zu können. Damit lassen sich ausserdem leicht Teile des Systems austauschen und man kann leicht auf Resourcen auf anderen Rechnern zugreifen.

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #8 am: 04. September 2005, 17:34 »
Zitat von: T0ast3r
also wenn das "modularisiert" ist, dann ist es ja eh gut, so kann man immer einzelne DAteien updaten, und muss nicht gleich den ganzen Kernel "auswecheseln", was ja auch nicht während der Betriebszeit des OSes gehen würde.
Also ich stehe zu diesen Konzept, eben das mit den DLLs.
Die DLLs sind ja eigentlich nur die API!
So machts ja auch Windows (ungefähr)!
Natührlich habe ich mir das Konzept eben von Windows angeschaut, und da ich es im Prinzip gut fand, hab ich es mehr oder weniger übernommen.
Sollte jemand ein besseres haben oder eine verbesserung finden, so soll er sie mir melden, ich überlege dann ob es besser passt.


Du kannst es natürlich so machen, aber sei dir bewusst das es dann nun mal sicher KEIN Microkernel ist und schreibe es bitte dann auch nicht dran weil es schlichtweg eine falsche Bezeichnung ist.
*post*

T0ast3r

  • Gast
Gespeichert
« Antwort #9 am: 05. September 2005, 19:59 »
Also ich habe nieee gesagt das alle DLLs im ring 0 laufen.
Und übrigens laufen die DLLs im hintergrund, und andere programme können weiterarbeiten.
Die DLLs werden ja nicht mit Interrupts verzweigt, sondern über Call Gates angesprochen.
Es werden nur ausgewählte System DLLs im Ring 0 laufen, so wie beispielsweise bei Windows die DLL "Kernel32.dll" im Ring läuft, die sicher jeder kennt.
Okay und wenn ihr dass nicht ale microkernel system bezeichnet was dann?
Ich bin für jden Vorschlag offen!
Die API besteht ja eigentlich nur aus DLLs, also Librarys, die dynamisch in den Speicher geladen werden.
Nur die WIRKLICH benötigten System DLLs werden in den Speicher geladen, wie es bei windows z.b. die kernel32 datei wäre.
Andere Libs die z. B. Joystick funktionen bereitstellen werden erst bei gebrauch geladen.
Sollte jemand IRGENDWAS besser machen, so soll er den VORSCHLAG hier einbringen.

Grüße an alle,

T0ast3r

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 05. September 2005, 20:22 »
Wie schon beschrieben, ist ein Microkernel ein Kernel, der nur IPC/RPC enthällt, und _alle_ Treiber als eigene Prozesse laufen lässt. Das was du hast ist ein Monolitischer Kernel.

Ich verstehe auch nicht ganz, wofür die Callgates gut sind. Rin0/3 Wechsel?

Ich glaube ausserdem nicht, dass die kernel32.dll in ring 0 läuft. Windows ist soweit ich weiß zumindest im Kern ein Microkernel.

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #11 am: 05. September 2005, 22:08 »
Nun ja, Windows kann wohl auch Hybrid sein, zumindestens konnte man Dinge vom Usermode wohl auch relativ einfach in den Kernelmode verfrachten (noch mehr ...). ;)

Aber wenn die "DLL" dann nicht im Kernelmode, sondern im Usermode, wogegen wird sie dann gelinkt? Oder bekommt die dann ihren eigenen Prozess? Dann nenn sie nicht DLL - und schon hätte man keine Verwirrung! ;)
*post*

T0ast3r

  • Gast
Gespeichert
« Antwort #12 am: 06. September 2005, 20:16 »
Also mim ersten Satz hats Legend alles auf den Punkt gebracht.

DLLs bekommen keinen eigenen Task, sie laufen "mit" dem Task.
Mit "mit" meine ich dass einfach zur DLL gesprungen wird, und der Code zählt sozusagen zu dem Programm.
Es können daher auch mehrere Programme die selbe DLL zur gleichen Zeit benutzen.

Ich weiß nicht was ihr als DLLs anseht, aber das sind Libs die Code bereitstellen und nur bei bedarf in den Speicher geladen werden.
Die kernel32.dll Datei ist übrigens auch eine DLL, daher auch die Endung.
Und da sie eine DLL ist, besteht die API zu einem gewissen Teil auch aus DLLs.

SO.

WAS SOLL EIN IPC/RPC SEIN?
JEDER REDET DAVON NUR CIH KENNS NICHT!

Also was ist das?
(IPC = Interrupt Call?)

@SSJ...:
TREIBER SIND WAS ANDERES ALS DLLs.
TREIBER LINKEN SICH z.B. in ein IRQ ein um dort z. B: dann immer Tasten zu lesen und dann zu versenden.
Damit meine ich das treiber nich gleich DLL bedeutet.

SIEHE WDM = WINDOWS DRIVER MODEL

Noch nie was davon gehört?
MIM WDM SCHREIBT MAN TREIBER!!!
ABER NICHT MIT DLLs!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Lg,

T0ast3r

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #13 am: 06. September 2005, 22:27 »
IPC = InterProcess Communication
Sowas wie Shared Memory, Message Queues, Mutexe, usw.

RPC = Remote Procedure Call
Nun ja, der Name sollte halbwegs selbsterklärend sein.

Und nun ja, wenn wir ne API um mit den Kernel zu kommunizieren sehen wollen, dann mehr so ne Liste wie, Interrupt XY, aufgerufen mit z.B. EAX=1 macht Aktion A. Oder mit Call Gates, je nachdem was du vorhast!

Was innerhalb der Anwendung ist, kann theoretisch eh nicht kontrollieren, wer sagt denn das ich die ganzen DLLs die ein von MSVC generiertes Programm auch benutzen muss um den Kernel anzusprechen - ich kann ja selber meine INT Instruktionen kodieren.

Du wirst wohl a) erstmal so eine Liste erstellen die wirklich die Schnittstelle Kernel - Applikation beinhaltet erstellen, und darauf aufbauend kannst du dann noch sagen, da liefere ich auch noch DLLs die das in eine C API kapseln.
*post*

Golum

  • Beiträge: 96
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 07. September 2005, 10:55 »
Ich glaube es wäre sinnvoller ELF als Dateistruktur zu nehmen da es ja schon ziemlich ausgereift ist, man muss ja nicht alle möglichkeiten davon nutzen. Damit wäre auch möglich gcc zB. zu benutzen.

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #15 am: 07. September 2005, 12:38 »
Also da ich nicht sagen würde, das DLL automatisch PE heisst, ist das glaube ich eine Frage die an ne andere Stelle gehört, und auch nicht sooo wichtig ist (nun ja, alles neukompilieren und neuen Code zum laden - na ja, konzeptionell nicht allzu viel neues in dem Fall)! ;)
*post*

T0ast3r

  • Gast
Gespeichert
« Antwort #16 am: 07. September 2005, 20:00 »
@ Legend:
Danke für die Erklägrung!
Das bringt mich schon weiter!
Also dass IPC benutzt wird ist klar! (nur mal so..)
aber das hat wenig mit dem DLL Aufbau (Interface zum laden...) zu tun

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 07. September 2005, 20:09 »
Hm, wie werden den die Treiber im Kernel organisiert? Bleibt der Kernel jetzt ein Microkernel oder wird er Monolitisch?

T0ast3r

  • Gast
Gespeichert
« Antwort #18 am: 07. September 2005, 20:18 »
Für Treiber kreire ich das Driver Model.
Gibts bei Windows auch. (WDM - Windows Drive Model)
Jaaa aber das Drive Model ist nch in der Anfangsphase.
Ist ne weiterentwiclung von der DLL.

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 07. September 2005, 20:24 »
Wie würd es denn etwa aussehen?
Werden die Treiber in alle Prozesse gemappt und als Module geladen?
Oder sind die Treiber eigene Prozesse?

Das Windows Treibermodell ist meiner Meinung nach auch nicht das Ideal, es läd Treiber doch einfach als Kernelmodule, oder?

 

Einloggen