Autor Thema: Multitasking aufbauen  (Gelesen 5114 mal)

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« am: 18. March 2009, 15:42 »
Hallo,

ich bin gerade dabei mein System multitasking-fähig zu kriegen.
Als erstes muss ich ja eine TSS einbauen.
Muss ich die schon mit werten befüllen, wenn ja mit welchen?
Dann habe ich mir das mit dem User- und dem Kernel-Stack angeschaut.
Mir ist klar, dass der einen eigenen Kernelstack benötigt.
Den kann ich ja einfach nach ganz unten setzen und dann wars das, oder?
Aber wieso habt ihr den Kernelstack noch einmal new_task->esp gelegt?
Muss der Prozess nicht einen eigenen Stack bekommen?

[EDIT]
Wenn ich nun ein Modul in den Kernelspace lade, wie muss ich denn da dann die Stack-Pointer setzen?
« Letzte Änderung: 18. March 2009, 15:50 von rizor »
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 18. March 2009, 19:46 »
Muss ich die schon mit werten befüllen, wenn ja mit welchen?
Kommt drauf an ob du Software- oder Hardwaremultitasking machen möchtest. Normalerweise macht man Softwaremultitasking und da reicht im Prinzip SS0:ESP0. Alle anderen Werte speichert man normalerweise auf einem Stack oder sonst irgendwo anders.

Zitat
Den kann ich ja einfach nach ganz unten setzen und dann wars das, oder?
zB, du solltest halt trotzdem nie zwei Codeabschnitte gleichzeitig den gleichen Stack nutzen lassen, aber das kriegst du mit ein bisschen Gehirnschmalz sicherlich hin (oder alternativ kackt dein Kernel unvorhergesehen ab und du darfst Debuggen).

Zitat
Aber wieso habt ihr den Kernelstack noch einmal new_task->esp gelegt?
Die Frage verstehe ich leider nicht, da ich meine Grammatik-Kristallkugel leider verlegt habe :wink:

Zitat
Muss der Prozess nicht einen eigenen Stack bekommen?
Nicht nur jeder Prozess sondern sogar jeder Thread.

Zitat
Wenn ich nun ein Modul in den Kernelspace lade, wie muss ich denn da dann die Stack-Pointer setzen?
Wenn deine Module keine eigenständigen Tasks sind, brauchst du logischerweise keinen eigenen Stack. Erst wenn du darauf eigens schedulbare EInheiten (aka Tasks) machst brauchst du einen Stack.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 18. March 2009, 20:13 »
Ok. Danke.

Zitat
Kommt drauf an ob du Software- oder Hardwaremultitasking machen möchtest. Normalerweise macht man Softwaremultitasking und da reicht im Prinzip SS0:ESP0. Alle anderen Werte speichert man normalerweise auf einem Stack oder sonst irgendwo anders.
Das mit SS0:ESP0 verstehe ich nicht.
Was meinst du damit?

Zitat
zB, du solltest halt trotzdem nie zwei Codeabschnitte gleichzeitig den gleichen Stack nutzen lassen, aber das kriegst du mit ein bisschen Gehirnschmalz sicherlich hin (oder alternativ kackt dein Kernel unvorhergesehen ab und du darfst Debuggen).
Das ist klar.

Zitat
Die Frage verstehe ich leider nicht, da ich meine Grammatik-Kristallkugel leider verlegt habe :wink:
ja, ja.
Deutsch Sprach schwer Sprach
Ich habe mich nur bei dem Lost-Code gewundert, warum es einmal heißt: new_task->kernel_stack = kernelstack und new_task->esp = kernelstack.
Das hat mich nur gewundert.
Dann habe ich aber gesehen, dass new_task->user_stack = userstack gibt.
Wieso wird das mit dem ganzen Stack-Geschiebe gemacht?

Zitat
Wenn deine Module keine eigenständigen Tasks sind, brauchst du logischerweise keinen eigenen Stack. Erst wenn du darauf eigens schedulbare EInheiten (aka Tasks) machst brauchst du einen Stack.
Wie sieht dass denn dann mit dem Rücksprung aus dem Modul in den Kernel aus?
Geht das nur über Syscalls?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 18. March 2009, 20:30 »
Zitat
Das mit SS0:ESP0 verstehe ich nicht.
Was meinst du damit?

wiki: TSS: Das Feld SS0:ESP0 gibt an welcher Stack bei einem Interrupt benutzt wird (um den Interrupt Stackframe darauf zu pushen), d.h. es gibt den Kernelstack an.

Zitat
Wieso wird das mit dem ganzen Stack-Geschiebe gemacht?
Ich nehme an, dass das eine angibt wo sich den der Anfang des Kernelstacks ist und der andere wo genau sich der Kernelstack momentan befindet. Ist aber wohl eher nicht von großer Bedeutung.

Zitat
Wie sieht dass denn dann mit dem Rücksprung aus dem Modul in den Kernel aus?
Geht das nur über Syscalls?
Das kommt drauf an. Wenn du deine Module nicht im Kernelspace (also im CPL0) laufen lässt dann ja, ansonsten nein. Bei ersterem ist das Modul im Prinzip ein eigener Prozess (und du bist bei einem Microkernel), bei letzterem ist der Aufruf ein ganz normaler Funktionsaufruf (und du bist bei einem monolithischen Kernel mit ladbaren Modulen).
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 18. March 2009, 20:42 »
Danke.
Wie funktioniert das mit dem Kernelstack?
Bekommt jeder Task seinen eigenen Kernelstack oder teilen sich alle einen?
Wenn sich alle einen teilen, bekomme ich beim Mehr-CPU-Betrieb Konsistenzprobleme, oder?

