Autor Thema: Warum wird IRQ14 nur einmal aufgerufen?  (Gelesen 12804 mal)

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« am: 13. October 2006, 17:46 »
Hallo,

ich versuche die ganze Zeit über Ports und dem IRQ14 Daten auf Sektore einer Festplatte zu schreiben. Dafür nehme ich mein altes Notebook. Ich habe Win95 installiert und mir die Ressourcen des Festplattencontrollers angeschaut. Dort steht wie erwartet: IRQ14, Ports 1F0h - 1F7h etc. Dann wandelte ich den Spaghetti Code (in C/C++ geschrieben) von meinem PC Hardwarebuch in Assembler Code um. Da ich 4 Sektore schreibe, soll der IRQ14 auch vier mal aufgerufen werden. Aber bei mir wird er nur ein einziges mal aufgerufen. Ich verstehe das einfach nicht. Schließlich sende ich ja am Ende einen EOI. Könnt ihr mir vielleicht weiter helfen. Das ist ein Bootsektor-Code den ich assembliere (mit fasm), auf Diskette kopiere und mein altes Notebook von dieser starten lasse. Hier der Code:

org 0

cli
mov ax,07C0h
mov ds,ax
mov es,ax
xor ax,ax
mov ss,ax
mov sp,7BFEh
sti

mov si,SetIRQ14Msg
call WriteMsg

push es

cli
xor ax,ax
mov es,ax
mov ax,07C0h
shl eax,16
mov ax,int76h ;IRQ14
mov [es:76h*4],eax
sti

pop es

mov si,WriteSectorsMsg
call WriteMsg

cli

.1:
mov dx,1F7h
in al,dx
test al,80h
jnz .1

mov al,4 ;Sektoranzahl
mov dx,1F2h
out dx,al

mov al,0 ;Sektornummer
mov dx,1F3h
out dx,al

mov al,0 ;Spur LSB
mov dx,1F4h
out dx,al

mov al,0 ;Spur MSB
mov dx,1F5h
out dx,al

mov al,10100000b ;DRV=0, Head = 0
mov dx,1F6h
out dx,al

mov al,00110011b ;command for write sectors
mov dx,1F7h
out dx,al

;warte bis bereit
.2:
mov dx,1F7h
in al,dx

test al,80h
jnz .2

test al,08h
jz .2

;schreibe ersten Sektor (erst danach sollte immer ein IRQ14 aufgerufen werden)
mov cx,512/2
mov si,WPuffer
mov dx,1F0h
rep outsw

mov cx,4
mov si,BPuffer
;mov dx,1F0h
rep outsb

sti ;jetzt können die IRQs kommen

.3:
cmp [int_count],4
jb .3 ;warte auf die restlichen IRQ14 <- hier bleibt der hängen da nur einmal der IRQ14 aufgerufen wird

mov si,FinishMsg <- wird nie ausgeführt
call WriteMsg

jmp $


int76h: <- Code des IRQ14, wird nur einmal ausgeführt
cmp [int_count],4
ja .1
inc [int_count]

mov cx,512/2
mov si,WPuffer
mov dx,1F0h
rep outsw

mov cx,4
mov si,BPuffer
;mov dx,1F0h
rep outsb

.1:

mov al,20h  <- extra am EOI gedacht
out 20h,al
out 0A0h,al
iret


WriteMsg:
lodsb
or al,al
jz .1
mov ah,0Eh
int 10h
jmp WriteMsg

.1:
ret


SetIRQ14Msg db "Initialisiere den IRQ14 neu...",0
WriteSectorsMsg db 13,10,"Schreibe die Sektoren...",0
FinishMsg db 13,10,10,"Ende...",0
WPuffer: <- nur Testdaten (muss eigentlich 512 Byte groß sein, aber da kein Platz, ist ja egal)
dw 0AA55h
BPuffer:
times 4 db 22h
int_count db 0

times 510-($-$$) db 0
dw 0AA55h

Also ich bin mit mein Latein am Ende. Aber vielleicht wisst ihr ja was falsch ist.

thx

bitmaster
In the Future everyone will need OS-64!!!

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 13. October 2006, 18:24 »
Du gibst doch den startsektor im CHS-Format an ?!?
Im CHS-Format gibt es nicht SectorNummer 0 (nur Cylinder 0, Head 0 & Sector 1)
Probiers ma mit Sectornummer 1
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #2 am: 13. October 2006, 22:35 »
Du gibst doch den startsektor im CHS-Format an ?!?
Im CHS-Format gibt es nicht SectorNummer 0 (nur Cylinder 0, Head 0 & Sector 1)
Probiers ma mit Sectornummer 1
OK, aber auch wenn ich einen anderen Sektor angebe (z.B. 1, 2 etc.) passiert genau das selbe. Der IRQ14 wird nur einmal aufgerufen.

