Autor Thema: Multitasking  (Gelesen 21287 mal)

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #20 am: 30. June 2008, 17:13 »
Gibt es eine möglichkeit zu prüfen, ob ein Programm nun 16-Bit oder 32-Bit Code verwendet?
Das sagt dir das Dateiformat der ausführbaren Datei.
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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #21 am: 01. July 2008, 16:40 »
Nun das funktioniert vllt. bei *.com und anderen 16-Bit Formaten.
Allerdings kann ich eine Datei Binär einmal 16-Bit und einmal 32-Bit compilieren, oder assemblieren, oder wie auch immer.
 
Aber das ist egal, denn das werde ich später noch herausfinden.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #22 am: 01. July 2008, 17:01 »
Nun das funktioniert vllt. bei *.com und anderen 16-Bit Formaten.
Allerdings kann ich eine Datei Binär einmal 16-Bit und einmal 32-Bit compilieren, oder assemblieren, oder wie auch immer.
Meinst du nicht, dass das ein von dir selbst verursachtes Problem ist? :wink: Ich mein exakt für solche Zusatzinformationen sind Dateiformate da. Wobei 16bit Code auch schon wieder so alt ist, dass es dafür kein ELF Dateiformat gibt. Ich seh auch nicht wirklich den Nutzen jetzt noch irgendwelchen 16bit Code ausführen zu wollen (einzige Ausnahme sind die VESA BIOS Extensions vllt.). Ich mein es wird demnächst sowieso Richtung EFI und logischerweise weg vom BIOS gehen...
Und rein vom Code her kann man das nicht praktikabel unterscheiden. Du könntest auch nicht praktikabel zwischen PowerPC, ARM und x86 Maschinencode unterscheiden (und das nicht weil die gleich wären :-D ).
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

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 01. July 2008, 18:43 »
Nun das funktioniert vllt. bei *.com und anderen 16-Bit Formaten.
Allerdings kann ich eine Datei Binär einmal 16-Bit und einmal 32-Bit compilieren, oder assemblieren, oder wie auch immer.
Nur der Vollständigkeit halber: Die .com-Dateien von DOS sind einfach nur reiner Maschinencode ohne echtes Dateiformat, also flache Binaries. Womit du vielleicht eher was anfangen kannst, ist .exe. Aber nur vielleicht. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 01. July 2008, 18:54 »
mal so zur Anschauung
ein
[BITS 32]
mov eax, ebx
mov cx, dx
produziert exact den selben binärcode wie
[BITS 16]
mov ax, bx
mov ecx, edx
der unterschied besteht halt in der interpretation vom processor

Binärcode16Bit-CPU32Bit-CPU
0x89 0xd8mov ax, bxmov eax, ebx
0x66(Operand Size Prefix) 0x89 0xd8mov eax, ebxmov ax,bx
« Letzte Änderung: 01. July 2008, 19:05 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #25 am: 04. July 2008, 08:09 »
Nun das funktioniert vllt. bei *.com und anderen 16-Bit Formaten.
Allerdings kann ich eine Datei Binär einmal 16-Bit und einmal 32-Bit compilieren, oder assemblieren, oder wie auch immer.
Nur der Vollständigkeit halber: Die .com-Dateien von DOS sind einfach nur reiner Maschinencode ohne echtes Dateiformat, also flache Binaries. Womit du vielleicht eher was anfangen kannst, ist .exe. Aber nur vielleicht. ;)
Kein Bedarf....  :-)

 
Ich habe mal über die ganze Interprozesskommunikation nachgedacht. Und zwar habe ich mir folgendes überlegt (basierend auf i386):

Ich ändere, bzw. erweitere meine Virtuelle Speicheraufteilung. Zuvor war der Aufbau wie folgt:
0x00000000 - 0xBFFFFFFF     => User Programme
0xC0000000 - 0xCFFFFFFF     => Kernel
0xD0000000 - 0xDFFFFFFF     => Kernel Heap
0xE0000000 - 0xFFFFFFFF     => "Noch nicht vergeben"
Geändert sieht das nun So aus:
0x00000000 - 0xBFFFFFFF     => User Programme
0xC0000000 - 0xCFFFFFFF     => Kernel
0xD0000000 - 0xD000FFFF     => Kernel Heap
0xD0010000 - 0xDFFFFFFF     => Multitasking (Task Stacks, Thread Stacks, ...)
0xE0000000 - 0xFFFFFFFF     => Platz für IPC (Shared Memory, Message Passing, ...)

