Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: bitmaster am 29. June 2006, 16:12

Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 16:12
Also ich muss mein OS kräftig umschreiben sonst ist es bald nicht mehr existens fähig. Die neueren CPUs (und der 64-bit Modus) unterstützen nämlich kein Hardwaremultitasking mehr. Jetzt steh ich doof da. Ich muss also zu Softwaremultitasking wechseln. Aber davon habe ich überhaubt keine Ahnung. Hat man dann kein TSS oder wie? Wie speichert man die Register und wo? Please help me!!!

bitmaster
Titel: Softwaremultitasking, aber wie?
Beitrag von: scales of justice am 29. June 2006, 16:26
hmm? ich dachte immer der Prozessor emuliert das von alleine.
Sicher das der OS-Programmierer das machen muss?
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 29. June 2006, 17:20
Zitat von: scales of justice
hmm? ich dachte immer der Prozessor emuliert das von alleine.
Sicher das der OS-Programmierer das machen muss?

ROFLMAO  :lol:

Ne mal im ernst, du hast schon noch ein TSS benutzt es aber nichtmehr zum speichern der Register sondern nur noch, um SS0 und ESP0 bei Interupts zu bekommen. Evtl. hilf dir das tutorial von beyond infinity (http://www.osdever.net/tutorials/multitasking.php?the_id=84). Wenn nicht dann einfach fragen, was du nicht verstehst :)
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 17:23
Zitat von: scales of justice
hmm? ich dachte immer der Prozessor emuliert das von alleine.
Sicher das der OS-Programmierer das machen muss?
Ja, ich bin mir da ganz sicher. Im Intel Manual steht sogar drin, dass im 64-Bit Modus kein Hardwaremultitasking mehr möglich ist. Und der AMD64 kann das sogar im 32-Bit Modus nicht mehr (soweit ich weiß). Deswegen muss ich zu Softwaremultitasking wechseln, sonst ist mein OS nicht zufunftssicher. Hat einer 'ne Ahnung wie das mit Softwaremultitasking funktioniert?

danke!!!
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 29. June 2006, 17:30
Zitat von: bitmaster
Hat einer 'ne Ahnung wie das mit Softwaremultitasking funktioniert?

Siehe mein Post, welches du mit Sicherheit überlesen hast :)
Titel: Softwaremultitasking, aber wie?
Beitrag von: n3Ro am 29. June 2006, 17:36
Da die 64 Bit CPUs von AMD 100% abwärtskompatibel zu allen 32bit x86ern ist geht da natürlich auch noch Hardwaremultitasking in den "alten" Modi.
Softwaremultitasking funktioniert im Prinzip ganz einfach. Du rufst ja in Regelmäßigen Zeitabständen den Timerinterupt auf. Bei diesem wird im Stack CS:EIP,SS:ESP und eFlags abgelegt die beim IRET wieder ausgelesen werden. Wenn du nun vor dem IRET deine alten Register von Task A abgespeichert hast und die von Task B lädst und dabei auf deine Stackwerte umänderst, springst du beim IRET in deine Task B ;)
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 20:27
Aso, danke für die vielen Antworten. Also ich lade einmal mit ltr ein TSS und mehr habe ich dann auch nicht, oder wie? Und mein IRQ0 macht dann das oder wie? :

pusha
push ds
push es
push fs
push gs

kA was dann

pop gs
pop fs
pop es
pop ds
popa
iret


Aber dann habe ich doch die vorherigen Register wieder? Und wieso überhaubt dann ein TSS? Hmm... blick da nicht so ganz durch.

bitmaster
Titel: Softwaremultitasking, aber wie?
Beitrag von: Jidder am 29. June 2006, 20:32
Zitat von: bitmaster
Aber dann habe ich doch die vorherigen Register wieder?
Nicht, wenn du bei "kA was dann" den Stack wechselst. Das ist der Trick beim Softwaremultitasking.

Zitat
Und wieso überhaubt dann ein TSS? Hmm... blick da nicht so ganz durch.

Das TSS brauchst du für einen Privilegwechsel von Ring 3 nach Ring 0. (Die Schwierigkeit ist SS und CS gleichzeitig zu ändern.) Anders kommst du nicht in den Kernel.
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 20:41
OK, also das mit den anderen Werten durch den anderen Stack verstehe ich jetzt. Aber wie wechsle ich denn den Stack? Und wie bekomme ich dann das neue CS?

bitmaster
Titel: Softwaremultitasking, aber wie?
Beitrag von: Jidder am 29. June 2006, 20:49
Stack wechseln:
mov [alter_stack], esp
mov esp, [neuer_stack]


Das neue CS bekommst entweder durch einen far-jump oder bei einem Privilegwechsel durch ein iret.
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 20:53
Zitat von: PorkChicken
Stack wechseln:
mov [alter_stack], esp
mov esp, [neuer_stack]


