Autor Thema: Qemu = ok, echt Hardware = Auaa... ;(  (Gelesen 50296 mal)

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 01. February 2014, 22:33 »
ok, ist bearbeitet. Fehler bleibt.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 02. February 2014, 01:25 »
Dann heißt es weitersuchen. Wenn der Kernel hängt, kannst du Qemu nach EIP fragen, um zu erfahren, wo genau er hängt. Da sollte sich eine Endlosschleife befinden, möglicherweise ausgeführt als Denkfehler.

Debug-Ausgaben sind sehr hilfreich. Je nachdem, wie aussagekräftig dein Exception-Handler ist, kannst es nützlich sein, den #NM-Handler zu missbrauchen. Einen NMI kann man in der Qemu-Konsole auslösen. Da Paging ebenfalls ein regelmäßig wiederkehrender unerschöpflicher Quell der Freude ist, solltest du deinem VMM-Code viel Aufmerksamkeit widmen und dessen Ergebnisse mit "info mem" und "info tlb" auf Korrektheit prüfen.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 02. February 2014, 18:52 »
Dann heißt es weitersuchen. Wenn der Kernel hängt, kannst du Qemu nach EIP fragen, um zu erfahren, wo genau er hängt. Da sollte sich eine Endlosschleife befinden, möglicherweise ausgeführt als Denkfehler.

Debug-Ausgaben sind sehr hilfreich. Je nachdem, wie aussagekräftig dein Exception-Handler ist, kannst es nützlich sein, den #NM-Handler zu missbrauchen. Einen NMI kann man in der Qemu-Konsole auslösen. Da Paging ebenfalls ein regelmäßig wiederkehrender unerschöpflicher Quell der Freude ist, solltest du deinem VMM-Code viel Aufmerksamkeit widmen und dessen Ergebnisse mit "info mem" und "info tlb" auf Korrektheit prüfen.

Wie kann ich Qemu nach EIP fragen?
Debug-Ausgabe habe ich mit kprintf(); gemacht und dabei ist mir aufgefallen, dass er bei dem zuvor geposteten Codeabschnitt hängt. Exeption wird von Qemu nicht ausgelöst. Bei richtiger Hardware kommt es wohl zum Triple Fault und somit kann keine Exeption ausgelesen werden!
Um das Paging brauch ich mich im Moment auch nicht zu kümmern, da Paging noch nicht aktiv ist, wenn Qemu einfach so stehen bleibt ohne weitere Aktion. Wenn ich into mem oder tlb abrufe sagt mir Qemu nur, das PG noch nicht aktiv ist.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 02. February 2014, 19:04 »
Wie kann ich Qemu nach EIP fragen?
"info registers".

Debug-Ausgabe habe ich mit kprintf(); gemacht und dabei ist mir aufgefallen, dass er bei dem zuvor geposteten Codeabschnitt hängt.
Und wo genau?

Exeption wird von Qemu nicht ausgelöst.
Mit "nmi" schon.

Bei richtiger Hardware kommt es wohl zum Triple Fault und somit kann keine Exeption ausgelesen werden!
Das ist schlecht. Wobei ich bezweifle, dass dir Debugging auf der realen Hardware weiterhelfen würde.

Um das Paging brauch ich mich im Moment auch nicht zu kümmern, da Paging noch nicht aktiv ist, wenn Qemu einfach so stehen bleibt ohne weitere Aktion.
Das war mir nicht klar, ist aber dennoch ein gut gemeinter Rat für später. :-)

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 05. February 2014, 17:17 »
Also laut Qemu
hat EIP=0000fff0
EDX=00000633
alles andere 0!

CR0=60000010 falls das weiter hilft.

Wie bringen mich diese Register weiter? Wie kann ich nach EIP suchen?

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 05. February 2014, 17:44 »
Die Adresse 0xfff0 sieht verdächtig nach des BIOS-Startadresse aus. Und CR0 verrät dir auch das du dich gerade nicht im Protected Mode befindest.

