Autor Thema: Floppy auf echtem PC lesen  (Gelesen 5414 mal)

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« am: 14. September 2005, 13:44 »
Hi,

ich schreibe grad bisl ein OS und teste das immer mit bochs.
jetzt habe ich es mal endlich auf ne richtige floppy getan und
es geht nicht.
liegt wahrscheinlich an meinen floppy-read-code.
da lese ich nich, wie in allen beispielen im internet, nur einmal
sondern 3 mal.

sieht dann so aus:
- int13, 00 -> reseten
- 3x int13, 02 -> Sektoren in Memory lesen

wenn ich nur einen int13,02 mache dann geht es (bzw es geht soweit
es soll, weil die andren daten ja auch gebraucht werden).
die parameter scheinen ja auch richtig zu sein da es mit bochs funzt.
hab auch schon probiert vor jeden int13,02 zu reseten -> geht nich

hoffe jemand kann mir damit helfen !

und nochwas: ich würde ganz gerne, dass nach dem lesen das disketten-
licht wieder ausgeht... falls da jemand knowhow hat..

naja schon ma danke im vorraus

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 14. September 2005, 14:01 »
Dazu bräuchte man warscheinlich deinen Code. Ich kann dazu nur sagen, dass unter Bochs öfter mal Sachen gehen, die auf einem echten PC Probleme machen.

Zitat
und nochwas: ich würde ganz gerne, dass nach dem lesen das disketten-
licht wieder ausgeht... falls da jemand knowhow hat..

Dazu musst du den Motor ausschalten. Wir hatten in einem der letzten Threads mal was dazu.
Edit der Code dafür:

mov dx,0x3F2
mov al,0x0C
out dx,al

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 14. September 2005, 14:07 »
erstmal danke für die motor geschichte...

hatte den code als erstes nich gepostet weil is bisl lang aber wenns anders nicht geht... bitte schön:


_disk_reset:
; Diskdrive reset (Interrupt 13h, 0)
push ds            ; Sichere DS
mov ax, 0          ; Die gewünschte Funktion (reset)
mov dl, [bootdrv]
int 13h            ; Den Interrupt ausführen
pop ds             ; DS wiederherstellen
jc _disk_reset            ; Geht nicht? -> Noch mal!

; ------------------------------------------------
; kernel
; ------------------------------------------------
_loadkernel:

mov ax,0x1000      ; ES:BX = 10000
mov es,ax
mov bx, 0

mov al, 18 ; num of sectors
mov cx, 2 ; cylinder + start sector
mov dh, 0 ; head

; Read Sectors( Int 0x13, 2 )
mov dl, [bootdrv]
mov ah, 2
int 0x13  

jc _loadkernel


_loadprogramfiles:
; ------------------------------------------------
; command
; ------------------------------------------------
_loadprogramfiles_1:
mov ax,0x5200      ; ES:BX = 52000
mov es,ax
mov bx, 0

mov al, 18 ; num of sectors
mov cx, 2 ; cylinder + start sector
mov dh, 1 ; head

; Read Sectors( Int 0x13, 2 )
mov dl, [bootdrv]
mov ah, 2
int 0x13  

jc _loadprogramfiles_1        ; Fehler? Noch mal!

; ------------------------------------------------
; info
; ------------------------------------------------
_loadprogramfiles_2:
mov ax,0x5300      ; ES:BX = 53000
mov es,ax
mov bx, 0

mov al, 18 ; num of sectors
mov cx, 5 ; cylinder + start sector
mov dh, 1 ; head

; Read Sectors( Int 0x13, 2 )
mov dl, [bootdrv]
mov ah, 2
int 0x13  

jc _loadprogramfiles_2        ; Fehler? Noch mal!

_load_end:


wobei in bootdrv die richtige zahl liegt ... hat ja funktioniert wenn nur der
kernel geladen wird

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 15. September 2005, 14:23 »
hat keiner ne lösung ??

oder wenigstens ein quellcode in dem
mehr als einmal etwas mit dem BIOS
von der floppy gelesen wird ?

WhiteDragon

  • Beiträge: 124
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 15. September 2005, 15:50 »
Also wenn ich es richtig verstehe, wird deine Routine zwar korrekt durchlaufen, aber die Daten sind nicht so wie du es erwartest.

Falls dem so ist, kann ich dir sagen, woran das liegt:

Du liest in jedem der drei Blöcke jeweils 18 Sektoren. Da ein Sektor 512 Byte entspricht sind das dann jeweils 9 kByte.

Deine Anfangsadressen sind 0x10000, 0x52000 und 0x53000.

Das heißt, es werden nacheinander die folgenden drei Speicherbereiche beschrieben:

0x10000 - 0x121ff
0x52000 - 0x541ff
0x53000 - 0x551ff

Wie du siehst, überlappen sich der zweite und dritte Bereich in 0x53000 - 0x541ff. Daher sind deine Daten vom zweiten Lesen wohl nicht mehr so, wie du sie gerne hättest.

Ansonsten sind deine Routinen korrekt aufgebaut.

Ich hoffe, dass dir das weiter hilft. Wenn nicht, dann schreibe einfach, was das für Daten sind und was genauer schief läuft, wir finden die entsprechende Lösung mit Sicherheit.

Gruß!

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 16. September 2005, 20:56 »
nein die bereiche die sich überschneiden machen da kein problem
sie sind im moment noch sehr klein... ausserdem gehts ja bei
bochs einbandfrei.

und so weit ich das sehe ist das problem, das der pc irgentwo während
diesen Lese-Codes einfriert.

falls es wirklich jemanden interressiert:
das was nach 0x10000 geladen wird ist der kernel und die andren beiden
teile sind kleine testprogramme.
und wie gesagt wenn man nur den kernel läd dann gehts!

danke für den hinweis mit den überschneidungen, hoffe es gibt noch mehr ideen

WhiteDragon

  • Beiträge: 124
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 17. September 2005, 15:01 »
Hi,

ich werde gerne weiter helfen, bitte sei doch so nett und gib mal deinen Source komplett her - das macht für mich die Sache einfacher.

Gruß!

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 17. September 2005, 16:48 »
kein problem.
danke das du es auf dich nimmst den ganz durch zu guckn

boot.asm:

[BITS 16]
org 0x7C00

start:

mov [bootdrv], dl

mov ax, cs
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

; -----------------------------------
; Setup Stack
; -----------------------------------
cli             ; Keine Interrupts!
mov ax, 0x9000  ; Stackadresse
mov ss, ax      ; SS = 9000 (unser Stack)
mov sp, 0       ; SP = 0000  (der Stackpointer)
sti             ; Interrupts zulassen

; -----------------------------------
; Enable A20
; -----------------------------------
call enableA20

; -----------------------------------
; Load Kernel
; -----------------------------------
%include "load_floppy.inc"

; -----------------------------------
; Print a message
; -----------------------------------
%include "message.inc"   <-----------------------HIER DIESE MESSAGE WIRD NICH ANGEZEIGT (ES SEI DENN ICH MACHE SIE VOR DEN FLOPPY LOAD)

; -----------------------------------
; Setup GDT
; -----------------------------------
lgdt [gdt]

; -----------------------------------
; Enter Protected Mode
; -----------------------------------
cli
mov ecx, CR0
or ecx, 1
mov CR0, ecx

db 0xea ;Bitmuster für einen FAR JUMP
dw PMode ;Angabe des Offsets zu dem gesprungen werden soll
dw 0x8 ;Angabe des Selektors für das Segment zu dem gesprungen werden soll.

; -----------------------------------
; Refresh Registers
; -----------------------------------
[BITS 32]

PMode:
mov eax, 2 ;Index 2 der GDT auswählen
shl eax, 3
mov ds, ax
mov es, ax
mov ss, ax
mov eax, 0
mov fs, ax ;FS und GS auf NULL Deskriptor zeigen lassen
mov gs, ax
mov esp, 0x1FFFF ;ESP setzen

; -----------------------------------
; Jump to the Kernel
; -----------------------------------
jmp dword 8:0x10000

%include "gdt.inc"
%include "a20gate.inc"

bootdrv db 0
loadmsg db "Loading ClusterOS...",13,10,0

TIMES 510-($-$$) DB 0
SIGNATURE DW 0xAA55


load_floppy.inc:

_disk_reset:
; Diskdrive reset (Interrupt 13h, 0)
push ds            ; Sichere DS
mov ax, 0          ; Die gewünschte Funktion (reset)
mov dl, [bootdrv]
int 13h            ; Den Interrupt ausführen
pop ds             ; DS wiederherstellen
jc _disk_reset            ; Geht nicht? -> Noch mal!