Was meint ihr dazu?
Seht ihr irgendwelche Nachteile, oder ähnliches?
 
 
Gruß Christian
 
PS: Den Kram mit der Unterscheidung von 16 und 32 Bit habe ich jetzt einfach mal nach hinten verschoben :D

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #26 am: 04. July 2008, 15:15 »
Was meint ihr dazu?
Seht ihr irgendwelche Nachteile, oder ähnliches?
Wenn du den Kernel Heap direkt hinter den Kernel klebst, dann ist für den Heap ein bisschen mehr Platz :wink: Ich würde sagen 0x10000 ist ein bisschen wenig für den Kernel Heap. Zumindest ist für die Kernel Binary überproportional viel Platz (Ich hab jetzt einfach mal das 'Kernel' in deiner Liste als das Kernel image bzw. die Binary interpretiert).
Ansonsten steht da nicht wirklich was konkretes, insofern lässt sich da nicht viel zu 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

jgraef

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 04. July 2008, 15:43 »
Hi,

Der Heap ist etwas zu klein. Und außerdem würde ich die Task/Thread-Daten, IPC-Daten und sämtliche andere Daten des Kernels in den Kernelheap reinmachen, denn dafür ist er ja da.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #28 am: 04. July 2008, 16:39 »
Und außerdem würde ich die Task/Thread-Daten, IPC-Daten [...]
Das würde ich dann eher im Einzelfall nochmal betrachten, va. bei IPC halte ich das für sehr implementationsabhängig, zB wäre es bei shared-memory Schwachsinn, das auf einem Kernel Heap zu machen und selbst bei [fixed-size] message passing man vielleicht einen spezielleren Allokator (als malloc), da man da bestimmt einiges rausholen könnte, da man ja weiß wie die Allokationsgröße ist.
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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #29 am: 12. August 2008, 13:11 »
Hmmm...
Mir stellt sich da gerade eine Frage...
 
Ich erkläre das mal an einem Beispiel:
Ich habe einen Grafiktreiber. Dieser wird jetzt gestartet.
Als erstes wird der Prozess mit einem Thread erstellt. Danach erstellt der Prozess
von sich aus einen neuen Thread, und zwar einen VM8086-Thread. Dieser wechselt
nun den Grafikmodus (VESA 1.0 oder so) und stirbt dann.

Da sich in einem Prozess ja die Threads die Resourcen teilen müsste ich ja auch auf
die Daten des gestorbenen Threads zugreifen können oder werden diese danach freigegeben?
 
Und noch eine Frage ist da. Ich bin momentan dabei Paging einzubauen.
Nun fordert ein Prozess per System Call Speicher an.
Nach welchen Kriterien mappt ihr den Physikalischen Speicher an welche Adresse?
Ist mir das frei gestellt, oder muss ich da irgendwas beachten?
 
Gruß Christian
 
 
*EDIT*
Mir ist klar, dass bei einem VM8086-Thread die physikalische Adresse innerhalb des ersten MBs sein muss.
Aber wie ist das bei normalen Prozessen, also elf oder flat binary?
Gibt es hier Informationen dazu im Header (zumindest bei elf)?

