ok, ist bearbeitet. Fehler bleibt.
09. November 2026, 18:31
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?"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.

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
check_exception old: 0xffffffff new 0xeDas 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?
6: v=0e e=0000 i=0 cpl=0 IP=0008:00102c17 pc=00102c17 SP=0010:f000ff53 CR2=f000ff53
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?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.
check_exception old: 0xffffffff new 0xeDas 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?
6: v=0e e=0000 i=0 cpl=0 IP=0008:00102c17 pc=00102c17 SP=0010:f000ff53 CR2=f000ff53
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:
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?!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.
Seltsam....
Laut Qemu ist kein Paging aktiv!Laut log ist Paging schon vor dem ersten IRQ aktiv. (Siehe CR0)
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?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.
00000000-00800000 00800000 urw
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
...
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
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
...
...
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
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.
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;
}
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;
}
#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