; ------------------------------------------------
; kernel
; ------------------------------------------------
_loadkernel:

mov ax,0x1000      ; ES:BX = 10000
mov es,ax
mov bx, 0

mov al, 18 ; num of sectors
mov cx, 2 ; cylinder + start sector
mov dh, 0 ; head

; Read Sectors( Int 0x13, 2 )
mov dl, [bootdrv]
mov ah, 2
int 0x13  

jc _loadkernel


_loadprogramfiles:
; ------------------------------------------------
; command
; ------------------------------------------------
_loadprogramfiles_1:
mov ax,0x5200      ; ES:BX = 52000
mov es,ax
mov bx, 0

mov al, 18 ; num of sectors
mov cx, 2 ; cylinder + start sector
mov dh, 1 ; head

; Read Sectors( Int 0x13, 2 )
mov dl, [bootdrv]
mov ah, 2
int 0x13  

jc _loadprogramfiles_1        ; Fehler? Noch mal!

; ------------------------------------------------
; info
; ------------------------------------------------
_loadprogramfiles_2:
mov ax,0x5300      ; ES:BX = 53000
mov es,ax
mov bx, 0

mov al, 18 ; num of sectors
mov cx, 5 ; cylinder + start sector
mov dh, 1 ; head

; Read Sectors( Int 0x13, 2 )
mov dl, [bootdrv]
mov ah, 2
int 0x13  

jc _loadprogramfiles_2        ; Fehler? Noch mal!

_load_end:

; deactivate floppy-motor
mov dx,0x3F2
mov al,0x0C
out dx,al


message.inc

mov si,loadmsg

putstr:
lodsb             ; Byte laden
or al,al
jz short putstrd  ; 0-Byte? -> Ende!

mov ah,0x0E       ; Funktion 0x0E
mov bx,0x0007     ; Attribut-Byte (wird nicht benötigt)
int 0x10          ; schreiben
jmp putstr        ; Nächstes Byte

putstrd:


gdt.inc

gdt_start:
dd 0 ;Ein DWORD mit dem Wert 0
dd 0 ;Ein DWORD mit dem Wert 0

FLAT_CODE: ; 1
dw 0xFFFFF
dw 0x0
db 0x0
db 9Ah
db 0CFh
db 0

FLAT_DATA: ; 2
dw 0xFFFFF
dw 0x0
db 0x0
db 92h
db 0CFh
db 0

gdt:
dw gdt - gdt_start - 1
dd gdt_start


a20gate.inc habe ich von einen andren projekt rauskopiert.
steht nur code drinne der den a20 aktiviert.
sollte also nix falsche drinnen sein.


;;
;; enableA20.s (adapted from Visopsys OS-loader)
;;
;; Copyright (c) 2000, J. Andrew McLaughlin
;; You're free to use this code in any manner you like, as long as this
;; notice is included (and you give credit where it is due), and as long
;; as you understand and accept that it comes with NO WARRANTY OF ANY KIND.
;; Contact me at jamesamc@yahoo.com about any bugs or problems.
;;

enableA20:
;; This subroutine will enable the A20 address line in the keyboard
;; controller.  Takes no arguments.  Returns 0 in EAX on success,
;; -1 on failure.  Written for use in 16-bit code, see lines marked
;; with 32-BIT for use in 32-bit code.

pusha

;; Make sure interrupts are disabled
cli

;; Keep a counter so that we can make up to 5 attempts to turn
;; on A20 if necessary
mov CX, 5

.startAttempt1:
;; Wait for the controller to be ready for a command
.commandWait1:
xor AX, AX
in AL, 64h
bt AX, 1
jc .commandWait1

;; Tell the controller we want to read the current status.
;; Send the command D0h: read output port.
mov AL, 0D0h
out 64h, AL

;; Wait for the controller to be ready with a byte of data
.dataWait1:
xor AX, AX
in AL, 64h
bt AX, 0
jnc .dataWait1

;; Read the current port status from port 60h
xor AX, AX
in AL, 60h

;; Save the current value of (E)AX
push AX; 16-BIT
;; push EAX; 32-BIT

;; Wait for the controller to be ready for a command
.commandWait2:
in AL, 64h
bt AX, 1
jc .commandWait2