thx

bitmaster
In the Future everyone will need OS-64!!!

BehindTheScenes

  • Beiträge: 12
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 13. October 2006, 22:38 »
Hmm, wenn alle 4 Sektoren gelsen worden sind, dann wird der IRQ14 ausgelöst, den dann hat die Festplatte die Aufgabe erledigt ... und net nach jedem Sektor, dafür musst du schon die Anzahl der Sektoren auf 1 stellen ;)
We change the future and the future change us!
leParkour ==> http://www.be-free-and-jump.com

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #4 am: 13. October 2006, 23:35 »
Hmm, wenn alle 4 Sektoren gelsen worden sind, dann wird der IRQ14 ausgelöst, den dann hat die Festplatte die Aufgabe erledigt ... und net nach jedem Sektor, dafür musst du schon die Anzahl der Sektoren auf 1 stellen ;)
Sorry, aber wenn man keine Ahnung hat einfach mal Schnautze halten. Nach jedem Sektor wird ein IRQ14 bzw. sollte ein IRQ14 aufgerufen werden. Von dir will ich diesem Beitrag auch nichts hören.

thx

bitmaster
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 13. October 2006, 23:40 »
Wieso so gereizt, bitmaster? Wenn die Information falsch ist, kannst du das natürlich gern korrigieren, aber ein angenehmerer Ton wäre wünschenswert.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #6 am: 13. October 2006, 23:48 »
@taljeth: Wer nicht mal weiß das man im RM keine 4 GByte Adressieren kann (außer natürich unrealmode) und das man im PM auch den A20 aktiviert haben muss um alle 4 GByte zu adressieren soll mir hier nicht meine Informationen für falsch erklären. Schon gar nicht wenn er keine Ahnung hat und das einfach mal so denkt. Ich bezweifle das er sich mit diesem Thema schon auseinandergesetzt hat.

Und jetzt kommt bitte nicht immer vom Thema ab. Mein Problem ist das der IRQ14 nur einmal aufgerufen wird und kein Sektor verändert (beschrieben) wird. Ich möchte gerne wissen ob einer weiß wieso. Was ist an meinem Code falsch.

thx

bitmaster
In the Future everyone will need OS-64!!!

AndiDog

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 14. October 2006, 13:50 »
Zitat
.1:

mov al,20h  <- extra am EOI gedacht
out 20h,al
out 0A0h,al
iret

Also da glaube ich liegt dein Fehler. Du hast zwar richtig gedacht, weil man für IRQ 8 bis 15 auch an den zweiten Interruptcontroller einen EOI senden muss - meiner Meinung nach musst aber den EOI zuerst an den Slave, und dann erst an den Master schicken (der Port 0xA0 steht für den Slave). Es sollte also heißen:

.1:

mov al,20h
out 0A0h,al    ; Slave EOI
out 20h,al      ; Master EOI
iret

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #8 am: 14. October 2006, 17:12 »
@AndiDog: Davon habe ich noch nie was gehört das erst an Slave gesendet werden muss und dann an Master. Ich habe das aber mal gemacht. Ändert aber nichts daran. Der IRQ14 wird weiterhin nur einmal aufgerufen.

bitmaster
In the Future everyone will need OS-64!!!

AndiDog

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 14. October 2006, 18:48 »
Schau mal hier, vielleicht hilft dir das weiter:

http://osdever.net/bkerndev/Docs/irqs.htm (Bran's Kernel Development Tutorial, sehr zu empfehlen)

Ist halt zum Schreiben von Interrupthandlern gedacht, aber egal...
« Letzte Änderung: 14. October 2006, 18:50 von AndiDog »

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #10 am: 14. October 2006, 22:31 »
@AndiDog: Dort wird zwar erst an den Slave gesendet und dann an den Master, aber wo steht dort das es diese Reihenfolge sein muss?

Weiß sonst noch jemand was der Fehler sein könnte?

thx

bitmaster
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 15. October 2006, 11:38 »
Ich hab hier mal ein paar Posts von BehindTheScenes und bitmaster gelöscht. Leute, hier geht es um ein technisches Thema, persönliche Beleidigungen gehören sicher nicht dazu und werden in keinem Bereich des Forums geduldet. Lernt mal, wie man miteinander umgeht.

