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

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #40 am: 07. February 2014, 15:25 »
Wann tritt der Fehler auf?
  Nach dem ersten Timer interrupt. (Siehe Qemu Log)

Was gibt handle_interrupt in diesem Fall zurück?
  new_cpu = schedule(cpu);

Was gibt schedule(cpu) zurück?
  vermutlich: first_task->cpu_state;

Wie ist first_task initialisiert?
  Vermutlich ist hier der NULL-Pointer, der dereferenziert wird.

Falls das doch noch nicht der Fall war, kannst du auch mal versuchen die erste Page nicht zu Mappen. Dein Kernel wird die nicht brauchen. Dann knallt's gleich wenn du einen NULL-Pointer dereferenzierst.
„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 #41 am: 09. February 2014, 02:21 »
Nach Kontrolle von init_task und kleinen veränderungen tretten die letzten beiden Eceptions nach dem Timer IRQ bei folgenden Befehle im handle_interrupt auf:
push %ecx
Und
pop %ecx

Ich versteh einfach nicht wodran es liegt. Ich habe teilweise wieder orginal Code zum Tutorial wiederhergestellt und trotzem kommich vom Triple Fault nicht weg.
Langsam verzweifel ich.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #42 am: 09. February 2014, 21:53 »
Jetzt macht mein Kernel noch andere komische Sachen. -.-

Wie es scheint wird jetzt nach dem Timer IRQ eine #GP ausgelöst und danach eine #PF, dann gefolgt vom #DF [Qemu stopp]


Zitat
     1: v=20 e=0000 i=0 cpl=0 IP=0008:0010166f pc=0010166f SP=0010:00109f3c EAX=000000ed
EAX=000000ed EBX=00000002 ECX=00000000 EDX=00000060
ESI=00000014 EDI=00000020 EBP=00109f54 ESP=00109f3c
EIP=0010166f 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=00000010 CCD=00109f30 CCO=EFLAGS 
EFER=0000000000000000
check_exception old: 0xffffffff new 0xd
     2: v=0d e=0000 i=0 cpl=0 IP=0008:00102bcd pc=00102bcd SP=0010:00001024 EAX=00002027
EAX=00002027 EBX=00003007 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00001024
EIP=00102bcd 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=00000000 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=00001024 CCO=ADDL   
EFER=0000000000000000
check_exception old: 0xffffffff new 0xe
     3: v=0e e=0002 i=0 cpl=0 IP=0008:00102ba8 pc=00102ba8 SP=0010:00001000 CR2=00000ffc
EAX=00002027 EBX=00003007 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00001000
EIP=00102ba8 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=00000ffc CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=00001024 CCO=ADDL   
EFER=0000000000000000
check_exception old: 0xe new 0xe
     4: v=08 e=0000 i=0 cpl=0 IP=0008:00102ba8 pc=00102ba8 SP=0010:00001000 EAX=00002027
EAX=00002027 EBX=00003007 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00001000
EIP=00102ba8 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=00000ffc CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=00001024 CCO=ADDL   
EFER=0000000000000000
check_exception old: 0x8 new 0xe

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #43 am: 09. February 2014, 22:07 »
Also wenn die erste Page nicht mappe, spri. physisch = virtuell erst ab 4096KB, dann wird sofort eine #PF ausgelöst, log dazu:

Zitat
     0: v=0e e=0000 i=0 cpl=0 IP=0008:0010444a pc=0010444a SP=0010:00109f3c CR2=00000400
EAX=00000400 EBX=00000002 ECX=00000000 EDX=00000400
ESI=00000014 EDI=00000020 EBP=00109f50 ESP=00109f3c
EIP=0010444a 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=00000400 CR3=00001000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000400 CCD=00000400 CCO=ADDL   
EFER=0000000000000000


Das blöde dazu, wenn ich objdump mit den Option -dS speicher und durchsuche, finde ich Adresse 10444a nicht.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #44 am: 09. February 2014, 22:39 »
Liest du für irgend etwas die BIOS Data Area (BDA) aus? Die liegt nämlich genau bei 0x400.

Hast du denn irgend etwas in der nähe von 0x10444a, bzw. was liegt denn so davor und dahinter ?
Wenn du es nur grob wissen willst oder code weit weg ist kannst du auch mit 'nm <kernel>' nur die labels ausgeben lassen.
„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 #45 am: 09. February 2014, 22:46 »
Liest du für irgend etwas die BIOS Data Area (BDA) aus? Die liegt nämlich genau bei 0x400
Beim Starten lese ich die BDA aus um Daten zur seriellen Schnittstelle zu bekommen etc.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #46 am: 09. February 2014, 23:05 »
Mir kommt gerade eine Idee weil ich mich gefragt habe wieso Qemu doch manschmal weiter läuft.
Könnte der Fehler daran liegen, dass die Taskliste mit Null init. wird und wenn die Interrupts aktiviert werden der schedule dann null zurück gibt, dann noch kein Task in dieser Zeit aktiv ist bis das erste Mal Timer IRQ kommt? Interessanterweise ist nach änderung der Timerfrequenz an Problem mit Qemu schlimmer geworden! Das würde auch erklären wieso echte Hardware sofort resetet! Bei echter Hardware ist der Timer genUer oder er braucht länger den ersten Task zu init als der Timer und deswegen kommt es zu dieser geheimnisvollen Null, dass das ganze System zum absturz bringt.

