Autor Thema: Timer Interrupt  (Gelesen 14507 mal)

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« am: 26. September 2005, 17:50 »
Hallo

Ich komme bei meinem eigenem OS nicht mehr weiter. Nachdem ich schon in den PM gewechselt habe, habe ich eine Interrupt Tabelle eingerichtet, und will nun den Timer Interrupt benutzten. Ich leite zuerst die Hardware-Interrupts um und schalte dann die Interrupts ein. Ich habe für den Timer Interrupt einen (bis jetzt noch leeren Handler eingerichtet) welchen ich mit "iretd" beeende.

Wenn ich nun das ganze im Bochs teste, dann blinkt der Bildschirm. Wenn ich das ganze auf eiener Boot-Diskette speichere und 1 zu 1 ausprobiere, dann schaltet sich der Computer immer wieder aus beziehungsweise er startet neu.

Vielen Dank im Vorraus
Dominik

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 26. September 2005, 17:53 »
Was macht denn iretd?
Versuch mal normales iret zu benutzen.

Wenn du die Interrupts auslässt passiert garnichts? Bist du dir sicher, dass der  Handler richtig in der IDT steht?

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 26. September 2005, 19:47 »
Also das Problem besteht immer noch, auch wenn ich "iret" ohne "d" nehmen.

Ich habe mal für alle Interrupts den selben Handler genommen, da bestand das Problem weiterhin. Nachdem der Bildschirm bei Bochs etwa 20 mal geblinkt hatte, meldete Bochs "Too many registred timers".

Vieleicht hilft das.

Dominik

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 26. September 2005, 19:51 »
Du musst zum PIC noch ein EOI Signal senden, das kann aber eigentlich nicht für den Problem ausschlaggebend sein.

Zu deinem Problem fällt mir sonst nichts ein, ich kann mir nur vorstellen, das irgentwas in der IDT nicht stimmt.

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #4 am: 26. September 2005, 20:08 »
Naja wenn kein EOI kommt merkt sich der PIC noch ein paar Anfragen und irgendwann ist auch der voll, ka wie er darauf reagiert.
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 27. September 2005, 18:23 »
Das Problem besteht wieterhin. Mein EOI Singnal sieht so aus:
                   mov al,20h
                    out 20h,al


Mein Eintrag in der IDT so:
                   dw II, 8, 8E00h, 0

Dabei habe ich ein Label names II das den EOI beinhaltet und mit iret beendet wird.

Vielen Dank
Dominik

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 27. October 2005, 12:31 »
Hat wirklich keiner ne Ahnung, woran das liegen könnte. Ich komm nicht mehr weiter.

WhiteDragon

  • Beiträge: 124
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 27. October 2005, 18:03 »
Steht denn im GDT-Eintrag auch das korrekte Segment, in dem der Interrupt-Code liegt?

Außerdem: Schreib mal dies hier hin:

       mov     al, 20h
        out     0a0h, al
        out     20h, al


Ist wahrscheinlich nicht die Lösung, aber probier mal...

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #8 am: 27. October 2005, 18:24 »
Zitat von: WhiteDragon

Außerdem: Schreib mal dies hier hin:

       mov     al, 20h
        out     0a0h, al
        out     20h, al


Ist wahrscheinlich nicht die Lösung, aber probier mal...
Dies muss gemacht werden wenn der IRQ sich im slave PIC befindet. Aber der timer befindet sich im master deswegen genügt das mov al,20h out 20h,al.
In the Future everyone will need OS-64!!!

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 27. October 2005, 18:50 »
Also eben das komische an der ganzen Sache ist dass Bochs abstürzt(blinkt) und nach ca. 40 Sekuden die Meldung ausgiebt "to many registred timers" aber wenn ich das ganze mit dem Debugger anschaue durchläuft Bochs brav meine Endlosschleife.

WhiteDragon

  • Beiträge: 124
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 27. October 2005, 21:52 »
Zitat von: WhiteDragon
Steht denn im GDT-Eintrag auch das korrekte Segment, in dem der Interrupt-Code liegt?


