Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: dietzi am 19. February 2017, 21:30
-
Hallo,
ich habe ein Problem mit dem Interrupt-Handling. Ich habe bis jetzt größten teils mit dem Tutorial gearbeitet. Wenn ich meinen Code in Bochs ausführe bekomme ich als Debug-Info "check_cs(0x0010): not a valid code segment !"
Hier mein Code (die betreffenden Zeilen)
Interrupts.S
.macro irq num, map
.global irq\num
irq\num:
cli
push $0
push $\map
jmp irq_stub
.endm
irq 0, 20
irq 1, 21
irq 2, 22
irq 3, 23
irq 4, 24
irq 5, 25
irq 6, 26
irq 7, 27
irq 8, 28
irq 9, 29
irq 10, 30
irq 11, 31
irq 12, 32
irq 13, 33
irq 14, 34
irq 15, 35
.extern handle_interrupt
irq_stub:
// 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
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
// Ruecksprung zum unterbrochenen Code
// xchg %bx, %bx
iret
isr.c
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;
};
struct cpu_state* handle_interrupt(struct cpu_state* cpu)
{
struct cpu_state* new_cpu = cpu;
if(cpu->intr == 0x21) {
keyboard_handler();
}
if (cpu->intr >= 0x20 && cpu->intr <= 0x2f) {
terminal_writestring("Resetting Master");
if (cpu->intr >= 0x28) {
terminal_writestring("Resetting Slave");
outb(SLAVE_COMMAND, PIC_RESET);
terminal_writestring("Slave resetted");
}
outb(MASTER_COMMAND, PIC_RESET);
terminal_writestring("Master resetted");
}
terminal_writestring("Returning CPU-State");
return new_cpu;
}
handle_interrupt() läuft genau 1 mal durch und wird danach nicht mehr aufgerufen....
Kann mir vielleicht jemand sagen wo der Fehler liegt?
LG Dietzi
-
Du solltest erst einmal versuchen, genauer einzugrenzen, wann der Fehler genau kommt. Aus der Fehlermeldung wird erst einmal nur klar, dass irgendwo versuchst wird, cs=0x10 zu setzen. Wenn du dich ans Tutorial gehalten hast, ist 0x10 ein Datensegment und deswegen tut das nicht; das Codesegment wäre 0x08.
Weil du sagst, dass handle_interrupt() einmal ausgeführt wird, tippe ich auf das iret als fehlschlagende Instruktion. bochs müsste in der Fehlermeldung auch die Adresse ausgeben, die du aber nicht mitkopiert hast. Die kannst du mal mit deiner Kernelbinary vergleichen, um rauszufinden, wo es genau passiert. Wenn es tatsächlich das iret ist, dann liegt ein falscher Wert auf dem Kernelstack und du musst rausfinden, wo er herkommt.
-
Hallo,
danke für die schnelle Antwort. Bochs zeigt mir keine Adresse an:
00086139136e[CPU0 ] check_cs(0x0010): not a valid code segment !
00086148001e[CPU0 ] check_cs(0x0010): not a valid code segment !
00086156866e[CPU0 ] check_cs(0x0010): not a valid code segment !
00086381397e[CPU0 ] check_cs(0x0010): not a valid code segment !
Ich verstehe auch nicht so ganz wie es hier zu diesem Fehler kommen kann, da ich genau den Status zurück gebe welchen ich bei Aufruf von handle_interrupt() erhalte. Was ich noch vergessen hatte zu erwähnen: es wird ein GP ausgelöst - evtl. hilft das der Lösungsfindung.....
LG Dietzi
-
Naja, wenn bochs es nicht anzeigt, musst du eben andere Möglichkeiten nehmen, um das zu debuggen. Zum Beispiel einen Breakpoint vor dem iret setzen und dort dann den Stack anschauen, ob der aussieht wie erwartet.
-
Nun folgende Ausgabe (Breakpoint zu start in irq_stub und direkt vor iret)
<bochs:3> sreg
es:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x0008, dh=0x00cf9b00, dl=0x0000ffff, valid=1
Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=31
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=31
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0028, dh=0x0000eb10, dl=0x32000080, valid=1
gdtr:base=0x000000000010b840, limit=0x2f
idtr:base=0x000000000010b8e0, limit=0x7ff
<bochs:4> c
00086139138i[CPU0 ] [86139138] Stopped on MAGIC BREAKPOINT
(0) Magic breakpoint
Next at t=86139138
(0) [0x00000010049b] 0008:000000000010049b (unk. ctxt): iret ; cf
<bochs:5> sreg
es:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x0008, dh=0x00cf9b00, dl=0x0000ffff, valid=1
Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=31
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0028, dh=0x0000eb10, dl=0x32000080, valid=1
gdtr:base=0x000000000010b840, limit=0x2f
idtr:base=0x000000000010b8e0, limit=0x7ff
<bochs:6> c
00086139138e[CPU0 ] check_cs(0x0010): not a valid code segment !
00086148003e[CPU0 ] check_cs(0x0010): not a valid code segment !
00086156868e[CPU0 ] check_cs(0x0010): not a valid code segment !
00086381399e[CPU0 ] check_cs(0x0010): not a valid code segment !
00086929429e[CPU0 ] check_cs(0x0010): not a valid code segment !
00087477459e[CPU0 ] check_cs(0x0010): not a valid code segment !
00088025489e[CPU0 ] check_cs(0x0010): not a valid code segment !
00088573519e[CPU0 ] check_cs(0x0010): not a valid code segment !
00089121549e[CPU0 ] check_cs(0x0010): not a valid code segment !
00089536436i[ ] Ctrl-C detected in signal handler.
Next at t=89536436
(0) [0x000000100f70] 0008:0000000000100f70 (unk. ctxt): add ebx, ebx ; 01db
<bochs:7> sreg
es:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x0008, dh=0x00cf9b00, dl=0x0000ffff, valid=1
Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=31
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=31
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0028, dh=0x0000eb10, dl=0x32000080, valid=1
gdtr:base=0x000000000010b840, limit=0x2f
idtr:base=0x000000000010b8e0, limit=0x7ff
Nachtrag:
<bochs:8> info gdt
Global Descriptor Table (base=0x000000000010b840, limit=47):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
GDT[0x03]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, 32-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
GDT[0x05]=32-Bit TSS (Busy) at 0x00103200, length 0x00080
-
Fehler gefunden...... tss war im header als static deklariert. Habe tss jetzt in der isr.c als "nicht-static" deklariert und in der gdt.h habe ich einen Verweis mittels extern auf tss gesetzt. Und schon geht alles wieder. Danke für deine Hilfe