Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: kotzkroete am 31. May 2007, 15:39

Titel: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 31. May 2007, 15:39
Hallo,
ich versuche gerade mal die ganzen Interrupts zu programmieren, aber ich schaffs einfach nicht, habe sehr viele Fragen, aber die kommen spaeter, erstmal nur eine:
Undzwar: welches sind im Pmode die Hardware Interrupts, welches Exceptions, welches Software Interrupts und welches eigene Interrupts (sind Software und die eigenen die gleichen?) ?

So eine Liste waer mal ganz schoen.

Wenn ich das weiss, dann frag ich weiter :)

Edit: Und vielleicht nochmal die gleiche Liste fuer den Rmode, damit ich sehen kann, wo die Unterschiede sind.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: Svenska am 31. May 2007, 17:20
Such mal nach der "Ralph Brwon's Interrupt List".
Umfangreicher gehts nicht. :)
Titel: Re: Verwirrt durch Interrupts
Beitrag von: bitmaster am 31. May 2007, 17:47
Im ProtectedMode kannst du mittels PIC (im RM geht das auch, aber nicht empfohlen) die IRQs die InterruptNummern zuweisen. Also in meinem OS sind z.B. die IRQ0-IRQ7 den int20h bis int27h und die IRQ8-IRQ15 den  int28h bis int2Fh zugewisen. Also soweit ich weiß liegen die Exceptions bei int00h bis int1Fh, weswegen du dort die IRQs nicht platzieren solltest. Mit dem int30h bis intFFh kannst du dann machen was du willst.

bitmaster
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 31. May 2007, 17:55
Achso....
Also IRQs kommen nur von der Hardware?
Und die Sachen, die ich mit int aufrufe sind die ISRs?
Und ich kann jetzt einem IRQ sozusagen ein int zuweisen?
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 31. May 2007, 18:04
ja also du weist ihm im pm eher ein int gate zu welches auf ein codestück zeigt, welches den int behandlet.

ja irqs sind von der hardware...du kannst mit int theoretisch auch einen interrupt aufrufen, welcher eine exeption behandelt macht aber wenig sinn


gruss
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 31. May 2007, 18:10
Achso....Aber eine Exception ist doch auch ein interrupt, oder nicht?
Dann muesste ich also erstmal alle ISRs schreiben und dann die IRQs zuweisen...hm ...da ob ich das verstehe.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 31. May 2007, 18:13
nene isrs musst du nicht unbedingt schreiben...ich habe seit 2 jahren leere isrs und ab und zu fülle ich einen auf...

natürlich wäre eine kleine funktion gut, welche eine meldung ausgibt wenn eine exeption oder ein sonstiger int aufgerufen wird...das wäre aber nicht so aufwändig...

jaja eine exeption ist ein interrupt...


gruss
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 31. May 2007, 18:29
Aber man braucht doch einige ISRs, um ueberhaupt irgendwas machen zu koennen. Zumindest fuer die IRQs sollte man doch welche schreiben und evtl. fuer die Exceptions, oder nicht?
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 31. May 2007, 18:47
Jaja klar aber es macht nix wenn du zuerst noch z.B. Paging, Speicherverwaltung usw. machst...weil sonst musst du eventuell wieder Sachen an den ISRs ändern...Danach ist das programmieren von gescheiten ISRs und/oder Treibern neben dem machen einer (G)UI das wesentliche am OS-Dev
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 31. May 2007, 18:52
Hm....da ob ich das jetzt alles verstehe.... :/
Woher kenn ich denn die Adresse der ISR? Denn die brauch ich ja fuer die IDT.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 31. May 2007, 19:19
dort wo dein code beginnen soll machst du ein label...in asm so:

label:

dann kannst du im code stellvertretend für die adresse das label angeben(ohne doppelpunkt)...Hier einmal ein Muster Gate:

   dw label
   dw 8
   db 0
   db 11101110b
   dw 0


Somit hast du die Adresse direkt eingetragen...


gruss
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 31. May 2007, 19:22
Nur das Problem ist ja, dass in der IDT die Adresse in 2 words oder so eingeteilt ist. 
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 31. May 2007, 19:28
hmm ja das ist allerdings nur ein problem wenn dein Kernel (oder besser isr) überhalb von 64 KB ist...in diesem falle machst du das irgendwie so:
adresse_isr:
dd label


und dann verwendest du im Gate einmal:
dw [adresse_isr]

und einmal:
dw [adresse_isr+2]


Gruss
Titel: Re: Verwirrt durch Interrupts
Beitrag von: bluecode am 31. May 2007, 21:05
Wenn es dein Binärformat zulässt, dann (sollte mit nasm/yasm gehen):
dw label ; und
dw (label >> 16)
oder das label durch ein Codestück an den richtigen platz schreiben:
mov eax, label
mov [blabla], ax
shr eax, 16
mov [blabla2], ax

