Autor Thema: Applikationen: Aufruf und ähnliches.  (Gelesen 18591 mal)

WhiteDragon

  • Beiträge: 124
    • Profil anzeigen
Gespeichert
« am: 05. October 2005, 11:15 »
Hallo zusammen,

also mit meinem OS bin ich nun soweit, dass ich gerne Applikationen ausführen würde. Nun habe ich in der GDT/LDT schon die Segmente für Code, Daten und Stack vorbereitet und möchte gerne in das Programm hinein springen.

Hierfür bin ich mir nicht sicher, wie ein entsprechender JMP-Befehl auszusehen hat. Descriptor-Nummer und Offset habe ich, Stack- und Datendescriptor kann ich natürlich vorher schon laden. Aber wie springe ich nun genau in die Application, damit der Code-Descriptor auch verwendet wird?

Oder gibt es eine schönere Möglichkeit, alle Daten auf den Stack zu packen und mit einem RET FAR oder etwas ähnlichem hinein zu springen? Bei einem Wiederaufsetzen auf ein schon begonnenes Programm (soll schließlich eine Multitasking-Umgebung werden) wäre natürlich auch interessant, wie ich auch die Standardregister auf ihren Ursprungswert kriege. Vielleicht wäre ein IRET dafür besser geeignet, aber ich bin leider noch etwas unerfahren in dieser Hinsicht...

Wäre schön, wenn ihr mir sagen könntet, was ein guter Weg ist oder wie ihr selbst es realisiert habt.

Gruß und vielen Dank im Voraus!

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #1 am: 05. October 2005, 12:33 »
Ich benutze ein IRET zum zurückspringen. Muss nur das Stacklayout vorm IRET stimmen. Registerwerte werden aus den Registern direkt übernommen.

Was das Wiederaufnehmen angeht, würde ich mal nach Software Task Switching gucken oder, wenn du willst, Hardware Task Switching.
*post*

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 05. October 2005, 12:56 »
Du brauchst nicht für jede Anwendung Segmente in der GDT/LDT, zumindest wenn du ein flaches Speichermodell benutzt.
Meine GDT sieht so aus:
1. Null Descriptor
2. Kernel Code
3. Kernel Daten
4. User Code
5. User Daten
6. TSS

Die Programme werden so geladen:
1. Eine struct die Informationen über einen Prozess enthällt wird erstellt und in eine linked list geschrieben.
2. In den neuen Prozess werden (bei mir entweder von einem JIT-Compiler, oder von einem sonstigen Programmloader) die Code/Daten/BSS Segmente gemappt. (die z.B. aus einer ELF File ausgelesen werden)
3. Dann wird eine Sturktur für eine Thread erstellt und in eine linked list geschrieben. Sie enthällt einen Stack für den Thread, der dann so aussieht, wie wenn gerade ein interrupt ausgelöst wurde, und danach alle anderen wichtigen Register gepusht wurden.