Für BehindTheScenes ist das der Grund für seinen Bann, für bitmaster eine ernste Verwarnung.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

AndiDog

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 15. October 2006, 15:33 »
Also ich hab deinen Code mal assembliert und in Bochs gebootet.

Mir ist aufgefallen, dass der Interrupt überhaupt nicht aufgerufen wird.
Probier's doch selbst mal aus: Ich habe als Schreibquelle nicht "WBuffer" benutzt, sondern das Label "start" das ich an den Codeanfang gesetzt hab (damit hat man auf jeden Fall 512 byte zusammen und kann im Festplattenimage erkennen, was geschrieben wurde). Außerdem habe ich nach "mov si, start" jeweils noch eine Zeile "mov word [si], 0x****" gesetzt (setze für die **** vor und innerhalb des Interrupts was unterschiedliches ein um unterscheiden zu können wer auf die Festplatte schreibt). Dann habe ich das Ganze als Floppy gebootet und heraus kam, dass der Interrupt nicht aufgerufen wurde (d.h. er schreibt nix). Der erste Sektor allerdings wird korrekt geschrieben.

Ich wusste gar nicht (bin noch en Noob sorry) dass bei solchen Fällen ein Interrupt aufgerufen wird, weil ich IDE-Lesen/Schreiben bisher nur im Protected Mode mache.

Noch en paar Sachen, die vielleicht falsch sind:

- "mov al, 10100000b" - die gesetzten Bits sind obsolete (ich weiß dass es in Bochs funktioniert, wenn sie null sind)
- "mov al, 00110011b;command for write sectors" - die Zahl entspricht 0x33 was allerdings "Write long without retry" wäre (bei Festplatten vielleicht doch lieber 0x30 = write sectors with retry oder 0x31 without retry)

Und den folgenden Abschnitt kapier ich gar net, wozu is der da:
Zitat
mov cx,4
mov si,BPuffer
;mov dx,1F0h
rep outsb

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 15. October 2006, 16:06 »
Ich wusste gar nicht (bin noch en Noob sorry) dass bei solchen Fällen ein Interrupt aufgerufen wird, weil ich IDE-Lesen/Schreiben bisher nur im Protected Mode mache.
Das hat aber nichts mit dem Protected Mode zu tun, ob ein Interrupt ausgelöst wird oder nicht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #14 am: 15. October 2006, 16:18 »
@AndiDog: Also bei mir wird der IRQ14 einmal aufgerufen. Denn ich habe zum Spass mal Code der eine Meldung ausgibt in dem IRQ14 Händler eingebaut. Und die Meldung erscheint einmal. Das mit 33h habe ich aus dem PC Hardwarebuch, Auflage 7 unter IDE (eigentlich den kompletten Code).

Was ist denn der Unterschied zwischen 30h, 31h und 33h?

thx

bitmaster
In the Future everyone will need OS-64!!!

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #15 am: 15. October 2006, 16:36 »
Was ist denn der Unterschied zwischen 30h, 31h und 33h?
33h ist obsolet (zumindest nach ATA/ATAPI 4)
31h: Write sector
30h: Write sector (wiederholt)
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

AndiDog

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 15. October 2006, 17:02 »
Ich schätz mal, wenn ein Sektor (mechanisch) beschädigt ist oder sonstwie nicht gelesen werden kann, probiert die Festplatte noch einmal, ihn zu lesen (Retry-Modus 30h).

Ach ja: Auf manchen Seiten steht, dass immer nur ein Sektor gelesen wird (d.h. ich weiß gar nicht ob 4 Sektoren zu lesen auf deine Art funktioniert).

http://www.ulinktech.com/downloads/ATA_Command_Table.doc
http://hem.passagen.se/communication/ide.html

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #17 am: 18. October 2006, 00:00 »
Also das Thema hat sich jetzt erledigt. Ich bin auf LBA umgestiegen. Aber ich glaube ich weiß wieso der IRQ14 nur einmal aufgerufen wurde. In meinem PC Hardwarebuch und in dem Dokument von Toaster steht das bei der Ansprechung des Statusregisters (sprich in diesem Fall 1F7h) eine eventuell anhängige Interrupt-Anforderung - im PC über IRQ14 - stoniert wird.

bitmaster
In the Future everyone will need OS-64!!!

 

Einloggen