Was ist mit meiner Frage? Hilft dir das weiter?

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 28. October 2005, 06:24 »
Ja also ich habe nur einen GDT Eintrag, dieser ist für den ganzen Code und die Interrupts.

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 28. October 2005, 11:01 »
Du brauchst doch mindestens 3 Einträge, einen Nulldescriptor, einen Code und einen Data Descriptor.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 28. October 2005, 12:12 »
Ja eben, ich hab diese drei, und der Code-Deskriptor ist für den ganzen Code inklusive Interrupts, er muss also fast funktionieren. Ich hab ihn für den ganzen 4 GB Adressrau eingestell.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 30. October 2005, 16:45 »
Hallo zusammen.

Ich hab jetzt alle Möglichkeiten (zu Fehlern), die ich im Forum gefunden habe, getestet und den Kernel 100 Mal nach Fehlern abgesucht. Dabei sind aber dennoch zwei Fragen aufgetaucht.

1.) Wo soll ich den Stack am besten hintun ? Jetzt hab ich ihn bei 0x2FFFF. Wobei mein Kernel bei 0x10000 ist.
2.) Wenn ich mein OS in Bochs laufen lasse, erscheint diese Meldung:"exeption(): 3rd (13) exeption with no resolution shutdown status is 00h, resetting" Danach startet Bochs mein Os neu und kaum eine Sekunde später geschiet das ganze wieder von Vorne. Nachdem das dann ca. 30 Mal passiert ist, schreibt Bochs:"Too many registred timers. Press Enter...." Wo liegt der Fehler für diese Exeption ???

Hier nochmals den neuen Code:[BITS 16]
;16 Bit Code erstellen
jmp start ;GDT überspringen

NULL_Desc:
dd 0
dd 0

CODE_Desc:
dw 0xFFFF ;Segmentgröße Byte 0/1
dw 0 ;Segmentbasisadresse Byte 0/1
db 0 ;Segmentbasisadresse Byte 2
db 10011010b ;Zugriffsberechtigungen
db 11001111b ;Zusatz + Segmentgröße Bits 16 - 19
db 0 ;Segmentbasisadresse Byte 3

DATA_Desc:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0

gdt:
Limit dw 0 ;Größe der GDT (wird später eingetragen)
Base dd 0


start_of_idt:
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0

dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0

dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0

dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0
dw PMODE4, 8, 8E00h, 0

; Hardware Interrupts
dw PMODE5, 8, 8E00h, 0

end_of_idt:


start:

cli
;Interrupts ausschalten

mov eax, cs ;EAX auf derzeitiges Codesegment setzen
mov ds, eax ;DS auf Codesegment setzen

shl ax, 4 ;EAX mit 16 multiplizieren (Lineare Adresse des Codesegments errechnen)
mov [CODE_Desc+2], eax ;Lineare Adresse des Codesegmentes als Startadresse des Code- und Datendeskriptors eintragen
mov [DATA_Desc+2], eax
shr eax, 16
mov [CODE_Desc+4], al
mov [DATA_Desc+4], al

mov eax, cs ;Startadresse der GDT errechnen
shl eax, 4
add eax, NULL_Desc

mov [Base], eax ;Startadresse der GDT eintragen
mov [Limit], WORD gdt - NULL_Desc -1 ;Größe der GDT errechnen und eintragen

lgdt [gdt] ;GDT laden

mov eax, cr0 ;In den Protected Mode schalten, indem Bit 0 des CR0 Registers auf 1 gesetzt wird
or eax, 1
mov cr0, eax

db 0xea ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8


[BITS 32] ;32 Bit Code erstellen

PMODE:

mov WORD [CODE_Desc+2], 0 ;Code Segmentstartaddresse auf 0 setzen
mov WORD [DATA_Desc+2], 0 ;Daten Segmentstartadresse auf 0 setzen
mov BYTE [CODE_Desc+4], 0 ;Code Segmentstartaddresse auf 0 setzen
mov BYTE [DATA_Desc+4], 0 ;Daten Segmentstartadresse auf 0 setzen