Sieht also so aus als hätte es auch unter QEMU einen Tripplefault gegeben, nur eben ohne Reboot.

Lass mal alle Interrupts mitloggen qemu -d int und guck was da so für Exceptions auftreten.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 05. February 2014, 18:19 »

SMM: enter
EAX=00000001 EBX=00000000 ECX=02000000 EDX=00000cfc
ESI=000f39fd EDI=0003802d EBP=0000000b ESP=00006ef0
EIP=000f409b EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fd3a8 00000037
IDT=     000fd3e6 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=000f39d0 CCD=00000001 CCO=LOGICB 
EFER=0000000000000000
SMM: after RSM
EAX=00000001 EBX=00000000 ECX=02000000 EDX=00000cfc
ESI=000f39fd EDI=0003802d EBP=0000000b ESP=00006ef0
EIP=000f409b EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fd3a8 00000037
IDT=     000fd3e6 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=ffffff9c CCO=EFLAGS 
EFER=0000000000000000
     0: v=21 e=0000 i=0 cpl=0 IP=0008:001016c3 pc=001016c3 SP=0010:00109f3c EAX=000000ed
EAX=000000ed EBX=00000002 ECX=00000000 EDX=00000060
ESI=00000014 EDI=00000017 EBP=00109f54 ESP=00109f3c
EIP=001016c3 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=00000000 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=00109f2c CCO=SUBL   
EFER=0000000000000000
     1: v=21 e=0000 i=0 cpl=0 IP=0008:0010170f pc=0010170f SP=0010:00109f5c EAX=00000000
EAX=00000000 EBX=00000002 ECX=00000000 EDX=00000060
ESI=00000014 EDI=00000017 EBP=00109f74 ESP=00109f5c
EIP=0010170f EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=00000000 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=00109f4c CCO=SUBL   
EFER=0000000000000000
     2: v=21 e=0000 i=0 cpl=0 IP=0008:001016c3 pc=001016c3 SP=0010:00109f3c EAX=000000f3
EAX=000000f3 EBX=00000002 ECX=00000000 EDX=00000060
ESI=00000014 EDI=00000017 EBP=00109f54 ESP=00109f3c
EIP=001016c3 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=00000000 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=00109f2c CCO=SUBL   
EFER=0000000000000000
     3: v=21 e=0000 i=0 cpl=0 IP=0008:0010172f pc=0010172f SP=0010:00109f5c EAX=00000000
EAX=00000000 EBX=00000002 ECX=00000000 EDX=00000060
ESI=00000014 EDI=00000017 EBP=00109f74 ESP=00109f5c
EIP=0010172f EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=00000000 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=00109f4c CCO=SUBL   
EFER=0000000000000000
     4: v=21 e=0000 i=0 cpl=0 IP=0008:001016c3 pc=001016c3 SP=0010:00109f3c EAX=000000f4
EAX=000000f4 EBX=00000002 ECX=00000000 EDX=00000060
ESI=00000014 EDI=00000017 EBP=00109f54 ESP=00109f3c
EIP=001016c3 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=00000000 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=00109f2c CCO=SUBL   
EFER=0000000000000000
     5: v=20 e=0000 i=0 cpl=0 IP=0008:00101c10 pc=00101c10 SP=0010:00109f40 EAX=00000000
EAX=00000000 EBX=00000002 ECX=0000055e EDX=000b84be
ESI=00000014 EDI=00000017 EBP=00109f54 ESP=00109f40
EIP=00101c10 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=00000000 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000085 CCD=fffff5c0 CCO=EFLAGS 
EFER=0000000000000000
check_exception old: 0xffffffff new 0xe
     6: v=0e e=0000 i=0 cpl=0 IP=0008:00102c17 pc=00102c17 SP=0010:f000ff53 CR2=f000ff53
