Autor Thema: Verständnissproblem mit paging und prozessen  (Gelesen 3441 mal)

Peabrain

  • Beiträge: 7
    • Profil anzeigen
Gespeichert
« am: 11. August 2009, 10:42 »
hallo.

ich habe da wohl ein kleines problem mit dem protected mode.
es ist toll, daß es so super dokumentationen über den protected mode gibt. jeder gibt einen einstieg bis zu dem punkt, wo es zum taskwechsel und diesem mystetiösen cr3 register geht. das haben anscheinend die wenigsten wirklich verstanden. ich gehöre blöderweise auch dazu.

deswegen frage ich hier einfach mal nach und hoffe auf hilfe.

also.
1. frage ist die adresse die ich mit lgdt lade cr3 relativ oder ist es eine absolute adresse?
2. ich habe eine gdt mit 4 werten (0, codedescriptor, datadescriptor und stackdescriptor). alle zeigen auf die adresse 0 und haben das maximale limit des speichers.
dann habe ich eine pagedir und die entsprechenden pagetables um den speicher von 0 bis 4 mb zu mappen. gut.

mein programm liegt ab 8000h.  soweit funktioniert alles.

jetzt kommt das seltsame, was ich nicht verstehe.

ich lege einen tss descriptor an und trage ihn in die gdt. ich fülle den tss aus, wobei ich das cr3 register auf eine pagedir/pagetable  setze die alles ab 0 mb auf 1 mb (wo ich mein neues programm hinkopiert habe) mapped und ip ist 0. cs,ds,es ... setze ich entsprechend der gdt. der stack liegt 4096 bytes hinter dem programm und der esp ist auf die adresse -4 gesetzt.

sobald ich den descriptor des tss anspringe, stürzt er ab. seltsamerweise wenn ich das mapping der neuen pagedir/pagetable nur bis 8000h auf 1mb mappe, klappt es. sehr seltsam. oder gibts da eine einfache erklärung?

wenn ihr code braucht einfach bescheid sagen.

danke.

gruß.

ps: gibt es eigentlich bücher über dieses thema? die meißten behandeln das paging nur nebenbei.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 11. August 2009, 11:01 »
es ist toll, daß es so super dokumentationen über den protected mode gibt. jeder gibt einen einstieg bis zu dem punkt, wo es zum taskwechsel und diesem mystetiösen cr3 register geht. das haben anscheinend die wenigsten wirklich verstanden. ich gehöre blöderweise auch dazu.
So mysteriös ist das gar nicht, ich habe mich bisher nur noch nicht aufraffen können, den nächsten Teil der Tutorialreihe zu schreiben. Da würde dann Paging vorkommen. ;)

Zitat
1. frage ist die adresse die ich mit lgdt lade cr3 relativ oder ist es eine absolute adresse?
Erstmal den groben Überblick: Aus einer virtuellen Adresse wird über die Segmentierung eine lineare Adresse, dafür ist die GDT zuständig. Danach wird aus der linearen Adresse über Paging eine physische Adresse, dafür sind die Page Tables zuständig. Wenn man sich merkt, dass Segmentierung "oberhalb" von Paging stattfindet, klappt das auch mit der GDT: Die GDT-Adresse ist eine lineare Adresse, wird also von cr3 beeinflusst.

Zitat
2. ich habe eine gdt mit 4 werten (0, codedescriptor, datadescriptor und stackdescriptor). alle zeigen auf die adresse 0 und haben das maximale limit des speichers.
Sehen Daten- und Stackdeskriptor dann nicht genau gleich aus? Meistens verwendet man da einfach denselben.

Zitat
ich lege einen tss descriptor an und trage ihn in die gdt. ich fülle den tss aus, wobei ich das cr3 register auf eine pagedir/pagetable  setze die alles ab 0 mb auf 1 mb (wo ich mein neues programm hinkopiert habe) mapped und ip ist 0. cs,ds,es ... setze ich entsprechend der gdt. der stack liegt 4096 bytes hinter dem programm und der esp ist auf die adresse -4 gesetzt.

sobald ich den descriptor des tss anspringe, stürzt er ab. seltsamerweise wenn ich das mapping der neuen pagedir/pagetable nur bis 8000h auf 1mb mappe, klappt es. sehr seltsam. oder gibts da eine einfache erklärung?
Ich komme hier ehrlichgesagt nicht ganz mit, was du machst. Aber eine einfache Erklärung gibt es ziemlich sicher. ;)

Was für einen Absturz gibt es denn genau? Grundsätzlich produzieren TSS-bezogene Sachen sehr gern einen GPF, aber dein Problem scheint ja mit Paging zusammenzuhängen - ist es also ein Page Fault?