;; Tell the controller we want to write the status byte again
mov AL, 0D1h
out 64h, AL

;; Wait for the controller to be ready for the data
.commandWait3:
xor AX, AX
in AL, 64h
bt AX, 1
jc .commandWait3

;; Write the new value to port 60h.  Remember we saved the old
;; value on the stack
pop AX; 16-BIT
;; pop EAX; 32-BIT

;; Turn on the A20 enable bit
or AL, 00000010b
out 60h, AL

;; Finally, we will attempt to read back the A20 status
;; to ensure it was enabled.

;; Wait for the controller to be ready for a command
.commandWait4:
xor AX, AX
in AL, 64h
bt AX, 1
jc .commandWait4

;; Send the command D0h: read output port.
mov AL, 0D0h
out 64h, AL

;; Wait for the controller to be ready with a byte of data
.dataWait2:
xor AX, AX
in AL, 64h
bt AX, 0
jnc .dataWait2

;; Read the current port status from port 60h
xor AX, AX
in AL, 60h

;; Is A20 enabled?
bt AX, 1

;; Check the result.  If carry is on, A20 is on.
jc .success

;; Should we retry the operation?  If the counter value in ECX
;; has not reached zero, we will retry
loop .startAttempt1


;; Well, our initial attempt to set A20 has failed.  Now we will
;; try a backup method (which is supposedly not supported on many
;; chipsets, but which seems to be the only method that works on
;; other chipsets).


;; Keep a counter so that we can make up to 5 attempts to turn
;; on A20 if necessary
mov CX, 5

.startAttempt2:
;; Wait for the keyboard to be ready for another command
.commandWait6:
xor AX, AX
in AL, 64h
bt AX, 1
jc .commandWait6

;; Tell the controller we want to turn on A20
mov AL, 0DFh
out 64h, AL

;; Again, we will attempt to read back the A20 status
;; to ensure it was enabled.

;; Wait for the controller to be ready for a command
.commandWait7:
xor AX, AX
in AL, 64h
bt AX, 1
jc .commandWait7

;; Send the command D0h: read output port.
mov AL, 0D0h
out 64h, AL

;; Wait for the controller to be ready with a byte of data
.dataWait3:
xor AX, AX
in AL, 64h
bt AX, 0
jnc .dataWait3

;; Read the current port status from port 60h
xor AX, AX
in AL, 60h

;; Is A20 enabled?
bt AX, 1

;; Check the result.  If carry is on, A20 is on, but we might warn
;; that we had to use this alternate method
jc .warn

;; Should we retry the operation?  If the counter value in ECX
;; has not reached zero, we will retry
loop .startAttempt2


;; OK, we weren't able to set the A20 address line.  Do you want
;; to put an error message here?
jmp .fail


.warn:
;; Here you may or may not want to print a warning message about
;; the fact that we had to use the nonstandard alternate enabling
;; method

.success:
sti
popa
xor EAX, EAX
ret

.fail:
sti
popa
mov EAX, -1
ret

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 19. September 2005, 12:17 »
biiitttteeee helft mir !!! bin praktisch fertig mit dem OS kann es aber nich auf nem echten PC austesten !

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #9 am: 19. September 2005, 17:40 »
*SPAM* Ein OS ist niemals fertig^^ *SPAM*
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

WhiteDragon

  • Beiträge: 124
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 19. September 2005, 21:23 »
Bin noch am Testen, habe aber nicht immer so viel Zeit und die nimmt Debugging nun mal in Anspruch...

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 22. September 2005, 15:07 »
Du hast ja im Moment drei mal den fast gleichen Code (zum Lesen von drei Bereichen auf der Festplatte). Es würde schon mal mehr Sinn machen das ganze in eine Funktion zu packen, also so:

; Parameter:
; CX = Anzahl der zu lesenden Sektoren
; AX = Erster Sektor
; [DestSeg] = Zielsegment
; [DestOff] = Zieloffset
ReadSectors:
; Insert Code her
ret

Bei mir funktioniert das so auf jeden Fall und es ist leichter Änderungen vorzunehmen.

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 24. September 2005, 19:58 »
jaja hab ich auch schon überlegt...
sind aber fast alles parameter die geändert werden
müssen .. man würde keinen besonderen Vorteil
dadurch bekommen.

Aber plz ich hoffe irgentjemand fällt ein warum es nich geht

 

Einloggen