Wie funktioniert das allgemein mit dem Aufrufen der Tasks?
Aus dem Elf-header bekomme ich alle benötigten Infos, oder?
Ich habe das leider nur noch nicht mit dem cmdline verstanden.

An sich wird ein Prozess doch mit der Main gestartet und wenn ein Prozess Startparameter braucht, liegen diese ja auf dem Stack. An sich müsste ich doch nur das Startregister setzen, damit er ordentlich laufen kann, oder?
Die Programme werden doch mit der Startadresse 0x0 versehen, oder?
Wie müsste ich das dann mit dem Offset machen, weil ich die Programme nicht auf 0x0 lege.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #5 am: 18. March 2009, 20:52 »
Wie funktioniert das mit dem Kernelstack?
Bekommt jeder Task seinen eigenen Kernelstack oder teilen sich alle einen?
Wenn sich alle einen teilen, bekomme ich beim Mehr-CPU-Betrieb Konsistenzprobleme, oder?
Du hast normalerweise einen pro CPU.

Zitat
Wie funktioniert das allgemein mit dem Aufrufen der Tasks?
Register auf den Stack pushen, iret -> Taskswitch. Nächster Interrupt -> Wechsel zum Kernelstack, pushen der Register, etc. auf diesen -> Zurück im Kernel.

Zitat
Aus dem Elf-header bekomme ich alle benötigten Infos, oder?
Das einzig wirklich interessante aus den ELF-Headern ist der Entry-Point des Programs (also der start EIP-Wert).

Zitat
Ich habe das leider nur noch nicht mit dem cmdline verstanden.
Ich habe keine Ahnung welche cmdline du meinst und inwiefern die in den momentanen Kontext passt.

Zitat
An sich wird ein Prozess doch mit der Main gestartet
Nein wird er nicht. Normalerweise läuft ein Codefitzelchen der libc davor um eben sowas wie die argc und argv Parameter für main zu holen, main aufrufen und eventuell vorher noch irgendwas falls notwendig in der libc selbst initialisieren.

Zitat
An sich müsste ich doch nur das Startregister setzen, damit er ordentlich laufen kann, oder?
Was ist das "Startregister"? Ich denke du meinst EIP, siehe oben

Zitat
Die Programme werden doch mit der Startadresse 0x0 versehen, oder?
Nein, normalerweise möchte man beim folgen eines NULL-Pointers einen Pagefault haben, deshalb legt man die Programme etwas höher, ich zB hab sie bei 4MB.

Zitat
Wie müsste ich das dann mit dem Offset machen, weil ich die Programme nicht auf 0x0 lege.
Du kannst sie doch im Linkerskript dahin linken wo du sie eben brauchst.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 18. March 2009, 21:17 »
Ok.
Wie bekomme ich das hin, dass für dem Programmcode noch die libc läuft?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #7 am: 19. March 2009, 06:52 »
Wie bekomme ich das hin, dass für dem Programmcode noch die libc läuft?
Linkerscript für Programme (Das wesentliche ist "ENTRY(startup)")
Assembler stub (Das wesentliche ist das Definieren des startup-Symbols)
_main() zum Initialisieren der und Aufrufen von main()
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 19. March 2009, 19:01 »
Ich habe mal ein paar Fragen zu deiner _main().
Wenn ich es richtig verstehe, dann zählt _cmdline die Anzahl an Argumenten, oder?
Woher holst du argv?
Das müsste an sich doch von der Konsole oder den Aufrufparametern kommen, oder?
Was genau ist denn dieses environ?
Das kommt von environment aber ich kann mir nicht vorstellen was das macht (den Code env.c habe ich gesehen).

Dann habe ich noch eine Frage wie ich dann am besten Kernel-Module linke.
Denen kann ich ja keine feste Startadresse zuteilen, bzw. das möchte ich nicht.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

jgraef

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 19. March 2009, 19:20 »
Wie du argv bekommst hängt davon ab, wie du das gestaltest. Bei meinOS werden beim Aufruf eines exec() Daten wie argv und environ in ein SharedMemory-Segment gelegt und die ID des Segmentes im Kernel gespeichert. Wenn der neue Prozess gestartet wird, lädt er die Daten aus dem SharedMemory-Segment.

environ ist ein Array von Umgebungsvariablen:
http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html

Bei Kernelmodulen musst du selbst die Adressen relocaten und dann die Symbole für Hooks (z.B driver_init()) auflösen.
« Letzte Änderung: 19. March 2009, 19:22 von jgraef »

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 19. March 2009, 19:29 »
Wie kann ich die Module denn relocaten?
An sich müsste ich dem Code ja beibringen, dass es immer noch ein Offset gibt.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #11 am: 19. March 2009, 20:06 »
Dann habe ich noch eine Frage wie ich dann am besten Kernel-Module linke.
Du linkst sie am besten garnicht, sondern machst wohl nur Objektdateien, würde ich mal sagen.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 19. March 2009, 20:32 »
Wie kann ich die dann laden?
Also über GRUB
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #13 am: 19. March 2009, 20:53 »
menu.lst (über "module")
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 19. March 2009, 21:10 »
Ja, das dachte ich mir.
Aber wie kann ich den Code dann ausführen?
So, als ob es ein normalen Prozess starten würde oder wie?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #15 am: 19. March 2009, 21:19 »
Jo natürlich. Grub gibt dir die Liste der geladenen Module mit Adressen der in den RAM geladenen ELF-Datei. Dann die ELF-Datei Parsen, die Segmente extrahieren und halt einen Task starten.
Ob irgendein Prozess einen anderen gestartet hat ist doch dafür komplett irrelevant.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

 

Einloggen