Autor Thema: Exception bei Mutitasking  (Gelesen 2654 mal)

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« am: 03. December 2012, 18:39 »
Also ich wollte mal nach langer Zeit mal wieder an meinem OS weiterarbeiten.
Das Problem ist, der Kernel löst nach dem 400 Timerinterupt beim Taskwechsel vom 1. Prozess zurück in den 0. eine Generall Protection Exception (13) aus.

Da das Multitasking aus mehreren größeren Dateien besteht, hab ich es angehängt.
Wäre um einen Tipp, wie ich dem Fehler zu Leibe rücken kann, sehr dankbar.  :-)
Was mich so irritiert ist, dass der Taskwechsel vorher einigemale klappt.

Die Textdatei im Anhang ist eine falsche 7-Zip-Datei, damit ich sie hochladen kann.
Warum sind hier keine Zipdateien erlaubt? Finde ich ziemlich umständlich.  :wink:
« Letzte Änderung: 03. December 2012, 21:02 von OS_3000 »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 03. December 2012, 18:52 »
Weil du den Code erstmal selber debuggen sollst. ;)

Die erste interessante Frage wäre, welcher Code an eip = 0x1024a3 ist.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 03. December 2012, 20:23 »
Wie kriege ich denn raus, welcher Code an 0x1024a3 liegt?
Debuggen algemein ist in der Betriebssystementwicklung ja generel eher schwer möglich.
Das einzige was ich sicher weiß ist noch, dass der Fehler nicht auftrit, wenn ich "Console_WriteChar" in den Multitaskthreads auskommentiere...

init.c
void Write0()
{
    while(true)
    {
        //halt();
        Console_WriteChar('0');
        for(int i = 0; i < 0x6fffff; i++) nop10();
    }
}
void WriteX()
{
    while(true)
    {
        //halt();
        Console_WriteChar('X');
        for(int i = 0; i < 0x6fffff; i++) nop10();
    }
}
void main(Multiboot_Info* MultibootInfo)
{
    Time_Read(&StartTime);
    Console_ClearScreen();
       
    Console_WriteHeader("Kernel gestartet!");
    Console_Write("Bootloader: ");
    Console_WriteLine(MultibootInfo->BootloaderName);
    Console_Write("Prozessorhersteller: ");
    int Processorvendor = CpuId_ReadVendor();
    Console_WriteVendor(Processorvendor);
    Console_NewLine();
    if (Processorvendor == CPUID_VENDOR_INTEL)
    {
        Console_Write("Prozessortype: ");
        Console_WriteIntelProcName();
        Console_NewLine();
    }
    Console_Write("Startzeit: ");
    Console_WriteTime(&StartTime);
    Console_NewLine(); Console_NewLine();
   
    Console_WriteHeader("Lade Kernel");
    Gdt_Init();
   
    ProcessCount = 2;
    Processes[0] = Process_New();
    Processes[0].Threads[0] = Thread_New(Proc0Thread0Stack, THREAD_STACKSIZE, Proc0Thread0UserStack, THREAD_USERSTACKSIZE, &WriteX);
    Processes[1] = Process_New();
    Processes[1].Threads[0] = Thread_New(Proc1Thread0Stack, THREAD_STACKSIZE, Proc1Thread0UserStack, THREAD_USERSTACKSIZE, &Write0);
   
    Intr_Init();
    stop();
}

console.c
#define CONSOLE_LINELENGTH (80)
#define CONSOLE_LINECOUNT (25)
#define CONSOLE_CHARCOUNT (CONSOLE_LINECOUNT * CONSOLE_LINELENGTH)
#define CONSOLE_VIDEO ((uint16_t*) 0xb8000)

__attribute__((unused)) uint32_t Console_Curser = 0;
__attribute__((unused)) uint32_t Console_UsingLines = 23;
__attribute__((unused)) uint8_t Console_Format = 0x07;
__attribute__((unused)) bool Console_ShowCurser = true;

[...] //Sehr viel jetzt nicht relevanter Code

void Console_ShiftUp()
{
    for(int i = 0; i < CONSOLE_CHARCOUNT; i++)
    {
        if (i < (CONSOLE_CHARCOUNT - CONSOLE_LINELENGTH))
        {
            //Untere Zeile nach oben kopieren
            CONSOLE_VIDEO[i] = CONSOLE_VIDEO[i + CONSOLE_LINELENGTH];
        }
        else
        {
            //Unterste Zeile leeren
            CONSOLE_VIDEO[i] = ((uint16_t)EMPTYCHAR) | (((uint16_t)Console_Format) << 8);
        }
    }
    //Curser eine Zeile nach oben verschieben
    Console_Curser -= CONSOLE_LINELENGTH;
    Console_CurserMove();
}