EAX=f0000023 EBX=00000002 ECX=0000055e EDX=00000020
ESI=00000014 EDI=00000017 EBP=00109f54 ESP=f000ff53
EIP=00102c17 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=f000ff53 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000024 CCD=00109f00 CCO=ADDL   
EFER=0000000000000000
check_exception old: 0xe new 0xe
     7: v=08 e=0000 i=0 cpl=0 IP=0008:00102c17 pc=00102c17 SP=0010:f000ff53 EAX=f0000023
EAX=f0000023 EBX=00000002 ECX=0000055e EDX=00000020
ESI=00000014 EDI=00000017 EBP=00109f54 ESP=f000ff53
EIP=00102c17 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=f000ff4f CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000024 CCD=00109f00 CCO=ADDL   
EFER=0000000000000000
check_exception old: 0x8 new 0xe

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 05. February 2014, 20:42 »
Wenn du dir das Log mal anschaust, fällt dir sicherlich auf, dass sich die Blöcke darin immer wiederholen. Ein Block beginnt mit eine oder zwei Zeilen, die ein paar Informationen über den Interrupt liefert, und dann mehrere Zeilen Registerdump. Die ersten beiden Interrupts (SMM: enter und SMM: after RSM) treten in qemu immer auf, und haben nichts mit deinem OS zu tun. Der darauf folgende Interrupt ist interessant. Der Dump fängt mit der Zeile "0: v=21 ..." an. Das heißt, dass Interrupt 21h (vermutlich IRQ 1 = Keyboard) ausgelöst wurde. Die drei darauffolgenden Interrupts kommen ebenfalls vom Keyboard Controller. Danach kommt ein Abschnitt, der mit "5: v=20 ..." anfängt, das heißt, dass ein Timer-Interrupt ausgelöst wird.

Die erste Frage, die du dir also stellen sollest: Warum treten Interrupts auf, bevor die Speicherverwaltung initialisiert ist, oder genauer warum aktivierst du Interrupts bevor die Speicherverwaltung initialisiert ist? Wenn du das nicht tust (und dir sicher bist, dass du das auch nicht ausversehen tust), wie konnte es dann kommen, dass du das Problem in pmm_init vermutet hast, wo doch das System offensichtlich danach weiterläuft?

Weiter mit dem Log:
Zitat
check_exception old: 0xffffffff new 0xe
     6: v=0e e=0000 i=0 cpl=0 IP=0008:00102c17 pc=00102c17 SP=0010:f000ff53 CR2=f000ff53
Das ist ein Page Fault. Die treten nur auf, wenn Paging aktiv ist. Wie kann das denn passieren, wo du doch oben gesagt hast, dass du kein Paging aktiviert hast?

Die Ursache für den Page Fault ist übrigens, dass ESP auf f000ff53 gesetzt wurde. Das ist ein Wert der in der IVT steht, welche sich an Adresse 0 befindet. Meine Vermutung ist, dass du Multitasking-Code hast, der einen NULL-Pointer derefenziert. Der Wert EIP=00102c17 kann dir bei der Suche helfen, indem du den Kernel disassemblierst (objdump -x kernel), und nach der Adresse 102c17 in der Ausgabe suchst. Dann solltest du herausfinden, in welcher Funktion sich dein Kernel befunden hat, als das aufgetreten ist.
Dieser Text wird unter jedem Beitrag angezeigt.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #28 am: 05. February 2014, 22:20 »
Der darauf folgende Interrupt ist interessant. Der Dump fängt mit der Zeile "0: v=21 ..." an. Das heißt, dass Interrupt 21h (vermutlich IRQ 1 = Keyboard) ausgelöst wurde. Die drei darauffolgenden Interrupts kommen ebenfalls vom Keyboard Controller. Danach kommt ein Abschnitt, der mit "5: v=20 ..." anfängt, das heißt, dass ein Timer-Interrupt ausgelöst wird.