OsDevNewbie

  • Beiträge: 281
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #47 am: 09. February 2014, 23:32 »
Also wenn der Scheduler dann NULL zurückgibt, dann ist das wohl die Ursache füf deine Fehler. Du solltest im Scheduler überprüfen, ob es überhaupt einen Task gibt, zu dem man wechseln kann. Ansonsten wird einfach der Task nicht gewechselt.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #48 am: 09. February 2014, 23:46 »
Meine Vermutung hat sich bewahrheitet!

Das Problem war die ganze Zeit, dass bei echter Hardware der Timer Interrupt früher auslöste als überhaupt der erste Task angelegt werden konnte! Bei Qemu mit Standart-Timerfrequenz hat es manschmal doch geklappt.

Bei folgendem Codeausschnitt vom Schedule:
    cpu = current_task->cpu_state;

    return cpu;
}

...habe ich einfach "if (current_task != NULL)" eingebaut:
    if (current_task != NULL)
    cpu = current_task->cpu_state;

    return cpu;
}

..und siehe da, dass PROBLEM ist behoben. Man man man was ein langer Weg für so wenig Code.
Wenn current_task = NULL ist wird der letzte CPU Stand einfach gelassen. Dieser Zustand kommt ja nur vor, wenn die Interrupts aktiviert werden und es noch wenige (m)sek. dauert bis der erste Task gestartet ist.

Bitte bitte ändert das mal jemand im Tutorial, damit dieser Fehler nicht bei irgendjemand sonst auftretten kann. Er ist überaus lästig!

Somit bedanke ich mich hiermit ganz herzlich bei jedem der sich hier mit den Kopf zerbrochen hat. Ich habe sehr viel über debugging gelernt und bin um einiges fitter in Sachen Register geworden. Vielen lieben Dank! Damit erkläre ich dieses Thema für erledigt und geschlossen! Danke!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #49 am: 10. February 2014, 11:13 »
Die Frage ist eher, warum der Scheduler so früh aufgerufen wird. Sollten eigentlich nicht Hardwareinterrupts deaktiviert sein, bis du alles fertig initialisiert hast?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

OsDevNewbie

  • Beiträge: 281
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #50 am: 10. February 2014, 15:31 »
Trotzdem ist es ein Fehler, denn nehmen wir mal an alle Task wurden beendet, dann gibt es immer einen Fault und das ist doch nicht schön.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #51 am: 10. February 2014, 17:01 »
Wenn alle Tasks beendet wurden, hast du sowieso ein größeres Problem, das deine Änderung auch nicht löst.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #52 am: 10. February 2014, 18:04 »
Wieso habe ich noch ein größeres Problem? Wie wäre es besser gelöst?

Svenska

  • Beiträge: 1 778
    • Profil anzeigen
Gespeichert
« Antwort #53 am: 10. February 2014, 18:11 »
Wer startet neue Tasks, wenn kein Task läuft?
Deine Idle-Schleife wird das eher nicht tun.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #54 am: 10. February 2014, 19:55 »
Die Idleschleife wäre auch schon ein Task.

Das Problem entsteht beim Beenden des letzten Tasks: Was ist denn dann der nächste Zustand, in den der Kernel springen sollte? Dein Scheduler wird mit deiner Änderung den Task nicht mehr wechseln, also macht der Kernel im gerade beendeten und freigegebenen Task weiter. Was das genau bedeutet, kannst du dir selber überlegen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #55 am: 11. February 2014, 00:42 »
Was ist, wenn ich einen Leerlauf Task erstelle der einfach nur eine Endlosschleife ist? Dieser Task nicht nicht beendbar.

Svenska

  • Beiträge: 1 778
    • Profil anzeigen
Gespeichert
« Antwort #56 am: 11. February 2014, 08:30 »
Linux kennt eine Funktion panic(), die den Kernel tötet. Wenn keine Tasks vorhanden sind, dann solltest du deinen Kernel töten. Dein Leerlauf-Task schützt den Kernel dann vor dem out-of-tasks-panic. :-)

In die Endlosschleife solltest du wenigstens ein __asm__ volatile("hlt") reinmachen, damit dein Qemu nicht 100% CPU-Leistung vom Host saugt, wenn in deinem System nichts zu tun ist. Wenn das nur eine Endlosschleife sein soll, dann solltest du die auch nur dann aufrufen, wenn es sonst keine lauffähigen Tasks gibt.

wissenshunger

  • Beiträge: 49
    • Profil anzeigen
Gespeichert
« Antwort #57 am: 14. February 2014, 02:18 »
Wie kann man den einen Kernel töten?

Dimension

  • Beiträge: 155
    • Profil anzeigen
Gespeichert
« Antwort #58 am: 14. February 2014, 08:17 »
Wie kann man den einen Kernel töten?
Mit der Kreissäge? Aus deiner Perspektive befindet sich der Kernel in der Matrix.

Jidder

  • Administrator
  • Beiträge: 1 623
    • Profil anzeigen
Gespeichert
« Antwort #59 am: 14. February 2014, 08:24 »
Wie kann man den einen Kernel töten?

Svenska meint damit eine Endlosschleife:
In die Endlosschleife solltest du wenigstens ein __asm__ volatile("hlt") reinmachen, damit dein Qemu nicht 100% CPU-Leistung vom Host saugt, wenn in deinem System nichts zu tun ist. Wenn das nur eine Endlosschleife sein soll, dann solltest du die auch nur dann aufrufen, wenn es sonst keine lauffähigen Tasks gibt.

Optional ist es den Bildschirm blau einzufärben und kryptische Stackdumps und Fehlercodes sowie irgendwas von wegen "Wenden Sie sich an den Administrator" anzuzeigen.
Dieser Text wird unter jedem Beitrag angezeigt.

 

Einloggen