PrettyOS Fehler-/Testthread



  • Revision 295
    Es gibt tatsächlich ein Paging-Problem:

    ; user\user_tools\start.asm 295
    
    _start:
    ; mov esp, 0x600000 ; stackpointer
    
      mov esp, 0x01402000 ; <- solange das problem nicht beseitigt ist
    

    Wenn der Stack der USER mit Adresse 0x600000 inititialisiert wird, benutzen sämtliche USER einen identischen Stack (und somit auch identische lokale Variablen (was heißt Adresse und Wert sämtlicher lokalen Variablen sind bei sämtlichen USERN identisch (sofern man ein Programm mehrmals startet). ( <- Hoffentlich kam das verständlich rüber 🙂 .).

    Irgendwie wird Adresse 0x600000 (und KERNELs 0x500000) nicht korrekt "gepaged".

    Wenn KERNEL (Shell) und alle USER die 0x01402000 benutzen, gibt es keine Probleme. Ein (dann neues) Problem gäbe es erst, wenn die Shell und/oder die Userprogramme > 0x2000 Bytes wären.


  • Mod

    Irgendwie wird Adresse 0x600000 (und KERNELs 0x500000) nicht korrekt "gepaged".

    Das passiert hier in paging.c, line 262, in paging_install:

    // Setup 0x00400000 to 0x00600000 as writeable userspace
        kernel_pd->codes[1] |= MEM_USER | MEM_WRITE;
        for (int i=0; i<512; ++i)
            kernel_pd->tables[1]->pages[i] |= MEM_USER | MEM_WRITE;
    

    wobei wir nicht 0x600000, sondern 0x5fffff nehmen sollten.

    Die shell ist übrigens ein User_Programm und wird auch genauso gestartet.



  • Erhard Henkes schrieb:

    wobei wir nicht 0x600000, sondern 0x5fffff nehmen sollten.

    Nein, da ein PUSH zuerst ESP um vier verringert und dann den Wert auf den Stack legt. Somit führt ESP==0x600000 dazu, dass das erste PUSH den Wert nach 0x5FFFFC legt (im Übrigen sollte man wohl besser keinen unalignten Stack benutzen, der Wert sollte IMO besser immer an vier ausgerichtet sein).


  • Mod

    @XanClic: ja, ist richtig. Sorry, da hat Jarvix mich irritiert. 😉

    @+gjm+: danke, wir nehmen nun 0x1420000 als gemeinsame virtuelle Stackadresse, allokieren aber für jedes User-Programm in create_task und nicht nur einmal in paging_install. Damit sind die physikalischen Speicheradressen wirklich verschieden.



  • Wie bereits im IRC gesagt, bekomme ich direkt nach dem Start einen Pagefault:

    PrettyOS schrieb:

    `<RAM Disk at C0005000h DIR> dev

    35 info

    13104 shell

    Page Fault ( read-only - write operation user-mode) at 004FFFFCh - EIP: 014013F5h

    err_code: 00000007h address(eip): 014013F5h

    edi: 00000000h esi: 00000000h ebp: 00000000h eax: 00000000h ebx: 00000000h ecx: 00000000h edx: 00000000h

    cs: 0000001Bh ds: 00000023h es: 00000023h fs: 00000023h gs 00000023h ss 00000023h

    int_no 14 eflags 00000202h useresp 00500000h

    Page Fault >>> Exception. System Halted! <<<`

    Offensichtlich wird da wohl versucht, was auf den Stack zu legen, das klappt aber nicht (warum auch immer, ob die Page jetzt wirklich Read-Only ist, wie es angezeigt wird, oder ob sie nicht für den Usermode ist) und das Programm verabschiedet sich mit einer Protection Violation.

    EDIT: OK, das Problem bestand darin, dass man offensichtlich erstmal make clean ausführen muss, was ich nicht getan habe. Jetzt läuft es. 🙂


  • Mod

    Lag offenbar daran, dass immer noch 0x500000 vorgegeben wurde durch alte Dateien, jetzt aber 0x1420000. Nach Update auch bei XanClic: "Na ja, es scheint zu funktionieren". 😉

    Bei mir läuft es aber auf real PC noch nicht, stürzt bei Eingabe in TTT ab.



  • Revision 303

    Kleiner Fehler in der console.c. Betrifft zwei Stellen:

    // console.c 303
    
    void console_init(console_t* console, const char* name)
    {
    (...)
    //    memsetw (console->vidmem, 0x20 | (console->attrib << 8), COLUMNS * USER_LINES * 2);
    memsetw (console->vidmem, 0x20 | (console->attrib << 8), COLUMNS * USER_LINES );
    (...)
    }
    
    void clear_console(uint8_t backcolor)
    {
    (...)
    //    memsetw (current_console->vidmem, 0x20 | (current_console->attrib << 8), COLUMNS * USER_LINES * 2);
    memsetw (current_console->vidmem, 0x20 | (current_console->attrib << 8), COLUMNS * USER_LINES);
    (...)
    }
    

    memsetw! Das "* 2" bewirkt, daß doppelt soviel Speicher überschrieben wird wie eigentlich gedacht. Das könnte auch der Fehler sein, warum TTT auf dem realen PC nicht läuft. VMs schummeln ja immer. 🙂


  • Mod

    danke, wurde umgesetzt. 🙂


  • Mod

    Für den anstehenden Code Review schlage ich folgende Reihenfolge vor (analog Start):

    Bootloader 1
    Bootloader 2
    Kernel:
        gdt_install();
        idt_install();
        timer_install();
        keyboard_install();
        mouse_install(); <--- neu  :live: 
        syscall_install();
        setup_x87_fpu();
        paging_install();
        heap_install();
        tasking_install();
        pciScan();
        ...
    

    Damit decken wir die wesentlichen Elemente von PrettyOS ab.



  • Revision 309
    Wenn schon, denn schon: 🙂

    //memset((void*)tictactoe, 0, 18); // tictactoe has two bytes!
    memset((void*)tictactoe, 0, sizeof(tictactoe));
    

    Aber folgendes stört weiterhin:

    memset((void *)ph->vaddr, 0, ph->memsz); // to set the bss (Block Started by Symbol) to zero
    

    Sollte das den Absturz auf dem realen PC verhindern, dann wird irgendwo im Quellcode auf nicht initialisierte Variablen zugegriffen.
    Das wiederum wird der tatsächliche Grund für den Absturz sein.


  • Mod

    program_header_t* ph = (program_header_t*)header_pos;
    

    elf.c, line 138
    Hier wird ein Pointer auf die Instanz ph vom Typ struct program_header_t auf konkrete Werte gesetzt, wenn ich mich nicht täusche, oder?

    Es stürzt nichts mehr ab, alles läuft gut. Nur einige alte PC von Cuervo machen unverständliche Probleme mit Floppy/DMA beim Laden.

    memset((void*)tictactoe, 0, sizeof(tictactoe));
    

    Danke, wird so eingebaut.



  • Revision 313
    Um das TS bit in CR0 zu löschen geht auch CLTS:

    // set TS in cr0 to zero
    // uint32_t cr0;
    // __asm__ volatile("mov %%cr0, %0": "=r"(cr0)); // read cr0
    // cr0 &= ~0x8; // reset the TS bit (no. 3) in CR0 to disable #NM
    // __asm__ volatile("mov %0, %%cr0":: "r"(cr0)); // write cr0
    
    __asm__ ("CLTS"); // CLearTS
    

  • Mod

    Hey, so einfach geht das? 😃

    Gibt es dauch den entsprechenden befehl zum Setzen?



  • Den gibt es nicht. Aber könnte es sein, daß das TS bit in der "task_switch" sowieso schon von der CPU gesetzt wurde?


  • Mod

    Da wir software task switching durchführen eher nicht. 🙂



  • Revision 341
    "vidmem" ist ein uint16_t*. Deshalb kopiert "2*i" nur jedes zweite Zeichen vom screenshot:

    // video.c
    static void catchVidmem()
    {
    uint16_t* vidmem = (uint16_t*) 0xB8000;
    (...)
    // videoscreen[j] = *(uint8_t*)(vidmem + 2*i);
    videoscreen[j] = *(uint8_t*)(vidmem + i);
    (...)
    }
    

  • Mod

    @+gjm+: Vielen Dank! Keine Ahnung, bei welcher "Aufräumaktion" das passiert ist, sieht einfacher aus und funktioniert, daher sofort implementiert. 🙂 👍


  • Mod

    In Rev. 342 korrigiert: ctrl+s: process, ctrl+t: thread



  • Fehler in 344:

    Bei "hello.elf":
    http://prettyos.fanofblitzbasic.de/error.png QEMU
    http://prettyos.fanofblitzbasic.de/error2.png VirtualBox
    wenn man scrollt.. sieht aber witzig aus^^



  • // os.h
    
    //static const uint8_t USER_LINES = 46;
    static const uint8_t USER_LINES = 42;
    

    Sonst fährt der Zug zeilenweise mit nach oben. 🙂


Anmelden zum Antworten