Nos Code funktioniert afaik nicht.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: Korona am 01. June 2007, 10:27
Afaik wird
dw label ; und
dw (label >> 16)
zumindest in NASM nicht funktionieren. (die Addresse von label wird erst durch den Linker bestimmt und kann daher nicht Teil eines Ausdrucks sein. Eventuell funkioniert der Code wenn du zu einer flachen Binary kompilierst, NASM überträgt zwischen seinen Stages aber normalerweise nur wenig Informationen, daher funzt das afaik auch nicht.)

Die beste Lösung ist wie Bluecode gesagt hat:
mov eax, label
mov [blabla], ax
shr eax, 16
mov [blabla2], ax
Titel: Re: Verwirrt durch Interrupts
Beitrag von: bluecode am 01. June 2007, 13:35
Eventuell funkioniert der Code wenn du zu einer flachen Binary kompilierst
Wie gesagt, es kommt aus das Format der Binary an. Mit elf geht es mit sicherheit nicht, da elf keine 16bit relocations unterstützt.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 01. June 2007, 19:38
Joa und wenn man noch ein bisschen optimieren wollte...aber für den anfang ist das mit shr sicher am schläusten....
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 02. June 2007, 12:40
Ok...mal sehen, ob ich das schaffe....
Aber wie mach ich das denn jetzt genau mit den IRQs, das hab ich noch nicht 100% verstanden...
Also ich sage dem ersten PIC, dass die IRQs 0-7 z.B. ISR32-39 sind und dem zweiten, dass IRQs 8-15 ISR40-47 sind?
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 02. June 2007, 14:07
ja aber für das gibt es überall fertige codestück...die eigentlich immer funktionieren...