*EDIT2*
Es sieht so aus, als ob im ELF-Format eine virtuelle adresse gespeichert werden kann, aber nicht muss.
Diese wird mit dem Linker Skript festgelegt, bsp.: . = 0xA0000000 o.ä.
Da diese jedoch 0 sein kann, müsste ich ja praktisch eine Default Adresse festlegen, bsp.: ab 0x00100000.
Wie macht ihr das mit dem flat binary Format?
« Letzte Änderung: 12. August 2008, 14:10 von ChristianF »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #30 am: 12. August 2008, 15:09 »
Und noch eine Frage ist da. Ich bin momentan dabei Paging einzubauen.
Nun fordert ein Prozess per System Call Speicher an.
Nach welchen Kriterien mappt ihr den Physikalischen Speicher an welche Adresse?
Ist mir das frei gestellt, oder muss ich da irgendwas beachten?
Du schreibst das OS, dir ist alles freigestellt. Du kannst höchstens fragen, was für die Programme am sinnvollsten/bequemsten ist. Wenn in LOST Speicher angefordert wird, wird (irgendein) freier physischer Speicher gesucht und an (irgend)eine freie Stelle im virtuellen Speicher des Prozesses gemappt. Die virtuelle Adresse wird dann halt an den Prozeß zurückgegeben.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #31 am: 13. August 2008, 08:11 »
Und noch eine Frage ist da. Ich bin momentan dabei Paging einzubauen.
Nun fordert ein Prozess per System Call Speicher an.
Nach welchen Kriterien mappt ihr den Physikalischen Speicher an welche Adresse?
Ist mir das frei gestellt, oder muss ich da irgendwas beachten?
Du schreibst das OS, dir ist alles freigestellt. Du kannst höchstens fragen, was für die Programme am sinnvollsten/bequemsten ist. Wenn in LOST Speicher angefordert wird, wird (irgendein) freier physischer Speicher gesucht und an (irgend)eine freie Stelle im virtuellen Speicher des Prozesses gemappt. Die virtuelle Adresse wird dann halt an den Prozeß zurückgegeben.
Nun, dass irgendeine freie physikalische Page verwendet wird, ist mir klar, die verwalte ich ja in einer Bitmap und in einem Stack.
Aber so wie das aussieht, muss ich mir wohl noch mal Gedanken machen, wie ich den Speicher bei normalen Anwendungen aufteile...
Mal schauen, vielleicht will mir was passendes dazu einfallen :D
 
Gruß Christian

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #32 am: 14. August 2008, 12:05 »
Mir ist klar, dass bei einem VM8086-Thread die physikalische Adresse innerhalb des ersten MBs sein muss.
Im VM8086 ist Paging aktiviert. Insofern muss die virtuelle Adresse unter 1MB sein, nicht (unbedingt) die physikalische. Wobei natürlich klar sein sollte, dass man das BIOS und solche Sachen mappen muss/sollte.

Zitat
Wie macht ihr das mit dem flat binary Format?
In flat binary würden die meisten aber auch eine Header mit eben solchen Informationen einbauen. Ansonsten gilt: Du hast es gelinkt, dann musst du auch wissen wo was in der Datei gelandet ist und wo es hingeladen werden soll. Wenn du ELF bereits hast/willst, dann ist es imho Schwachsinn Unterstützung für Flat Binary einzubauen.
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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #33 am: 14. August 2008, 14:16 »
Mir ist klar, dass bei einem VM8086-Thread die physikalische Adresse innerhalb des ersten MBs sein muss.
Im VM8086 ist Paging aktiviert. Insofern muss die virtuelle Adresse unter 1MB sein, nicht (unbedingt) die physikalische. Wobei natürlich klar sein sollte, dass man das BIOS und solche Sachen mappen muss/sollte.
Ups...
Da ist mir wohl ein Fehler unterlaufen ich meinte natürlich die virtuelle Adresse.
 
Zitat
Wie macht ihr das mit dem flat binary Format?
In flat binary würden die meisten aber auch eine Header mit eben solchen Informationen einbauen. Ansonsten gilt: Du hast es gelinkt, dann musst du auch wissen wo was in der Datei gelandet ist und wo es hingeladen werden soll. Wenn du ELF bereits hast/willst, dann ist es imho Schwachsinn Unterstützung für Flat Binary einzubauen.
Das macht auch irgendwo sinn.
Dann werde ich elf benutzen, und vllt. noch .exe, insofern es sich um keine Win32 Anwendung handelt.  :-P
 
*EDIT*
@bluecode
Nach welchem Schema wird denn bei Pedigree der Speicher gemappt?
« Letzte Änderung: 14. August 2008, 22:13 von ChristianF »

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #34 am: 20. August 2008, 13:28 »
Hallo
 
Ich habe da noch etwas gefunden  :evil:
 
Ich habe aus interesse mir mal den LOST Quellcode angeschaut. Hier ist es gang und gebe, für jeden einzelnen Real Mode Interrupt ein VM86-Thread zu erstellen.
Diese Vorgehensweise habe ich nach einiger Zeit der Suche auch bei anderen Hobby Betriebssystemen gefunden.
 
