Autor Thema: Taskswitch  (Gelesen 10348 mal)

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 16. February 2013, 18:41 »
SwitchTask:
    push ebp
    push edi
    push esi
    push edx
    push ecx
    push ebx
    push eax
 
    push esp
    call multitasking_scheduler
    mov eax, esp
 
    pop eax
    pop ebx
    pop ecx
    pop edx
    pop esi
    pop edi
    pop ebp
 
    add esp, 0x8
 
    iret

So sieht meine IRQ0 Behandlung jetzt aus. Ich bekomme aber einen General Protection Fault nach dem iret. Hab ich was vergessen?
« Letzte Änderung: 16. February 2013, 19:55 von üäpöol »

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 16. February 2013, 19:54 »
Ich hab jetzt einfach mal versucht, mir den Stack vor dem iret ausgeben zu lassen:

multitasking.asm
SwitchTask:
    push ebp
    push edi
    push esi
    push edx
    push ecx
    push ebx
    push eax
 
    push esp
    call multitasking_scheduler
    mov eax, esp

    mov al, 0x20
    out 0x20, al
 
    pop eax
    pop ebx
    pop ecx
    pop edx
    pop esi
    pop edi
    pop ebp
 
    add esp, 0x8

    push esp
    call check_stack
    add esp, 0x8
 
    iret

main.c
void check_stack(unsigned int* stack){
for(int i = 0; i < 25; i++){
print(itoa(*(stack-i*4), 16), i*80, 0xF);
}
while(1);
}

Ein Screenshot von der unsinnigen Ausgabe ist angehängt.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 16. February 2013, 20:05 »
Wenn du ESP auf den Wert von EAX setzen willst, solltest du mov esp, eax schreiben. Das sollte auch die Werte auf dem Stack erklären.

(Bei dem add esp, 0x8 nach check_stack sollte das eigentlich eine 0x4 sein, aber du machst es richtig und kehrst von check_stack gar nicht erst zurück.)
Dieser Text wird unter jedem Beitrag angezeigt.

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 16. February 2013, 20:40 »
Hm... Das war natürlich ein blöder Fehler, am General Protection Fault ändert das aber trotzdem nichts. Die Adresse auf dem Stack ist einfach totaler Unsinn. Hast du noch eine Idee, wo der  Fehler liegt?
« Letzte Änderung: 17. February 2013, 00:09 von üäpöol »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 16. February 2013, 20:47 »
Ich traue deiner itoa-Funktion nicht, weil die eine 16 als Parameter hat, aber nur dezimale Ziffern ausgibt.
Dieser Text wird unter jedem Beitrag angezeigt.

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 17. February 2013, 00:08 »
Ich hab's mir nochmal mit der Basis 10 angeschaut und ausgerechnet. Die Werte stimmen.
Hier die Ausgabe mit mov esp, eax.
Ich häng auch meinen schönen Bluescreen an. :D
Besonders komisch ist, dass esp 0x202 sein soll.
Was ist nur mit diesem Stack los?
An der Adresse 0x10152d ist übrigens das iret.
« Letzte Änderung: 17. February 2013, 00:11 von üäpöol »

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 17. February 2013, 00:55 »
Ich habe in der Funktion SwitchTask mal das add esp, 0x8 weggelassen und jetzt wird zumindest schon mal in die main Funktion gesprungen. Das heißt, kein (!) General Protection Fault. :D
Warum nicht in die Funktion task_a gesprungen wird, weiß ich aber immer noch nicht.

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 17. February 2013, 02:02 »
Okay, ich hab noch ein paar Fehler im Code gefunden.
Das sieht jetzt schon besser aus, aber ganz stimmt der Stack noch nicht.
0x10010B ist die richtige Adresse, an die gesprungen werden soll.
Im Moment bekomme ich natürlich wieder einen General Protection Fault, aber man kann die richtige Adresse schon sehen. :)
Ich hab versucht das pop eax etc. wegzulassen und am Stack mit add esp, 0x4 und sogar sub esp, 0x4 zu arbeiten, aber bisher hat das nicht funktioniert.
Aktueller Screenshot ist angehängt.

Ach ja.
Hier ist noch der dazugehörige Code:
SwitchTask:
    push ebp
    push edi
    push esi
    push edx
    push ecx
    push ebx
    push eax
 
    push esp
    call multitasking_scheduler
    mov esp, eax

mov al, 0x20
    out 0x20, al
 
    pop eax
    pop ebx
    pop ecx
    pop edx
    pop esi
    pop edi
    pop ebp

push esp
call show_stack
add esp, 0x4
hlt

    iret

Ich glaube, ich komme der Lösung langsam näher.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #28 am: 17. February 2013, 02:24 »
Die Beschriftung an deiner Ausgabe macht keinen Sinn. Die General Purpose Register (das sind eax, ebx, ecx, edx, esp, ebp, esi, edi) sind ja gar nicht mehr auf dem Stack. Du hast sie direkt vor der Ausgabe vom Stack genommen. Du kannst sie also nicht mehr ausgeben.

Das Problem ist, dass du in deiner struct cpu_state noch die Werte int_no und err_code hast. Du musst die entweder entfernen (und dann passt das struct nicht mehr zu den anderen Interrupts), oder du musst diese beiden Zeilen einfügen:

SwitchTask:
    sub esp, 8 ; <------------------------------------
    push ebp
    push edi
    push esi
    push edx
    push ecx
    push ebx
    push eax
 
    push esp
    call multitasking_scheduler
    mov esp, eax

mov al, 0x20
    out 0x20, al
 
    pop eax
    pop ebx
    pop ecx
    pop edx
    pop esi
    pop edi
    pop ebp

    add esp, 8 ; <-----------------------------------

push esp
call show_stack
add esp, 0x4
hlt

    iret

Dann ist EIP, CS, EFLAGS ganz oben auf dem Stack und IRET sollte funktionieren.
Dieser Text wird unter jedem Beitrag angezeigt.

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #29 am: 17. February 2013, 02:45 »
Wow! Jidder, du bist ein (und der einzige :D) Gott!
Vielen Dank! :)

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #30 am: 17. February 2013, 21:00 »
Ich hab mich jetzt mal an den Usermode versucht, was natürlich zu einem General Protection Fault führt. Diesmal aber nicht nach einem return, sondern ganz schlicht nach mov ax, 0x23 und mov ds, ax
Woran kann das schon wieder liegen?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #31 am: 18. February 2013, 13:14 »
Fehlt dir das Userspace-Datensegment in der GDT? Ist das Limit der GDT hoch genug?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #32 am: 18. February 2013, 14:37 »
struct GDTstruct GDT[6];
// ...
CreateGDT(0, 0, 0, 0, 0);
CreateGDT(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
CreateGDT(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
CreateGDT(3, 0, 0xFFFFFFFF, 0x9A | 0x60, 0xCF);
CreateGDT(4, 0, 0xFFFFFFFF, 0x92 | 0x60, 0xCF);
CreateGDT(5, (unsigned int) tss, sizeof(tss), 0x09 | 0x80 | 0x60, 0x0);
Das müsste so passen, oder?

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #33 am: 22. February 2013, 15:57 »
Ich weiß leider immer noch nicht, was das Problem ist. Hat noch jemand eine Idee?

 

Einloggen