Das neue CS bekommst entweder durch einen far-jump oder bei einem Privilegwechsel durch ein iret.
Hmm.. Also brauche ich nur sp und nicht ss ändern? Hä? Und muss also eine Zeichenkette voller Stackwerte von jedem Task haben? Und wenn ich einen Task starte muss ich auf seinem Stack vorher alle Werte für die Register draufpushen um nacher auch durch iret z.B. den cs und eip an der richtig Position zu haben?
Titel: Softwaremultitasking, aber wie?
Beitrag von: Jidder am 29. June 2006, 20:57
Zitat von: bitmaster
Hmm.. Also brauche ich nur sp und nicht ss ändern? Hä?

Doch. Wenn du nicht sicherstellen kannst, dass deine Programme mit ss irgendwelchen Unfug machen, dann solltest du ss auch jedes mal ändern.

Zitat
Und muss also eine Zeichenkette voller Stackwerte von jedem Task haben?

Korrekt. Ich würds nicht Zeichenkette nennen, sondern Speicherbereich. Und das ist ja eigentlich nix besonderes, denn ich gehe mal davon aus, dass all deine Tasks irgendwie irgendwo eigenen Speicher haben.  ;)

Zitat
Und wenn ich einen Task starte muss ich auf seinem Stack vorher alle Werte für die Register draufpushen um nacher auch durch iret z.B. den cs und eip an der richtig Position zu haben?

Jupp, genau so geht es.
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 21:05
Gut, das habe ich jetzt kapiert. Aber was meintest du mit schwer wenn der Ring gewechselt wird? In den Deskritoren der Segmente steht doch der Ring, das hat doch dann nichts mit dem Taskwechsel zu tun?

EDIT: Also so habe ich es bis jetzt verstanden:

;Task wechsel:
IRQ0:
cli
pusha
push ds
push es
push fs
push gs
mov eax,ss
mov [mem],eax
mov [mem],sp

mov eax,[mem]
mov ss,eax
mov sp,[mem]
mov al,20h
out 20h,al
pop fs
pop es
pop ds
popa
sti
iret

;[mem] ist jeweils ein anderer Speicherbereich!!!


Aber wenn ich jetzt einen Task zum aller ersten mal starte, dann holt der IRQ0 Werte vom Stack die ich aber noch nie gespeichert habe??? komisch, scheck gerade gar nichts mehr...
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 21:41
So, ich speichere im IRQ0 die aktuellen Register. Wechsle dann den Stack. Hole dann vom Stack Werte zu Register. Nee, halt stop. In diesem Stack habe ich ja noch gar keine Register Werte. Was jetzt?
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 29. June 2006, 21:57
Du musst beim erstellen eines neues Tasks den Stack so aufsetzten, dass es halt stimmt :) Eigentlich alles wie in dem tutorial das ich gepostet hab beschrieben.
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 22:43
Zitat von: bluecode
Du musst beim erstellen eines neues Tasks den Stack so aufsetzten, dass es halt stimmt :) Eigentlich alles wie in dem tutorial das ich gepostet hab beschrieben.
Aso, gut dann habe ich das jetzt glaube ich verstanden. Nur verstehe ich immer noch nicht wieso wir überhaubt ein TSS brauchen. Das ganze kann ich doch auch ohne TSS machen. Was meinst du mit ss0 und esp0?

Ach ja, und so tu ich einen Task für den ersten Start vorbereiten:

cli ;IRQ0 nicht aufrufen

push ss
push esp

mov eax,neuer Stack Selector
mov ss,eax
mov esp,neuer Stackpointer

push 0000001000000010b ;eflags
push 1 << 3 ;cs
push task1  ;eip
push 0 ;eax
push 0 ;ecx
push 0 ;edx
push 0 ;ebx
push ? ;esp was muss hier hin?
push 0 ;ebp
push 0 ;esi
push 0 ;edi
push 2 << 3 ;ds
push 2 << 3 ;es
push 2 << 3 ;fs
push 2 << 3 ;gs

pop esp
pop ss

sti ;jetzt kann der IRQ0 wieder aufgerufen werden



So, was muss ich bei push ? ;esp was muss hier hin? schreiben? Was muss bei dem ? hin? Weil da muss ja ein gültiger Wert hin, sonst ist esp ja kaput.

Ist das bis jetzt alles richtig?

danke!!!
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 29. June 2006, 22:58
Zitat von: bitmaster
Nur verstehe ich immer noch nicht wieso wir überhaubt ein TSS brauchen. Das ganze kann ich doch auch ohne TSS machen. Was meinst du mit ss0 und esp0?

