Memory Managment



  • Steckt man die paar Zeilen der init-Funktion direkt an den Anfang der main-Funktion, klappt alles. Verrücktes Verhalten. Ich würde sagen, wir lassen es erstmal bei -O.



  • Der Code ist sehr wahrscheinlich auch mit -O kaputt, nur subtiler. Solche Bugs werden vom Liegenlassen jedenfalls meistens nicht einfacher.



  • Da hast du wohl recht.



  • Oder es fehlt einfach irgendwo ein "volatile"...



  • Bei Treibern mag das ja regelmäßig vorkommen, aber eine Speicherverwaltung, die volatile braucht, wäre mir suspekt. 😉



  • An der Speicherverwaltung kann es gar nicht liegen, die wird erst später initialisiert, nach dem Crash. Der Code, der bis zum Absturz durchlaufen wird, ist auch relativ überschaubar. Direkt nach dem Eintritt in die main-Funktion wird die "init"-Funktion aufgerufen, die folgende Sachen ausführt:

    clear_screen();
    settextcolor(14,0);
    printformat("PrettyOS [Version 0.0.0.221]\n");
    gdt_install();
    idt_install();
    timer_install();
    keyboard_install();
    syscall_install();
    settextcolor(15,0);
    

    Auf den ersten Blick in diese Funktionen sieht das alles recht ungefährlich aus. Die Sachen laufen auch gut durch, beim return geht irgendwas schief, scheint also der Stack kaputt zu sein. Bloß woher 😕 Ich bin schon dabei, zu debuggen und zu disassemblern, ist aber eine eklige Arbeit..



  • Ist eher alles ein Problem mit den Kompilerflags. Folgendes Beispiel:

    // ckernel.c Revision 219
    
    int main()
    {
    for(;;); // <- Endlosschleife :)
    
        init();
    (...)
    }
    

    Ohne Flag "-O" stürzt PrettyOS ab, woraus vorerst nur folgen soll, daß die Endlosschleife nicht ausgeführt wurde (also "verschwunden" ist).

    Mit Flag "-O" bleibt PrettyOS in der Endlosschleife hängen, was heißt, daß sie nicht "verschwunden" ist.

    Daraus folgt, daß der GCC auch ohne Angabe von Optionen zur Optimierung den Quellcode wie auch immer verändert. Insofern wirst Du wahrscheinlich im Quellcode auch keine Fehler finden. 🙂



  • Da läuft beim Linken was schief, aber ist der Grund jetzt klar. Der eigentlich als Einstiegscode gedachte "KernelStart" liegt irgendwo in der Mitte des Binaries.

    Mit Compiler-Option -O0 wird die "init"-Funktion nicht ge-inline-t und liegt am Anfang des Binaries, d.h. der Code springt direkt in die init-Funktion, ohne vorher in der "main" gewesen zu sein. Logisch, dass dann keine gültige Rücksprungadresse auf dem Stack liegt und es kracht.

    Mit -O wird die "init"-Funktion ge-inline-t und die "main"-Funktion liegt direkt am Anfang des Binaries. Damit klappt es zwar, ist aber nicht im Sinne des Erfinders, die "KernelStart"-Funktion gibt es ja nicht umsonst, sie setzt z.B. den Stack auf 0x01900000.

    D.h. irgendwie bekommt der Linker es nicht hin, die "KernelMain" an den Anfang des Binaries zu setzen, obwohl die Funktion im Linkerscript als "ENTRY" markiert ist. Hat jemand eine Idee?

    edit: Danke, +gjim+!



  • Ok, habs. Im Linkerscript muss STARTUP(kernel.o) gesetzt sein, das ENTRY spielt keine Rolle. Ich comitte.

    edit: Was für ein Krampf 🙂



  • Trotzdem könnte man hier mal anmerken, dass man genau wegen sowas ELF oder ähnliche Formate will (die also einen Entrypoint haben)...


  • Mod

    Eine Frage aus dem IRC:

    ich frag mich, ob es wirklich nötig ist, die page tables für den kernel bereich im voraus zu allokieren.



  • Kann jemand die meory map irgendwie erwitern ? Mehr details wären cool, vielleicht auch graphisch.

    Apropo, ich kann auch osdev.org empfehlen.



  • Im Repository befindet sich unter /documentation/memory.txt eine detailiertere und aktuellere Übersicht.


Anmelden zum Antworten