Wieso IRQ 0 und 1 an dieser Stelle ausgelöst werden verstehe ich allerdings auch nicht. Interessant ist, dass pmm_init() bei mehreren Tests durchgelaufen ist aber der Kernel trotzdem nach Beendigung stehen bleibt. An dieser Stelle ist aber noch kein Inerrupt aktiviert worden und Qemu sagt mir weiter, das  PG nicht aktiv ist.

Zitat
Die erste Frage, die du dir also stellen sollest: Warum treten Interrupts auf, bevor die Speicherverwaltung initialisiert ist, oder genauer warum aktivierst du Interrupts bevor die Speicherverwaltung initialisiert ist? Wenn du das nicht tust (und dir sicher bist, dass du das auch nicht ausversehen tust), wie konnte es dann kommen, dass du das Problem in pmm_init vermutet hast, wo doch das System offensichtlich danach weiterläuft?
Diese Frage habe ich mir gestellt und ehrlich gesagt weiß ich nicht wieso diese Fehler auftretten, wenn der Kernel gar nicht weiter läuft und Qemu einfach stehem bleibt.

Zitat
check_exception old: 0xffffffff new 0xe
     6: v=0e e=0000 i=0 cpl=0 IP=0008:00102c17 pc=00102c17 SP=0010:f000ff53 CR2=f000ff53
Das ist ein Page Fault. Die treten nur auf, wenn Paging aktiv ist. Wie kann das denn passieren, wo du doch oben gesagt hast, dass du kein Paging aktiviert hast?
[/quote]
Laut Qemu ist kein Paging aktiv!

Zitat
Die Ursache für den Page Fault ist übrigens, dass ESP auf f000ff53 gesetzt wurde. Das ist ein Wert der in der IVT steht, welche sich an Adresse 0 befindet. Meine Vermutung ist, dass du Multitasking-Code hast, der einen NULL-Pointer derefenziert. Der Wert EIP=00102c17 kann dir bei der Suche helfen, indem du den Kernel disassemblierst (objdump -x kernel), und nach der Adresse 102c17 in der Ausgabe suchst. Dann solltest du herausfinden, in welcher Funktion sich dein Kernel befunden hat, als das aufgetreten ist.
Adresse 102c17 gibt es nicht, wenn ich alles richtig gemacht habe:
objdump -x kernel > kernel.txt
...danach in kernel.txt nach 102c17 gesucht => kein Treffer!

Aber hier mal am Rande die Frage: Wenn jemand das Tutorial ohne weiteres compiliert hat, hätte ihm doch den selbe Fehler auffallen müssen. Wieso funktioniert das bei mir nur nicht? Oder hat ihn bis her niemand auf echter Hardware probiert?!
Seltsam....

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #29 am: 05. February 2014, 22:36 »
Aber hier mal am Rande die Frage: Wenn jemand das Tutorial ohne weiteres compiliert hat, hätte ihm doch den selbe Fehler auffallen müssen. Wieso funktioniert das bei mir nur nicht? Oder hat ihn bis her niemand auf echter Hardware probiert?!
Seltsam....
Das Tutorial liefert ja nicht den vollständigen Code, sondern es lässt viele Sachen offen, die der Leser implementieren muss. Da kann einiges schief gehen.