mov eax, 2 ;Selektor für das Datensegment erstellen
shl eax, 3

mov ds, ax ;Daten- Stack- und Extrasegment mit Datensegmentdeskriptor laden
mov ss, ax
mov es, ax
mov eax, 0 ;FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax
mov esp, 0x2FFFFF ;Stack setzen

idt_pointer:
dw end_of_idt - start_of_idt - 1
dd start_of_idt
lidt [idt_pointer]


; Neuinit der Interrupt-Controller, sowie neu Setzen des Interrupt Mappings
mov al,00010001b     ; kaskadierte Interrupt-Controller und Flankentriggerung an beider Controller
out 020h,al        
out 0a0h,al

; neuer IRQ-Vektor für den ersten Controller einstellen neuer Wert => IRQ0..7 -> INT20h..27h
mov al,20h        
out 021h,al

; neuer IRQ-Vektor für den zweiten Controller einstellen neuer Wert => IRQ8..15 -> INT28h..2Fh
mov al,28h          
out 0a1h,al

; Kaskadierung beider Controller einstellen
mov al,00000100b     ; Kaskadierung über IRQ2
out 021h,al
mov al,00000010b     ; Kaskadierung über IRQ2
out 0a1h,al

; PIC auf Intel-Umgebung und manuelle Int.- Beendigung einstellen
mov al,00000001b
out 021h,al
out 0a1h,al


sti

PMODE2:
jmp 0x8:0x10000 + PMODE2 ;Endlosschleife

PMODE4:
pusha
push gs
push fs
push ds
push es


pop es
pop ds
pop fs
pop gs
popa
iret


 
PMODE5:
pusha
push gs
push fs
push ds
push es
mov al,20h
out 20h,al
pop es
pop ds
pop fs
pop gs
popa
iret



jmp 0x8:0x10000 + PMODE2


Vielen Dank im Vorraus
Nooooooooooos

ena

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 15. November 2005, 11:03 »
Ja, diesen fehler bekomme ich auch bei bochs, vorher kommt allerdings auch noch ein jump_protected: descriptor not executable. Ich weiss nicht woran das liegen kann, ich hab doch alle interrupts ausgeschaltet, zumindest die maskierbaren, bei teejay im pmode tutorial funzt das ja auch ohne idt.
Den source gibts unter http://cibass.de.

mfg ena

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #16 am: 15. November 2005, 14:49 »
Also ich habe einen Fehler in deinem Code gefunden. Ob es jetzt der ist, der dafür verandfortlich ist kann ich nicht sagen. Ich weis halt nur das es ein Fehler ist. Hier ist der Fehler:

mov      esp, 0x2FFFFF               ;Stack setzen

idt_pointer:
   dw end_of_idt - start_of_idt - 1
   dd start_of_idt
   lidt [idt_pointer]


Du kannst doch nicht Daten als Code ausführen. Das musst du so machen:

mov      esp, 0x2FFFFF               ;Stack setzen
jmp dummy
idt_pointer:
   dw end_of_idt - start_of_idt - 1
   dd start_of_idt
dummy:
   lidt [idt_pointer]


Also musst du einfach die Daten von dem IDT-Register überspringen. Hoffe mal das danach alles klappt.
In the Future everyone will need OS-64!!!

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 15. November 2005, 17:09 »
Danke, aber ich habe das Problem mittlerweile gelöst. Es bestand ein Problem mit dem PM-Jump.

Gruss
Noooooooooos

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 17. November 2005, 12:14 »
Ich würde sagen eher IDT-Tutorial. Was ist der unterschied zwischen Timer-Interupt und sonst einem Interrupt ????

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 17. November 2005, 19:54 »
nooooooooos meinte wohl eher, das sich der Timer Interrupt genauso behandeln lässt wie alle anderen, deshalb wäre ein Tutorial über die IDT oder Interrupts insgesammt sinnvoller.

 

Einloggen