esp0/ss0 sind nur beim software-taskswitching mit änderung des Priviledgelevels wichtig, da soe dort aus dem TSS entnommen werden und eben als neues SS/ESP genommen werden (des is dann der ich nenns mal "kernel-level task stack"). Auf dem Stack werden dann des alte SS/ESP, die EFlags, CS/EIP gesichert, welche beim iret widerhergestellt werden.
Beim softwaretaskswitching ohne änderung des Priviledgelevels wird der Stack nicht gewechselt, sondern nur EFlags/CS/EIP auf dem Stack gesichert, welche auch beim iret wiederhergestellt werden.
Zusätzlich zu den bereits gesicherten Regs musst dann halt noch die Generalpurpose regs sichern.

Zitat von: bitmaster
So, was muss ich bei push ? ;esp was muss hier hin? schreiben? Was muss bei dem ? hin? Weil da muss ja ein gültiger Wert hin, sonst ist esp ja kaput.

Du musst das push esp weglassen, da bei pusha/popa esp nicht gesichert/wiederhergestellt wird (Das scheint in dem Tutorial falsch zu sein...).
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 23:05
@bluecode: danke

aber:

Zitat
esp0/ss0 sind nur beim software-taskswitching mit änderung des Priviledgelevels wichtig, da soe dort aus dem TSS entnommen werden und eben als neues SS/ESP genommen werden (des is dann der ich nenns mal "kernel-level task stack").
Und woher weiß ich, wann ich die esp0/ss0 auslesen muss und wann nicht.

Zitat
Auf dem Stack werden dann des alte SS/ESP, die EFlags, CS/EIP gesichert, welche beim iret widerhergestellt werden.
iret läd aber ss und esp nicht. Sondern nur die EFlags, cs/eip.

Zitat
Zusätzlich zu den bereits gesicherten Regs musst dann halt noch die Generalpurpose regs sichern.
Was ist das?

Zitat
Du musst das push esp weglassen, da bei pusha/popa esp nicht gesichert/wiederhergestellt wird (Das scheint in dem Tutorial falsch zu sein...).
Doch, pusha und popa verändern auch das esp.

bitmaster
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 29. June 2006, 23:09
Zitat von: bitmaster
iret läd aber ss und esp nicht. Sondern nur die EFlags, cs/eip.

Doch genau das macht iret, wenn in den EFlags das PL != das PL von CS ist ;) Damit hat sich wohl auch die erste Frage erledigt

Zitat von: bitmaster
Zitat
Zusätzlich zu den bereits gesicherten Regs musst dann halt noch die Generalpurpose regs sichern.
Was ist das?

halt eax, ebx, ecx, edx (esi, edi, ebp)

Zitat von: bitmaster
Zitat
Du musst das push esp weglassen, da bei pusha/popa esp nicht gesichert/wiederhergestellt wird (Das scheint in dem Tutorial falsch zu sein...).
Doch, pusha und popa verändern auch das esp.

sry, habs grad auch nochma nachgeschaut. pusha sichert zwar esp, aber popa ignoriert den gepushten wert einfach => 0 setzten.
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 29. June 2006, 23:29
Zitat
sry, habs grad auch nochma nachgeschaut. pusha sichert zwar esp, aber popa ignoriert den gepushten wert einfach => 0 setzten.
Wie kommst du denn darauf?
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 29. June 2006, 23:36
Intel Manual #2 unter popa (bei mir Seite 633):
Zitat
The value on the stack for the ESP or SP register is ignored. Instead, the ESP or SP register is incremented after each register is loaded.
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 30. June 2006, 00:53
Zitat von: bluecode
Intel Manual #2 unter popa (bei mir Seite 633):
Zitat
The value on the stack for the ESP or SP register is ignored. Instead, the ESP or SP register is incremented after each register is loaded.
ou, stimmt
bei mir stehts im Assemblerbuch von Addison-Wesley auf Seite 97 auch:

popa mach folgendes:

pop (e)di
pop (e)si
pop (e)bp
add (e)sp, (4)2
pop (e)bx
pop (e)dx
pop (e)cx
pop (e)ax


Hmm... ich habe das zwar die ganze Zeit gelesen, aber wohl irgendwie nicht wahr genommen. ^^

Ich habs jetzt mit dem Softwaremultitasking geschaft. Der Kernel wird ausgeführt, dann wird zum IRQ0 gesprungen, der Führt dann zum Task, dann wird wieder der IRQ0 aufgerufen, der Führt wieder zum Kernel, dann wird wieder der IRQ0 aufgerufen, der Führt wieder zum Task usw.

Juhu, ich habs jetzt entlich kapiert und es funktioniert. Jetzt kommt aber wieder mein berühmtes - aber - ^^

Aber ich kapiere das nicht mit den: esp0, ss0, esp1, ss1, esp2 und ss2. Wozu sind die da? Jeder Task (auch der Kernel) hat bei mir einen neuen Stack. Brauchen die jetzt auch noch jeder 3 Stacks? Und wann soll ich die 0, 1 und 3 sachen denn nutzen?

danke!!!
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 30. June 2006, 04:03
Zitat von: bitmaster
Aber ich kapiere das nicht mit den: esp0, ss0, esp1, ss1, esp2 und ss2. Wozu sind die da? Jeder Task (auch der Kernel) hat bei mir einen neuen Stack. Brauchen die jetzt auch noch jeder 3 Stacks? Und wann soll ich die 0, 1 und 3 sachen denn nutzen?

Ok stell dir vor, du würdest den Inahlt der Register auf dem normalen Stack einer App speichern, was könnte die dann ganz leicht machen? Genau, in den EFlags zB das PL ändern, oder das CS ändern. Das wären alles keine so tollen Sachen ;) Deshalb wechselt die CPU beim taskswitchen von CPL3 nach CPL0 automatisch den Stack und pusht da die alten Register (bei denen man nun SS3 und ESP3 sagt) SS3, ESP3, EFlags, CS, EIP.

Aber eigentlich ist das beim Hardware taskswitching auch nicht anders :wink:
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 30. June 2006, 14:19
Zitat
Aber eigentlich ist das beim Hardware taskswitching auch nicht anders
Jo, da macht die CPU das ja alles von selbst (weshalb ich Hardwaretasking eigentlich auch inteligenter finde). Aber ich habe bis jetzt sowieso alles nur Privilegstufe Null. Ich muss mich da in der Materie noch mal einarbeiten.

danke!!!
Titel: Softwaremultitasking, aber wie?
Beitrag von: Osbios am 30. June 2006, 14:39
Zitat von: bluecode
Ok stell dir vor, du würdest den Inahlt der Register auf dem normalen Stack einer App speichern, was könnte die dann ganz leicht machen? Genau, in den EFlags zB das PL ändern, oder das CS ändern. Das wären alles keine so tollen Sachen ;) Deshalb wechselt die CPU beim taskswitchen von CPL3 nach CPL0 automatisch den Stack und pusht da die alten Register (bei denen man nun SS3 und ESP3 sagt) SS3, ESP3, EFlags, CS, EIP.

Aber eigentlich ist das beim Hardware taskswitching auch nicht anders :wink:


Da kann ich nicht ganz zustimmen.

Wenn man den Stack des Programmes zum Speichern der Register benutzt dann passiert das alles in dieser Reihenfolge:

- Task läuft
- Task wird unterbrochen
- Register werden auf Taskstack gesichert
jetzt mach das OS was es will (z.B. Taskwechsel oder Bluescreen) ...
- Register werden vom Stack zurückgesichert
- Task wird fortgesetzt

Der Task hat also keine Möglichkeit die EFlags oder etwas andere zu verändern, weil er niemals ausgeführt wird wenn sich die Register auf dem Stack befinden.

ABER:
Ein voller Stack würde die Registersicherung eines Interruptaufrufes natürlich nicht mehr aufnehmen können.
Ungültige werte im SS oder ESP Register des Tasks sind auch möglich.

Deshalb besitzt jeder Ring einen eigenen Stack.
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 30. June 2006, 18:08
Zitat von: Osbios
Der Task hat also keine Möglichkeit die EFlags oder etwas andere zu verändern, weil er niemals ausgeführt wird wenn sich die Register auf dem Stack befinden.

Da kann ich wiederum nicht zustimmen :-D Schonmal an Multithreading gedacht? Da könnte dann ein Thread die EFlags,etc. des anderen verändern.
Titel: Softwaremultitasking, aber wie?
Beitrag von: bitmaster am 30. June 2006, 23:52
Zitat
Deshalb besitzt jeder Ring einen eigenen Stack.
Also was jetzt genau? Jeder Ring nur einen Stack? Also 3 Stacks, oder jeder Task 3 Stacks?

bitmaster
Titel: Softwaremultitasking, aber wie?
Beitrag von: bluecode am 01. July 2006, 03:15
Zitat von: bitmaster
Zitat
Deshalb besitzt jeder Ring einen eigenen Stack.

Also was jetzt genau? Jeder Ring nur einen Stack? Also 3 Stacks, oder jeder Task 3 Stacks?

Lass dich nicht unnötig verwirren: Benutz nur Ring 0 (Kernel) und Ring 3 (User). Dann brauchst du nen normalen User-Stack, nen Stack auf dem die Register gespeichert werden und evtl. (falls dein kernel viel stack verbraucht) auch noch nen eigenen kernel-stack. Das macht 2 stacks pro task + evtl. einen für den kernel (pro prozessor, falls du mehrere Prozessoren unterstützen willst)..