Das Programmwechseln sieht nun so aus:
1. Der Timer Interrupt wird aufgerufen.
2. Alle wichtigen Register werden gepushed (EAX, EBX, ECX, EDX, ESI, EDI, EBP, sowie die Segmentregister, wobei man das evt. sich sparen könnte, da sie Segmentregister sich ja nicht verändern. (EFLAGS, der Userlevel ESP, CS und EIP werden durch den Aufruf des Interrupts gepushed)
3. Der aktuelle Stack wird in die thread-struct geschrieben
4. Der scheduler sucht einen Thread, das alls nächstes ausgeführt wird.
5. Eventuell wird ein neues Pagedirectory geladen
6. Der neue Stack wird aus der thread-struct des neuen Threads gelesen.
7. Es werden alle wichtigen Register gepoppt.
8. IRET wird ausgeführt, um in das Programm zu springen.

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #3 am: 05. October 2005, 14:50 »
Also ich halte TSS für am besten, da du damit wirklich alle Möglichkeiten der CPU ausschöpfst, es relativ einfach zu benutzen und zu implementieren ist und du wenig selbst machen musst. (Sichern der Umgebung, ...)
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 05. October 2005, 14:56 »
Zitat von: SSJ7Gohan
2. Alle wichtigen Register werden gepushed (EAX, EBX, ECX, EDX, ESI, EDI, EBP, sowie die Segmentregister, wobei man das evt. sich sparen könnte, da sie Segmentregister sich ja nicht verändern. (EFLAGS, der Userlevel ESP, CS und EIP werden durch den Aufruf des Interrupts gepushed)

die segmentregister solltest du auch mit sichern und wiederherstellen, da ein "böses" programm diese doch ändern könnte (zumindest könnte es iirc den null deskriptor laden), und wenn dann ein anderes programm dann auf den speicher zugreift, würde dieses andere programm abstürzen.
Dieser Text wird unter jedem Beitrag angezeigt.

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 05. October 2005, 15:20 »
Naja, man kann statt dem Sichern der Register auch

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

für den kernelspace und das gleiche mit 0x20 für den userspace machen, wenn man ein gewöhnliches GDT Layout hat. Das spart dann einige Speicherzugriffe und ein paar Bytes auf dem Stack

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #6 am: 05. October 2005, 18:54 »
Ich fand ein PUSHA und POPA einfacher als die TSS zu benutzen ...
*post*

WhiteDragon

  • Beiträge: 124
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 05. October 2005, 20:27 »
Dank euch allen - die Entscheidung ist zwar noch nicht gefallen (muss mich mit allem mal eine Weile auseinander setzen), aber ihr habt mir schon mal Denkanstöße gegeben.

Danke!

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #8 am: 06. October 2005, 17:01 »
Zitat von: Legend
Ich fand ein PUSHA und POPA einfacher als die TSS zu benutzen ...


Mit Softwaretasking kannst du aber nicht alle Möglichkeiten des Prozessors ausnutzen. (Soweit ich mich erinnere; z.B. dieser RM-Fake-Mode (Name is mir grade entronnen) ist meines Wissens nach an ein TSS gekoppelt)
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #9 am: 06. October 2005, 18:43 »
Jep, das stimmt, der v86 Modus arbeitet wohl auch mit der TSS. Leider.
*post*

maumo

  • Beiträge: 182
    • Profil anzeigen
    • http://maumo.50webs.com/
Gespeichert
« Antwort #10 am: 09. October 2005, 09:09 »
ich würde jetzt auch lieber TSS nutzen, aber nicht so wie J!N in seinem tut, sondern einfach den TimerInterrupt als TaskGate setzten und dann einfach Backlink ändern -> viel viel leichter
ausserdem haste dann nicht tausende Stacks...

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #11 am: 09. October 2005, 11:35 »
Zitat von: maumo
[...] sondern einfach den TimerInterrupt als TaskGate setzten und dann einfach Backlink ändern -> viel viel leichter
ausserdem haste dann nicht tausende Stacks...


Ja, dieser Weg geht auch. Allerdings finde ich ihn von der Theorie her etwas komplizierter, deswegen habe ich den anderen genommen.
"Tausend" Stacks haste mit der Methode auch, jede Applikation braucht ihren eigenen Stack...
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #12 am: 09. October 2005, 13:23 »
Backlink war auch so ne Sache die mich abgeschreckt hat ...
*post*

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 09. October 2005, 14:41 »
Naja, die um angeblich 300% geringe Taskwechsel-Dauer ist meiner Meinung schon ein Grund, Software Taskswitching zu benutzen. Welche PM Funktionen kann man denn mit Software Taskswitching nicht nutzen?
Mit TSS brauchst du genauso viele Stacks, wie mit Software Taskswitching, jede Anwendung braucht mindestens einen Kernelstack und in 99.9% der Fälle wohl auch einen Userlevel Stack. Falls du Ring1 und Ring2 benutzt, brauchst du sogar noch 2 Stacks mehr.

n3Ro

  • Beiträge: 288
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 09. October 2005, 14:49 »
Beim Software-Taskswitching ist es schwieriger für einzelne Tasks IO-Ports zu sperren / freizugeben, da der Mechanismus dafür auf dem TSS aufbaut. Und kleiner Tipp nebenbei: man braucht nicht immer pro Task einen Kernelstack, sondern kann auch pro CPU einen Kernelstack benutzen, das hängt ganz am Kerneldesign.
Agieren statt Konsumieren!

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 09. October 2005, 15:24 »
Zitat von: SSJ7Gohan
Naja, die um angeblich 300% geringe Taskwechsel-Dauer ist meiner Meinung schon ein Grund, Software Taskswitching zu benutzen.

gibt es eigentlich dafür irgendwelche tests oder benchmarks oder so?
Dieser Text wird unter jedem Beitrag angezeigt.

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #16 am: 09. October 2005, 15:33 »
Zitat von: n3Ro
Beim Software-Taskswitching ist es schwieriger für einzelne Tasks IO-Ports zu sperren / freizugeben, da der Mechanismus dafür auf dem TSS aufbaut. Und kleiner Tipp nebenbei: man braucht nicht immer pro Task einen Kernelstack, sondern kann auch pro CPU einen Kernelstack benutzen, das hängt ganz am Kerneldesign.

Stimmt, die Bitmap dafür ist in TSS. Jedoch soll die TSS sowieso pagingsensitiv sein, weswegen man es bei geschickter Positionierung hinbekommt die Bitmap gleich mit dem Wechseln von CR3 auszutauschen ...
*post*

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #17 am: 09. October 2005, 17:41 »
Zitat von: SSJ7Gohan
Naja, die um angeblich 300% geringe Taskwechsel-Dauer ist meiner Meinung schon ein Grund, Software Taskswitching zu benutzen. Welche PM Funktionen kann man denn mit Software Taskswitching nicht nutzen?


Das heißt, dass Hardwaretasking 3 mal so lange dauert, wie Softwaretasking. Wie man das misst ist mir eigendlich schleierhaft, ich frage mich auch, wieso es länger dauert, wenn die CPU auf Hardwareebene was macht, als wenn sie Befehle abarbeitet. Erklärbar währe das damit, dass man mit TSS eben weit mehr Möglichkeiten hat, wie zum Beispiel die Sache mit dem Portbitmap oder v86-Mode.
Und dafür, dass ich mit TSS eben die CPU weit mehr ausreizen kann, nehme ich gerne in Kauf, dass es angeblich 3 mal so lange dauert.

Zitat von: Legend

Backlink war auch so ne Sache die mich abgeschreckt hat ...


Backlinks braucht man standartmäßig garnicht, jedenfalls habe ich die meines Wissens nach nicht aktiv irgendwo einbezogen. Scheint alles automatisch zu gehen... (oder ich war so müde, dass ichs in trance gemacht hab, weil ich MT mit TSS nähmlich in den osterferien um 3 uhr in der nacht eingebaut hab ;))
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #18 am: 09. October 2005, 19:47 »
Wohl soll das Wechseln von der TSS dann wohl drei mal so lange dauern als ein PUSHA, ein MOV um CR3 auszutauschen und noch ein POPA.
*post*

maumo

  • Beiträge: 182
    • Profil anzeigen
    • http://maumo.50webs.com/
Gespeichert
« Antwort #19 am: 11. October 2005, 22:03 »
vorher musste ja in den kernelspace kommen, einen neuen task wählen und zurückspringen...
das sind dann auch mal n paar mov *s, eax, ...
bei hardware mt macht das die CPU für dich

 

Einloggen