gruss
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 02. June 2007, 14:21
Also die PICs hab ich nun remapped, die ISRs krieg ich auch noch selber hin, aber mit der IDT tu ich mich sehr schwer.
Folgendes habe ich mal geschrieben:
idt_start:
dw exception & 0x00ffff
dw 0x10
dw 0x8E00
dw exception >> 16
idt_end:
nasm:
idt.s:7: error: `&' operator may only be applied to scalar values
idt.s:10: error: shift operator may only be applied to scalar values

Ok, gegooglet:
You're trying to load a 16-bits field (a part of the IDT descriptor) with a reference to a 32-bit label that is subject to relocation. Try to replace

isr_label:
   iret
bad_stuff dw isr_label & 0xFFFF
          dw 0xdead
          dw 0xbeef
          dw isr_label >> 16

by something that extracts a 'pure value' from the address (e.g. the difference of two addresses are a pure value and $$ means to NASM the start of the section)

%define BASE_OF_SECTION SOME_CONSTANT_YOU_SHOULD_KNOW
isr_label:
   iret
good_stuff dw (BASE_OF_SECTION isr_label - $$) & 0xFFFF
           dw 0xcafe
           dw 0xbabe
           dw (BASE_OF_SECTION isr_label - $$) >> 16

The role of BASE_OF_SECTION is to adjust the pure offset to the real situation (usually as defined in your linker script), e.g. if your kernel get loaded at 1MB, you'll set it to 0x100000 to keep the CPU happy.

Aber das versteh ich nicht. Leider konnte ich mit den posts auch nicht so viel anfangen...
Titel: Re: Verwirrt durch Interrupts
Beitrag von: bluecode am 02. June 2007, 15:38
Du musst die Adresse von "exception" zur Laufzeit deines Kernels eintragen, d.h. du definierst zuerstmal die GDT ohne das label exception zu verwenden (habs den Deskriptor jetzt nicht auf korrektheit überprüft!):
idt_start:
dw 0
dw 0x10
dw 0x8E00
dw 0
Dann vervollständigst du die IDT bevor du sie lädst:
mov eax, exception
mov [idt_start], ax
shr eax, 16
mov [idt_start+6], ax

Und genau das hab ich in meinem vorletzten Post bereits vorgeschlagen :wink:
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 02. June 2007, 16:02
Aachso....hm...na ok...dann versuch ich das mal. Danke.

Also ich hab das jetzt so gemacht:
idt_start:
dw 0x0000
dw 0x10
dw 0x8E00
dw 0x00
idt_end:

idt_pointer:
dw idt_end - idt_start - 1
dd idt_start


set_idt:
mov eax, exception
mov [idt_start], ax
shr eax, 16
mov [idt_start+6], ax

lidt [idt_pointer]
sti
ret

Und so funktioniert es nicht. Und das liegt am sti. Da verreckt er immer. Wenn ich das sti auskommentiere, gehts, aber das ist ja nicht der Sinn. Denn ich brauche ja interrupts. Die PICs sind auch alle gesetzt. Oder brauche ich noch mehr ISRs?

Edit: Und die Adresse wird auch korrekt kopiert.
Edit: Anscheinend wird die Adresse doch nicht richtig eingetragen. Aber selbst, WENN ich sie manuell richtig eintrage, geht es nicht.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: MNemo am 02. June 2007, 16:56
Oder brauche ich noch mehr ISRs?

Du brauchst auf jeden Fall ein ISR für den Timer(IRQ0), wenn du den nicht ausschaltest.

Und du kannst natürlich auch alle Interrupts(auch exceptions, und so) per asm( INT ) aufrufen um sie zutesten.(ob mit oder ohne 'sti' ist da egal)
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 02. June 2007, 17:12
Du muss für alle Exeptions und HW-Ints eine ISR haben...wobei du auch überall die Gleiche himachen kannst...Am besten eine ohne Inhalt nur mit einem iret....

Probier mal noch nach dem progarmmieren der PICs, alle Harware-INTs zu deaktivieren. Etwa so:

   mov al, 11111110b                      ;IRQ-0 demaskieren, alle andern maskieren
   out 0x21, al
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 02. June 2007, 17:38
Dann werd ich erstmal 32+16 interrupts machen....hoffentlich gehts dann :/
Edit: Also manuelles Aufrufen per int funktioniert auch nicht :/
Seltsam :/
Edit: Ich fuerchte, der Eintrag ist falsch. ich habe den Einfach aus einem Tutorial kopiert und die Adresse angepasst, aber das scheint ja falsch zu sein.

Edit: Kann man nicht einfach die BIOS IDT inklusive ISRs irgendwo herbekommen und dann nur auf den PMode zuschneiden?
Titel: Re: Verwirrt durch Interrupts
Beitrag von: Thoth am 03. June 2007, 17:30
Soweit ich weiß verwendet das RM BIOS keine IDT, denn im Realmode gibt es lediglich eine sogenannte Interrupt Vector Table (IVT) am Anfang des Speichers (also Adresse 0), die für jeden Interrupt, angefangen mit dem ersten linear zwei Bytes Segment und zwei Bytes Offset der ISR speichert und bei einem Interrupt guckt die CPU dann halt in der IVT nach.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: bluecode am 03. June 2007, 17:49
Die BIOS ISR enthalten 16bit Code realmode code, das ist nicht unbedingt so wünschenswert im 32bit protected mode.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 03. June 2007, 18:06
Und den umzuschreiben macht keinen Sinn und dafür reicht auch dein Leben nicht aus...(Vorrausgesetzt du hast noch ein kleines bisschen Real-Life...)

...Wobei schöne Treiber im PM zu schreiben um ein "richtiges" Betriebsystem mit GUI und aufwendiger API zu machen würde warscheinlich auch zu lange dauern...

Tja darum ist das OS-Dev auch nicht einfach ein kleines Projekt von einem Jahr...Es sei denn man ist mit FAT 16 und einer UI mit 20 Befehlen zufrieden...


Gruss
Nooooooos
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 16. July 2007, 12:32
Hi, ich bins nochmal...nach einige Zeit hat mich das OS development wieder gepackt, aber ich haenge immernoch an dieser scheiss IDT. Ich glaube aber, dass ich jetzt weiss, wo der Fehler ist, undzar:
Folgendermassen sieht meine IDT aus, ich habe zu Testzwecken alle Eintraege ausgfuellt:
idt_start:
%rep 256
dw 0x02ec
dw 0x08  ; <---hier
dw 0x8E00
dw 0x10
%endrep
idt_end:

idt_pointer:
dw idt_end - idt_start - 1
dd idt_start
lidt [idt_pointer]

Die Addresse meiner universal isr ist bei 0x1002ec, die hab ich manuell eingetragen.
An der markierten Stelle soll der "code selector" stehen, hab ich gelesen.
So sieht meine GDT aus:
GDTR:

GDTsize DW GDT_END-GDT-1

GDTbase DD GDT



GDT:

NULL_SEL        EQU $-GDT     ; null descriptor is required (64bit per entry)

      DD 0x0

      DD 0x0

CODESEL     EQU $-GDT       ; 4GB Flat Code at 0x0 with max 0xFFFFF limit

      DW     0xFFFF           ; Limit(2):0xFFFF

      DW     0x0              ; Base(3)

      DB     0x0              ; Base(2)

      DB     0x9A             ; Type: present,ring0,code,exec/read/accessed (10011000)

      DB     0xCF             ; Limit(1):0xF | Flags:4Kb inc,32bit (11001111)

      DB     0x0              ; Base(1)

DATASEL     EQU $-GDT       ; 4GB Flat Data at 0x0 with max 0xFFFFF limit

      DW     0xFFFF           ; Limit(2):0xFFFF

      DW     0x0              ; Base(3)

      DB     0x0              ; Base(2)

      DB     0x92             ; Type: present,ring0,data/stack,read/write (10010010)

      DB     0xCF             ; Limit(1):0xF | Flags:4Kb inc,32bit (11001111)

      DB     0x0              ; Base(1)

GDT_END:
Was soll jetzt der code selector sein?
CODESEL?
Den habe ich naemlich eingetragen, ist in dem Falle 8, weil zwar dwords dazwischen sind, aber es geht immer noch nicht.
Ich kann keine interrupts aufrufen. Hoffentlich ist nicht alles so schwierig wie die IDT :/
Titel: Re: Verwirrt durch Interrupts
Beitrag von: bluecode am 16. July 2007, 12:51
Was soll jetzt der code selector sein? CODESEL?
Jo genau das sollte es sein...

Was passiert denn überhaupt (Triple fault?)? Was sagt das bochs log (am besten mal bevor dein kernel ausgeführt word strg+c drücken und das debugging für das CPU device überall auf "report" stellen... Wie testest du deine IDT (IF = 0/1?)?

[Ich hab den Rest vom Thread nicht gelesen.]
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 16. July 2007, 13:30
Hast du vor dem sti alle Handware Interrupts maskiert?
Zeig bitte mal noch den sti und den PIC Code...

Gruss
Noooooooooos
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kotzkroete am 17. July 2007, 08:56
@noooooos:
Also die Hardware interrupts habe ich DEmaskiert, so wie du es mir in einem anderen Post gesagt hast (zu Testzwecken).
Hiermit remappe ich die PICs:
PIC1 equ 0x20
PIC2 equ 0xA0
PIC1_DATA equ PIC1 + 1
PIC2_DATA equ PIC2 + 1

ICW1 equ 0x11
ICW4 equ 0x01


remap_pics: ; eax = offset1 ebx = offset2
push eax

in eax, PIC1_DATA
mov [a1], al

in eax, PIC2_DATA
mov [a2], al

mov eax, ICW1
out PIC1, eax
out PIC1, eax

pop eax
out PIC1_DATA, eax
mov eax, ebx
out PIC2_DATA, eax

mov al, 4
out PIC1_DATA, al
mov al, 2
out PIC2_DATA, al

mov eax, ICW4
out PIC1_DATA, eax
out PIC2_DATA, eax

mov eax, [a1]
out PIC1_DATA, eax
mov eax, [a2]
out PIC2_DATA, eax
ret


a1 db 0
a2 db 0

Und mir
mov eax, 0x20
mov ebx, 0x28
call remap_pics
rufe ich die Funktion auf.

Aber egal wie ich es mache, es funktioniert nicht. Kein int funktioniert und qemu friert einfach ein. Ich kann es nicht mal mehr beenden.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kevin am 17. July 2007, 09:27
Durch Einfrieren signalisiert qemu typischerweise einen Triple Fault. ;)

Du kannst mal probieren qemu mit -d int zu starten, dann bekommst du eine riesige Logfile, wo drinsteht, welche Exception es genau ist und wo sie aufgetreten ist. bochs reagiert in solchen Situationen manchmal souveräner, aber leider auch längst nicht immer.
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 17. July 2007, 10:40
Wird warschienlich beim sti passieren...Jedenfalls war das bei mir so
Nur dumm dass ich eigentlich nicht weiss warum das passiert ist...$

Hast du direkt nach dem sti eine Endlosschleife? Wenn ja mach soeine auch mal in den Interrupt-Handler...sonst gibt das logisch einen TripleFault...

Könntest du eventuell mal irgendwo deinen ganzen Code hochladen? (nopaste)

Gruss
Nooooooooooos
Titel: Re: Verwirrt durch Interrupts
Beitrag von: kevin am 17. July 2007, 12:43
Wird warschienlich beim sti passieren...Jedenfalls war das bei mir so
Nur dumm dass ich eigentlich nicht weiss warum das passiert ist...$
Daß sich eine kaputte IDT erst nach einem sti bemerkbar macht, ist eigentlich logisch, oder?

Zitat
Hast du direkt nach dem sti eine Endlosschleife? Wenn ja mach soeine auch mal in den Interrupt-Handler...sonst gibt das logisch einen TripleFault...
Hä? Wieso soll eine Endlosschleife nach dem sti einen Triple Fault verursachen? Das ist doch völlig legitim, da eine Endlosschleife hinzusetzen?
Titel: Re: Verwirrt durch Interrupts
Beitrag von: nooooooooos am 17. July 2007, 13:38
Mit ersterem meinte ich das es nichts bringt zu schauen bei welcher Adresse der Fault auftritt da dies eben logisch ist.

Die Endlosschleife verursacht eben kein Triple Fault aber keine eben eventuell schon... :-D

Gruss
Nooooooooooooos