Wenn Interrupts auftreten, obwohl du glaubst, dass Interrupts deaktiviert sind, wenn Page Faults auftreten, obwohl du glaubst, dass Paging deaktiviert ist, und wenn du Code im disassemblierten Kernel nicht findest, dann läuft irgendwas grundlegendes falsch. Ohne Code kann ich dir da nicht weiterhelfen. Wenn du willst, kannst du das irgendwo hochladen (z.B. in ein GIT-Repository), dann werde ich mir das mal anschauen.
Dieser Text wird unter jedem Beitrag angezeigt.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #30 am: 05. February 2014, 23:09 »
Laut Qemu ist kein Paging aktiv!
Laut log ist Paging schon vor dem ersten IRQ aktiv.  (Siehe CR0)
Dass dir Qemu sagt es wäre nicht aktiv, liegt  vermutlich daran, dass du das erst dann abfragst wenn Qemu wegen des Tripplefaults schon wieder rettetet wurde.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #31 am: 05. February 2014, 23:25 »
Laut Qemu ist kein Paging aktiv!
Laut log ist Paging schon vor dem ersten IRQ aktiv.  (Siehe CR0)
Dass dir Qemu sagt es wäre nicht aktiv, liegt  vermutlich daran, dass du das erst dann abfragst wenn Qemu wegen des Tripplefaults schon wieder rettetet wurde.
Das würde Sinn machen. Aber wie kann ich jetzt im info mem oder info tlb Daten auslesen, wenn Qemu schon reset hat? Kann ich den Rest irgendwie ausschalten?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #32 am: 05. February 2014, 23:58 »
qemu -no-reboot -no-shutdown ...
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #33 am: 06. February 2014, 12:37 »
Hat geklappt!
info mem gibt folgendes aus:
Zitat
00000000-00800000 00800000 urw

info tlb kann ich leider nicht komplett auslesen.

info registers:
Zitat
EAX=f0000023 EBX=00000002 ECX=0010ee00 EDX=00000020
ESI=00000014 EDI=00000011 EBP=00109ff4 ESP=f000ff53
EIP=00102c17 EFL=00000002
...
GDT= 0012a060 0000002f
IDT= 0012a0a0 999997ff

CR0=80000011 CR2=f000ff4f CR3=00001000 CR4-DR0-DR3=00000000
DR6=ffff0ff0 DR7=00000400
...

Dazu Qemu INT-Log:
Zitat
     0: v=20 e=0000 i=0 cpl=0 IP=0008:00103b28 pc=00103b28 SP=0010:00109fa8 EAX=00000030
EAX=00000030 EBX=00000002 ECX=0010ee00 EDX=00082bf2
ESI=00000014 EDI=00000011 EBP=00109ff4 ESP=00109fa8
EIP=00103b28 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=00000000 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000034 CCD=00109f68 CCO=ADDL   
EFER=0000000000000000
check_exception old: 0xffffffff new 0xe
     1: v=0e e=0000 i=0 cpl=0 IP=0008:00102c17 pc=00102c17 SP=0010:f000ff53 CR2=f000ff53
EAX=f0000023 EBX=00000002 ECX=0010ee00 EDX=00000020
ESI=00000014 EDI=00000011 EBP=00109ff4 ESP=f000ff53
EIP=00102c17 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=f000ff53 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000024 CCD=00109f68 CCO=ADDL   
EFER=0000000000000000
check_exception old: 0xe new 0xe
     2: v=08 e=0000 i=0 cpl=0 IP=0008:00102c17 pc=00102c17 SP=0010:f000ff53 EAX=f0000023
EAX=f0000023 EBX=00000002 ECX=0010ee00 EDX=00000020
ESI=00000014 EDI=00000011 EBP=00109ff4 ESP=f000ff53
EIP=00102c17 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00105180 00000080 0000e900 DPL=3 TSS32-avl
GDT=     0012a060 0000002f
IDT=     0012a0a0 000007ff
CR0=80000011 CR2=f000ff4f CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000024 CCD=00109f68 CCO=ADDL   
EFER=0000000000000000
check_exception old: 0x8 new 0xe