void Console_NewLine()
{
    //Zeiger platzieren
    Console_Curser -= Console_Curser % CONSOLE_LINELENGTH;
    Console_Curser += CONSOLE_LINELENGTH;
   
    //Zeilen hochschieben wenn nötig
    if (Console_UsingLines >= (Console_Curser * CONSOLE_LINELENGTH))
    {
        Console_ShiftUp();
    }   
}

void Console_WriteChar(const char Char)
{
    //Zeiger platzieren
    if (Char == NEWLINE)
    {
        Console_NewLine();
        return;
    }

    //Zeilen hochschieben wenn nötig
    if ((Console_Curser / CONSOLE_LINELENGTH) >= Console_UsingLines)
    {
        Console_ShiftUp();
    }     

    //Zeichen schreiben
    CONSOLE_VIDEO[Console_Curser++] = ((uint16_t)Char) | (((uint16_t)Console_Format) << 8);
}
« Letzte Änderung: 03. December 2012, 20:54 von OS_3000 »

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 03. December 2012, 20:31 »
objdump -dS kernel > kernel.txtdisasembliert deinen kernel.
dort nach 0x1024a3 suchen und dann weißt du es

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 03. December 2012, 20:53 »
Ok, danke für den Tipp. Werde ich versuchen.
Ich habe derweil meinen vorherigen Post "überarbeitet".   :wink:

EDIT:
Das hat schonmal wirklich geholfen.  :-)
Ein Geheimtipp den ich mir unbedingt merken sollte.

Den Assemblerausschnitt bei der Adresse:
00102490 <Console_CurserMove>:
  102490: 55                    push   %ebp
  102491: 89 e5                mov    %esp,%ebp
  102493: 80 3d 65 68 10 00 00 cmpb   $0x0,0x106865
  10249a: 74 22                je     1024be <Console_CurserMove+0x2e>
  10249c: ba d4 03 00 00        mov    $0x3d4,%edx
  1024a1: b0 0e                mov    $0xe,%al
  1024a3: ee                    out    %al,(%dx)                             ;Hier kracht es...
  1024a4: 8b 0d 30 69 10 00    mov    0x106930,%ecx
  1024aa: 89 c8                mov    %ecx,%eax
  1024ac: c1 e8 08              shr    $0x8,%eax
  1024af: b2 d5                mov    $0xd5,%dl
  1024b1: ee                    out    %al,(%dx)
  1024b2: b2 d4                mov    $0xd4,%dl
  1024b4: b0 0f                mov    $0xf,%al
  1024b6: ee                    out    %al,(%dx)
  1024b7: b2 d5                mov    $0xd5,%dl
  1024b9: 88 c8                mov    %cl,%al
  1024bb: ee                    out    %al,(%dx)
  1024bc: eb 17                jmp    1024d5 <Console_CurserMove+0x45>
  1024be: ba d4 03 00 00        mov    $0x3d4,%edx
  1024c3: b0 0e                mov    $0xe,%al
  1024c5: ee                    out    %al,(%dx)
  1024c6: b2 d5                mov    $0xd5,%dl
  1024c8: b0 07                mov    $0x7,%al
  1024ca: ee                    out    %al,(%dx)
  1024cb: b2 d4                mov    $0xd4,%dl
  1024cd: b0 0f                mov    $0xf,%al
  1024cf: ee                    out    %al,(%dx)
  1024d0: b2 d5                mov    $0xd5,%dl
  1024d2: b0 d0                mov    $0xd0,%al
  1024d4: ee                    out    %al,(%dx)
  1024d5: 5d                    pop    %ebp
  1024d6: c3                    ret   

Es scheint es Probleme beim "out"-Befehl zu geben.
Aber nur im Multitasking. Im Kernel funktioniert es.
Liege ich mit meiner Vermutung richtig, dass ich zum Lösen des Problemes Syscalls einbauen müsste?
« Letzte Änderung: 03. December 2012, 21:28 von OS_3000 »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 03. December 2012, 23:16 »
Du kannst vorläufig auch IOPL (I/O privilege level) auf 3 setzen, dann darf der Userspace in/out benutzen. Auf Dauer willst du das aber nicht haben, sonst könnte jedes beliebige Programm mit jeder Hardware herumhantieren. Nicht gut für die Sicherheit. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen