Wozu brauche ich diesen UserStack? Es existiert ja bereits ein Threadeigener Stack, also wozu nocheiner?
Für Userland und Kernel brauchst du unterschiedliche Stacks, weil ansonsten Usercode den Kernelstack kaputtmachen könnte. Entweder irgendwelche Kerneldaten überschreiben, die auf dem Stack liegen, oder auch gern einfach esp irgendwo in die Botanik setzen. Wenn man also denselben Stack für beides benutzen könnte, hätte man ein Sicherheitsproblem. Damit das nicht passiert, ist der Protected Mode so gebaut, dass bei jedem Ringwechsel auch immer gleich ein Stackwechsel dabei ist.
Ein eigener Userspace-Stack für jeden Thread muss also unbedingt sein. Wo man eventuell noch Sachen zusammenlegen kann, ist bei den Kernelthreads. Theoretisch reicht da einer pro CPU, allerdings kann man dann den Prozessorzustand nicht mehr einfach bequem auf den Stack pushen und dort liegen lassen, bis man wieder zu diesem Task zurückkommt, weil der Stack ja vom nächsten Task weiterbenutzt werden würde. Stattdessen müsste man den Registerzustand z.B. direkt in der struct task speichern.
Weshalb wird dieses TSS gebraucht? Die UserStack-Adresse übergebe ich ja bereits im CPU-State
Das TSS wird benutzt, wenn vom Userspace in den Kernel zurückgewechselt wird, z.B. durch einen IRQ oder eine Exception. Die Kernelstack-Adresse kann der Userspace erstens nicht geben, weil er gar nicht weiß, wann ein IRQ kommt, und zweitens wäre das ja wieder ein Sicherheitsproblem.
Nun zum konkreten Problem und Code:
Ich vermute, dass die Emulatoren beim GDT abstürzen.
Warum vermutest du nur? Du kannst z.B. mit einer Endlosschleife genau eingrenzen, wo es passiert.
Kann man eigentlich davon ausgehen dass der Gcc das "Gdt_SetEntry" komplett so inlined und optimiert, dass es wie eine einfache Zuweißung einer LL-Konstante im Assemblercode dasteht?
Mit einer hohen Optimierungsstufe und konstanten Parametern würde es mich nicht wundern, wenn er das tatsächlich hinbekommt. Allerdings spielt das überhaupt keine Rolle, der Code braucht nämlich nur ein paar Takte und läuft eh nur genau einmal während der gesamten Laufzeit des Kernels...