Das sind alles aktuelle Daten, die Qemu beim Stopp liefert.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #34 am: 06. February 2014, 13:03 »
Ich habe nochmal mit objdump -dS kernel >kernel.txt disasm. & da finde ich Adresse 102c17 in 00102bf8 <intr_common_handler>:
Zitat
00102bf8 <intr_common_handler>:
  102bf8:   55                      push   %ebp
  102bf9:   57                      push   %edi
  102bfa:   56                      push   %esi
  102bfb:   52                      push   %edx
  102bfc:   51                      push   %ecx
  102bfd:   53                      push   %ebx
  102bfe:   50                      push   %eax
  102bff:   66 b8 10 00             mov    $0x10,%ax
  102c03:   8e d8                   mov    %eax,%ds
  102c05:   8e c0                   mov    %eax,%es
  102c07:   54                      push   %esp
  102c08:   e8 56 11 00 00          call   103d63 <handle_interrupt>
  102c0d:   89 c4                   mov    %eax,%esp
  102c0f:   66 b8 23 00             mov    $0x23,%ax
  102c13:   8e d8                   mov    %eax,%ds
  102c15:   8e c0                   mov    %eax,%es
  102c17:   58                      pop    %eax
  102c18:   5b                      pop    %ebx
  102c19:   59                      pop    %ecx
  102c1a:   5a                      pop    %edx
  102c1b:   5e                      pop    %esi
  102c1c:   5f                      pop    %edi
  102c1d:   5d                      pop    %ebp
  102c1e:   83 c4 08                add    $0x8,%esp
  102c21:   cf                      iret   
   ...


wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #35 am: 06. February 2014, 13:22 »
int_stub.S:
...

intr_common_handler:
    // CPU-Zustand sichern
    push %ebp
    push %edi
    push %esi
    push %edx
    push %ecx
    push %ebx
    push %eax

    // Kernel-Datensegmente laden
    mov $0x10, %ax
    mov %ax, %ds
    mov %ax, %es

    // Handler aufrufen
    // Der Rueckgabewert ist der Prozessorzustand des moeglicherweise
    // gewechselten Tasks. Wir muessen also den Stack dorthin wechseln
    // um die Register wiederherzustellen.
    push %esp
    call handle_interrupt
    mov %eax, %esp

    // User-Datensegmente laden
    mov $0x23, %ax
    mov %ax, %ds
    mov %ax, %es

    // CPU-Zustand wiederherstellen
    pop %eax
    pop %ebx
    pop %ecx
    pop %edx
    pop %esi
    pop %edi
    pop %ebp

    // Fehlercode und Interruptnummer vom Stack nehmen
    add $8, %esp

    iret

Also bedeutet das doch, dass es bei pop %eax zum Fault kommt. Was sagt mir das jetzt?
« Letzte Änderung: 06. February 2014, 16:28 von wissenshunger »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #36 am: 06. February 2014, 17:16 »
Dass der Stack kaputt ist. Da der Rückgabewert von handle_interrupt nach %esp geladen wird, heißt das, dass handle_interrupt einen ungültigen Wert zurückliefert.
Dieser Text wird unter jedem Beitrag angezeigt.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #37 am: 07. February 2014, 01:43 »
Es muss also an der Funktion handle_interrupt liegen oder liegt es am Kernel Stack bzw. Am aktuellen Task Stack? Was heißt Stack kaputt?
« Letzte Änderung: 07. February 2014, 02:00 von wissenshunger »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #38 am: 07. February 2014, 03:18 »
Es muss also an der Funktion handle_interrupt liegen oder liegt es am Kernel Stack bzw. Am aktuellen Task Stack?
Ja handle_interrupt ist einer der Verdächtigen. Auch alles, das von handle_interrupt aufgerufen wird. Einer von denen sorgt dafür, dass der Kernel Stack falsch gesetzt wird indem das return-Statement in handle_interrupt etwas fehlerhaftes zurückgibt.

Was heißt Stack kaputt?
Im Allgemeinen heißt es, dass der Stack überschrieben wurde, es einen Stack Overflow gab oder der Stack Pointer einen fehlerhaften Wert hat.

In diesem Fall lässt sich aus dem "ESP=f000ff53" in den Logs von QEMU ablesen, dass der Stack Pointer einen fehlerhaften Wert hat. Es lässt sich sogar noch etwas mehr sagen, denn der Wert f000ff53 steht mehrfach in der IVT (die sich an Adresse 0 befindet). Das heißt die wahrscheinlichste Ursache ist eine Dereferenzierung eines NULL-Pointers und der fälschlich gelesene Wert wurde nach ESP geladen (über das return-Statement in handle_interrupt).
Dieser Text wird unter jedem Beitrag angezeigt.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #39 am: 07. February 2014, 14:56 »
struct cpu_state* handle_interrupt(struct cpu_state* cpu)
{