In gewisser Hinsicht ist diese Implementation aber doch sehr langsam oder nicht?
Ein kleines Beispiel zur Verdeutlichung:
Ich habe ein Programm geschrieben, das einen 16 Bit Thread startet. Dieses macht einige movs, interrupts, usw!
 
Würde man solch ein Programm mit der obigen Implementation ausführen, wäre das ja ewig langsam, da wegen jeder Aktion ein extra Thread erstellt wird.
 
Oder ich habe etwas falsch verstanden, was aber möglich ist, ist das mischen von 16 und 32 Bit Code.
Der Aufruf einer Funktion zum initialisieren des Grafikmodus (VESA) würde dann auch ewig brauchen, was nicht meine Intention ist.
 
Wie sieht das sonst so aus? Wie regelt ihr das?
 
Gruß Christian
 
*EDIT*
Ich möchte keinen Quellcode sehen  :wink:

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #35 am: 20. August 2008, 13:51 »
Ich biete in lightOS nicht die Möglichkeit 16bit Tasks zu erstellen, sondern ausschließlich einen Wrapper um VBE (innerhalb des Kernels). Ich wüsste so ad hoc auch nicht, was man damit sonst sinnvolles (!) anstellen könnte.
« Letzte Änderung: 20. August 2008, 15:45 von bluecode »
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

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #36 am: 20. August 2008, 15:17 »
Würde man solch ein Programm mit der obigen Implementation ausführen, wäre das ja ewig langsam, da wegen jeder Aktion ein extra Thread erstellt wird.
Ja, in der Tat, und dafür ist es auch nicht gedacht. Der typische Anwendungsfall ist der Aufruf eines BIOS-Interrupts zum Einschalten des Grafikmodus und vielleicht noch irgendwann ein zweiter, um wieder in den Textmodus zurückzuschalten. Da tut die Performance nicht wirklich weh.
 
Zitat von: bluecode
atok
Meinst du "ad hoc"? ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #37 am: 20. August 2008, 15:46 »
Zitat von: bluecode
atok
Meinst du "ad hoc"? ;)
steht doch da :-P :-D :oops:
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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #38 am: 20. August 2008, 20:09 »
Nun ja mir ist jetzt aber auch kein anderes Beispiel eingefallen als der Grafikmodus...
Bzw. das ist das einzigst Sinnvolle beispiel, denn wer greift über RM Interrupts auf die Festplatte oder Diskette zu, wenn es dafür DMA gibt :-D
 
Aber wenn ich da richtig liege, wird der RM auch nur dafür gebraucht  :-D
Und auch unter Windows gibt es eine Möglichkeit, einen Interrupt einzeln auszuführen, z.B. beim setzen des Mode 13h.  :roll:
 
Mal schauen, wie es dann letzten endes aussehen wird, da ich noch nicht ganz mit der Speicherverwaltung fertig bin.
 
Grüße Christian

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #39 am: 04. February 2009, 08:37 »
So, da melde ich mich mal wieder...
 
Ich bin mit dem Multitasking nun soweit, dass ich Prozesse mit einzelnen Unterprozesse (Threads) erstellen und im "Round Robin"-Verfahren ausführen kann. So weit funktioniert auch alles, nur bin ich momentan am überlegen, wie ich das mit dem Page Directory und den User-Space Prozessen mache...
 
Momentan werden die Prozessstruktur und alles benötigte auf dem Kernel Heap abgelegt, der allerdings vom User-Space nicht erreichbar ist. Des Weiteren wird der Stack der einzelnen Threads im virtuellen Bereich 0xF0000000 - 0xFFFFF000 abgelegt.
 
Bezogen auf den User-Space müsste ich also folgende änderungen machen:
  • Den Bereich "0xF0000000 - 0xFFFFF000" für den User-Space beschreibbar machen, alles andere würde keinen Sinn machen.
  • Bei jedem Task-Wechsel vorher das kernel page directory aktivieren.
So müsste ich dann zum einen im Page Directory des Kernels die Thread-Stacks der Prozesse ablegen, sowie auch im Page Directory des Prozesses. Wohlgemerkt nur die Thread-Stacks, die der Prozess auch hat, denn die anderen da noch hinein zu mappen wäre nicht sehr sinnvoll.
 
Was ist eure Meinung zu diesem Text? Gibt es noch Punkte, die ich nicht berücksichtigt habe oder die überflüssig sind?
 
Gruß Christian

 

Einloggen