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.
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.
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).
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.
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.
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
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.
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.