    struct cpu_state* new_cpu = cpu;

    if (cpu->intr <= 0x1f) {
    //  ... Exeptions

       while(1) {
            // Prozessor anhalten
            asm volatile("cli; hlt");
        }
    } else if (cpu->intr >= 0x20 && cpu->intr <= 0x2f) {
// ====> AB HIER HARDWARE INTERRUPTS <====
        if (cpu->intr == 0x20) {  //TIMER
// kprintf("!! TIMER !!\n");

// TIMER_ITR();
new_cpu = schedule(cpu);
// kprintf("!! SCHEDULE !!\n");
    tss[1] = (uint32_t) (new_cpu + 1);
           
        }

if (cpu->intr == 0x21) {  //Keyboard
interruptevent = 3;
keypress = kbd_read();
}

if (cpu->intr == 0x24) {  //SS0
interruptevent = 4;
}

if (cpu->intr == 0x26) {  //FDC
interruptevent = 6;
FLOPPY_IRQ();
}

        if (cpu->intr >= 0x28) {
            // EOI an Slave-PIC
            outb(0xa0, 0x20);
        }
        // EOI an Master-PIC
        outb(0x20, 0x20); // PIC zurueksetzen
       
        // =======================================
       
    } else if (cpu->intr == SYSCALL_INTERRUPT) {
        new_cpu = syscall(cpu);
    } else {
        kprintf("Unbekannter Interrupt\n");
        while(1) {
            // Prozessor anhalten
            asm volatile("cli; hlt");
        }
    }
   
    /*
    if (cpu != current_task->cpu_state) {
        asm volatile("mov %0, %%cr3" : : "r" (cpu->context));
    } */
   
    return new_cpu;
}

Da er bei echter Hardware immer nach dem Schedule abstürzt hier auch dieser Code:
struct cpu_state* schedule(struct cpu_state* cpu)
{

    /*
     * Wenn schon ein Task laeuft, Zustand sichern. Wenn nicht, springen wir
     * gerade zum ersten Mal in einen Task. Diesen Prozessorzustand brauchen
     * wir spaeter nicht wieder.
     */
    if (current_task != NULL) {
        current_task->cpu_state = cpu;
    }

    /*
     * Naechsten Task auswaehlen. Wenn alle durch sind, geht es von vorne los
     */
    if (current_task == NULL) {
        current_task = first_task;
    } else {
        current_task = current_task->next;
        if (current_task == NULL) {
            current_task = first_task;
        }
    }
   
/* Prozessorzustand des neuen Tasks aktivieren */
   
    cpu = current_task->cpu_state;
//   ###############################################################################
    return cpu;
}

Also ich kann kein Fehler sehen und das irgendwo NULL ausgegeben wird auch nicht.
Hier auch nochmal die intr.h:
#ifndef INTR_H
#define INTR_H

#include <stdint.h>
#include "multiboot.h"

struct cpu_state {
    // Von Hand gesicherte Register
    uint32_t   eax;
    uint32_t   ebx;
    uint32_t   ecx;
    uint32_t   edx;
    uint32_t   esi;
    uint32_t   edi;
    uint32_t   ebp;

    uint32_t   intr;
    uint32_t   error;

    // Von der CPU gesichert
    uint32_t   eip;
    uint32_t   cs;
    uint32_t   eflags;
    uint32_t   esp;
    uint32_t   ss;
};

void init_gdt(void);
void init_intr(void);
void init_multitasking(struct multiboot_info* mb_info);

struct cpu_state* handle_interrupt(struct cpu_state* cpu);
struct cpu_state* schedule(struct cpu_state* cpu);

#endif


 

Einloggen