Ich glaube, an dieser Stelle musst du einfach mal ein bisschen Code herzeigen, damit wir sehen, was du genau machst.

Zitat
ps: gibt es eigentlich bücher über dieses thema? die meißten behandeln das paging nur nebenbei.
Ich kann dazu eigentlich nur zwei "Standardwerke" empfehlen: Die Doku von Intel und die von AMD. Dort ist alles (und zwar wirklich alles) sehr detailliert beschrieben - dummerweise ist es dann halt wieder so ausführlich, dass man als Anfänger den Wald vor lauter Bäumen nicht mehr sieht. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Peabrain

  • Beiträge: 7
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 12. August 2009, 09:11 »
danke erstmal für deine antwort.

ich hab mir die dokumentationen von intel nochmal genauer angesehen und festgestellt, wenn ich im tss bei eflags keine 0x200 (nt=flag nehme ich an) setze funktioniert es. na mal sehen, vielleicht sollte ich dieses flag erst setzen, wenn ich im taskmanager angekommen bin.
 ich werds mal ausprobieren.

und außerdem müssen wohl alle globalen variablen und tabellen in jeder pagedir an der gleichen adresse stehen. hmm. auch blöd.

so, jetzt muss ich mein ursprüngliches projekt erstmal wieder meinem neuen kenntnissstand anpassen.

danke nochmal,

gruß

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 12. August 2009, 11:51 »
Ich wüsste eigentlich wofür man das NT-Bit benutzten kann, aber eventuell solltest du dir wenn du das unbedingt brauchst das Kapitel 6.4 Task Linking in den Intel Manuals durchlesen. Das NT-Bit wird eigentlich nur verwendet, wenn du mit call in andere TSS springst, was afaik aber niemand macht.
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

Peabrain

  • Beiträge: 7
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 12. August 2009, 12:36 »
also ich hab die 0x200 im tss.flag zu stehen, weil er mir sonst das tss beim taskwechsel garnicht ausfüllt. vielleicht liegt auch da der fehler. den taskwechsel selbst mache ich mit dem backlink und einem iret.

also im moment funktioniert alles soweit. nur das mit den interrupts geht nicht richtig. die vektoren scheinen auch vom cr3 modifiziert zu werden. was natürlich ungünstig ist, wenn man sie von irgendwo aufruft und im cr3 register steht eine andere table drin. hmm.

alles ein wenig verwirrend. :)

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #5 am: 12. August 2009, 22:57 »
Normalerweise verwendet man (bei x86) kein Hardwaremultitasking mehr, sondern Softwaremultitasking, d.h. man nimmt die TSS nur für den Stackwechsel her, das sichern übernimmt man dann selbst in eine geeignete Struktur. Dann braucht man nur ein TSS (pro CPU). Das wird im Lowlevelwiki von taljeth etwas breiter getreten, insofern schau dort nach, wenn du eine konkrete Umsetzung davon sehen willst.
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

Peabrain

  • Beiträge: 7
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 15. August 2009, 08:35 »
aber wo liegt der vorteil im softwaremultitasking?
man verbraucht auf jedenfall den selben speicher, denn die strukturen zum speicher der tss müssen ja auch dort vorhanden sein.
desweiteren sehe ich da ein sicherheitsproblem, da die hardwareinterrupts keinen pl check machen. somit kann jeder der an den pit und die irqtable rankommt, den scheduler ändern.

oder hab ich was übersehen?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 15. August 2009, 09:57 »
Du hast beim Software-Multitasking nur noch ein TSS pro CPU statt eins für jeden Task. Insofern hält sich die Speicherverschwendung in Grenzen. Die wesentlichen Vorteile sind wohl, dass es einfacher geht und schneller ist.

Wo du ein Sicherheitsproblem siehst, weiß ich nicht, aber ich bin mir sehr sicher, dass es keins gibt. Dass jeder, der an Kernelinterna rankommt, was daran herumpfuschen kann, ist normal und hat mit Software-/Hardwaremultitasking nichts zu tun. Die Lösung ist so einfach wie effektiv: Userspace darf halt nicht auf Kernelspeicher zugreifen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Peabrain

  • Beiträge: 7
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 16. August 2009, 22:29 »
hmm, das mit den tss in der gdt stimmt wohl. nur muß man ja trotzdem noch für jeden task eine struktur zur speicherung anlegen. also speicher spart man nicht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #9 am: 16. August 2009, 22:41 »
Es geht da eher um die Anzahl der Deskriptoren in der GDT und die Geschwindigkeit, wie bereits gesagt wurde.
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