mehr als ein cylinder
-
ich bekomms einfach net hin..
ich möchte ca. 20kb von diskette ins ram laden.. das macht 3 cylinder.
zum testen hab ich jetz 3 mal das selbe mit int 13h hingeschrieben.beginnen soll alles bei adresse 09000h
mov ax, 0900h
mov es, ax
mov bx, 0xor dx, dx
mov ch, 0
mov cl, 2
mov al, 17
mov ah, 02h
int 13hmov bx, 8704 ; 17 * 512
xor dx, dx
mov ch, 1
mov cl, 1
mov al, 18
mov ah, 02h
int 13hmov bx, 17920 ; (17+18) * 512
xor dx, dx
mov ch, 2
mov cl, 1
mov al, 18
mov ah, 02h
int 13hsobald ich im programm über einen near call einen code ausfuehre, der im 2ten oder 3ten cylinder liegt/lag, stürzt er entweder gleich ab oder er zeigt nur schrott an (scheinbar irgendwelche restdaten, die noch auf diskette waren weil ich sie net formatiert habe)
..wers genau wissen will, er hat bei mir einen abschnitt eines java sourcecodes auf den bildschirm angezeigter lädt aber schon 3 cylinder ein, das hört man indem das laufwerk 3 mal *tack* macht.
aber irgendwie scheint die adressierung falsch zu sein.das image schreibe ich mit rawrite auf diskette (aber mit nem selbstgebastelten in c, mit read() / write())
vielleicht schreibt er es falsch auf diskette ??ist oben im code ein fehler ?
mfg
haMMer
-
Hi.
Ich gehe mal davon aus, dass das ein zusammenhaengender Datenblock sein sollte, der da eingelesen wird?
Aus Effizienzgruenden ist es normalerweise naemlich so, dass auf einem cyl. zunaechst alle discs/seiten (fuer jede Disc/Seite ein Head => siehe dh) beschrieben werden, bevor mit dem naechsten track angefangen wird.Ach ja, AFAIK waren es bei einer normalen Floppy auch noch 18Sectors per track...
-
ja, es ist ein einzelnes binary image. bootloader und kernel zusammengeklebt
rawrite:
die datei wird mit open() geöffnet, mit read() eingelesen und mit write() auf diskette geschrieben@seiten:
ich weiss nich genau wie du das jetzt meinst, aber ich habs so verstanden, dass mein rawrite (linux) jetz die ersten 18 sektoren auf head 0 beschreibt , dann den head wechselt und dort die nächsten 18 sektoren reinknallt, und dann erst auf den nächsten track springt.
(ich müsste dann im bootloader erst den head von 0 auf 1 wechseln bevor ich auf track 1 überspring ?)ich dachte er beschreibt erst alle 80 tracks auf einer seite und wechselt dann den head. war wohl nen denkfehler von mir..
wenn das so is, wirds wohl der fehler sein.
-
Hoi.
Ich hab mir vor einiger Zeit mal nen Bootsektor geschrieben der eine Binäre Datei (Kernel) von einer Diskette die FAT12 formatiert ist in den speicher lesen kann. Ich poste dir einfach mal den Code. Vielleicht kannst du damit was anfangen:
;####################################################################### ;BOOTSECTOR zum laden einer binären Kernel-Datei aus dem Root-Verzeichnis ;Copyright by TeeJay (masta_ace_inc@gmx.de) ;Bei Fragen oder Problemen einfach eine Mail schreiben ;Auf Anfrage gibts auch ein eigenes DEUTSCHES Tutorial zum Thema FAT12 ;####################################################################### ;INCLUDE_START %include "Macros16.asm" ;Hier sind Macors um die einzelnen lokalen Variablen und Parameter ;bequem ansprechen zu können ;Diese gelten aber nur für einen 16-Bit Stack!!! ;INCLUDE_END ;####################################################################### ;BOOTSECTOR_INFOBLOCK jmp BOOTINFOBLOCK_END OSName db "JAY-OS " BytesPerSec dw 512 SecPerClus db 1 ResvdSecCnt dw 1 NumFATs db 2 RootEntCnt dw 224 TotSec dw 2880 MediaType db 0xF0 FATSize dw 9 SecPerTrack dw 18 NumHeads dw 2 HiddenSec dd 0 TotSec32 dd 0 DrvNum db 0x00 Reserved db 0 BootSig db 0x29 VolumeID dd 1 VolumeLavel db "NO NAME " FileSysType db "FAT12 " BOOTINFOBLOCK_END: ;######################################################################## ;BOOTSECTOR_CODE_START org 0x7C00 ;Code-Start-Adresse auf 0x7C00 setzen cli ;Interruptflag löschen (keine Interrupts zulassen) mov ax, 0x9000 mov ss, ax ;Stacksegment auf AX(0x9000) setzen xor sp, sp ;Stackpointer auf 0 setzen sti ;Interruptflag setzen (Interrupts wieder zulassen) call func_FindFileSector ;Startsektor der Kerneldatei finden lassen (Rückgabe in AX) or ax, ax ;AX = 0? -> Datei nicht gefunden jz KernelNotFound ;Zur Ausgabe (File not found) springen call func_ReadFATTable ;FAT-Tabelle in den Speicher lesen lassen mov bx, 0x1000 ;Segmentadresse festlegen an die der Kernel geladen werden soll mov dx, [RootEntCnt] ;Startsektor der Datensektoren errechnen shl dx, 5 add dx, [BytesPerSec] dec dx shr dx, 9 add [Temp], dx ;Und das Ergebnis in Temp-Variable speichern LoadKernelFile: mov dx, [Temp] ;Startsektor der Datensektoren in DX schreiben add dx, ax ;Zum Startsektor der Datensektoren den Startsektor der Datei addieren dec dx ;DX um 2 verringern dec dx ;Zweimal "dec dx" braucht weniger Bytes als einmal "sub dx, 2" push bx ;Segmentadresse an die der Sektor gelesen werden soll auf den Stack pushen push dx ;Sektornummer die gelesen werden soll auf den Stack pushen call func_ReadSector ;Sektor lesen lassen add sp, 4 ;2 Parameter vom Stack löschen push ax ;FAT-Eintrag-Nummer auf den Stack pushen call func_ReadFATEntry ;Wert des FAT-Eintrags lesen (Rückgabe in AX) add sp, 2 ;1 Parameter vom Stack löschen cmp ax, 0xFFF ;Ist das der letzte FAT-Eintrag der Kernel-Datei? je ExecuteKernel ;Wenn Ja -> Springe zum Kernel add bx, 32 ;Segmentadresse um 32 erhöhen. Dort wird der nächste Sektor hingelesen jmp LoadKernelFile ;Springe wieder nach oben um nächsten Sektor der Kernel-Datei zu lesen ExecuteKernel: mov ax, 0x1000 push ax ;Segmentadresse an welcher der Kernel ist auf den Stack pushen mov ax, 0 push ax ;Offsetadresse des Kernels (0) auf den Stack pushen retf ;Einen FAR-Rücksprung zum Kernel machen KernelNotFound: push WORD MsgFileNotFound ;Offset der "File not Found" Meldung auf den Stack pushen call func_PrintString ;Meldung ausgeben lassen add sp, 2 ;1 Parameter vom Stack löschen WaitForKeyToReboot: mov ah, 0 ;Auf Tastendruck warten int 0x16 Reboot: db 0xEA ;Reboot dw 0x0000 dw 0xFFFF ;BOOTSECTOR_CODE_END ;######################################################################## ;DATABLOCK_START MsgFileNotFound db "File not found.",13,10,0 ;Meldung wenn kein Kernel gefunden wurde Filename db "KERNEL BIN" ;Dateiname des Kernels Temp dw 0 ;Tempvariable ;DATABLOCK_END ;######################################################################## ;FUNCTIONS_START ;------------------------------------------------------------------------ ;Funktion um einen NULL-Terminierten String auszugebens ;1. Paramtere: Offset an dem sich der String befindet func_PrintString: push bp ;BP sichern mov bp, sp ;Stackpointer in BP übertragen pusha ;Alle Register sichern mov si, [Param1] ;1. Parameter(Offset des Strings) nach SI kopieren mov ah, 0x0E ;Funktion zur Zeichenausgabe mov bx, 0x0007 ;Farbattribut des Zeichens .1: lodsb ;Zeichen von SI-Pointer nach AL kopieren und SI um 1 erhöhen or al, al ;AL = 0? String zu Ende? jz .2 ;Wenn JA -> Springe zum Ende int 0x10 ;Zeichen ausgeben lassen jmp .1 ;Wieder nach oben springen um nächstes Zeichen auszugeben .2: popa ;Register wiederherstellen mov sp, bp ;Stackpointer wieder in SP übertragen pop bp ;BP wiederherstellen ret ;Return ;------------------------------------------------------------------------ ;Funktion um den Startsektor der Kernel-Datei zu finden func_FindFileSector: push bp ;BP sichern mov bp, sp ;Stackpointer in BP übertragen sub sp, 2 ;Platz für eine lokale Variable auf dem Stack schaffen pusha ;Alle Register sichern mov ax, 0x9200 ;Segmentadresse festlegen an die ein Sektor zwischengespeichert wird mov es, ax mov ax, [FATSize] ;Startsektor des Root-Directorys errechnen mov bl, [NumFATs] mul bl add ax, [ResvdSecCnt] mov [Temp], ax ;Startsektor des Root-Directorys in Temp-Variable speichern xor dx, dx ;DX auf 0 setzen (Braucht weniger Bytes als "mov dx, 0") .E: cmp dx, [RootEntCnt] ;Wurden schon alle Root-Dir-Einträge durchsucht? je .A ;Wenn JA -> Datei nicht gefunden test dx, 15 ;DX durch 16 ohne Rest teilbar? jnz .B ;Wenn JA -> Nächsten Sektor lesen push es ;Segmentadresse für zwischenspeichern eines Sektors auf Stack pushen push ax ;Sektornummer auf Stack pushen call func_ReadSector ;Sektor lesen lassen add sp, 4 ;2 Parameter vom Stack löschen inc ax ;AX um 1 erhöhen (Braucht weniger Bytes als "add ax, 1") xor bx, bx ;BX auf 0 setzen (Braucht weniger Bytes als "mov bx, 0") .B: ;Wenn DX NICHT durch 32 OHNE Rest teilbar ist, fahre HIER fort cmp BYTE [es:bx], 0x0E ;Erstes Zeichen des Root-Dir-Eintrags = 0x0E? je .D ;Wenn JA -> Nächsten Eintrag lesen cmp BYTE [es:bx], 0 ;Erstes Zeichen des Root-Dir-Eintrags = 0? je .A ;Wenn JA -> Keine weiteren Einträge mehr. Datei nicht gefunden mov si, Filename ;Offset des Dateinamens nach SI kopieren mov di, bx ;Offset des Root-Dir-Eintrags nach DI kopieren mov cx, 11 ;11 Zeichen sollen verglichen werden repe cmpsb ;Solange vergleichen bis CX = 0 oder ungleiche Zeichen or cx, cx ;CX = 0? jz .C ;Wenn JA -> Alle Zeichen stimmen überein. Datei gefunden .D: inc dx ;DX um 1 erhöhen add bx, 32 ;BX um 32 erhöhen (Offset des nächsten Root-Dir-Eintrags) jmp .E ;Wieder nach oben springen um nächsten Eintrag zu vergleichen .A: ;Wenn die NICHT Datei gefunden wurde, HIER fortfahren popa ;Alle Register wiederherstellen xor ax, ax ;AX auf 0 setzen (Braucht weniger Bytes als "mov ax, 0") jmp .Ende ;Zum Ende Springen .C: ;Wenn die Datei gefunden wurde, HIER fortfahren push WORD [es:bx+26] ;Startsektornummer der Datei auf den Stack pushen pop WORD [Var1] ;Startsektornummer in lokale Variable popen popa ;Alle Register wiederherstellen mov ax, [Var1] ;Startsektornummer der Datei nach AX kopieren .Ende: mov sp, bp ;Stackpointer in SP übertragen pop bp ;BP wiederherstellen ret ;Return ;------------------------------------------------------------------------ ;Funktion um einen Sektor zu lesen ;1. Parameter: Logische Sektornummer des Sektors welcher gelesen werden soll ;2. Parameter: Segmentadresse an die der Sektor gespeichert werden soll func_ReadSector: push bp ;BP sichern mov bp, sp ;Stackpointer in BP übertragen sub sp, 6 ;Platz für 3 lokale Variablen auf dem Stack schaffen pusha ;Alle Register sichern ;Aus Logischer Sektornummer die CHS Adresse errechnen mov ax, [Param1] ;Aus logischer Sektornummer den Cylinder errechnen mov bx, 36 mov dx, 0 div bx mov [Var1], ax mov ax, dx ;Aus logischer Sektornummer den Head errechnen push ax mov bx, 18 mov dx, 0 div bx mov [Var2], ax pop ax ;Aus logischer Sektornummer den Sektor errechnen mov dx, 0 div bx mov ax, dx add ax, 1 mov [Var3], ax .1: mov ax, [Param2] ;Segmentadresse zum speichern des Sektors festlegen mov es, ax mov bx, 0 ;Offset zum speichern des Sektors festlegen mov ah, 2 ;Funktion zum Sektorlesen mov al, 1 ;1 Sektor soll gelesen werden mov ch, [Var1] ;Angabe des Cylinders an dem der Sektor gelesen werden soll mov cl, [Var3] ;Angabe des Sektors an dem der Sektor gelesen werden soll mov dh, [Var2] ;Angabe des Heads an dem der Sektor gelesen werden soll mov dl, 0 ;Von Laufwerk A: lesen int 0x13 ;Sektor lesen lassen jc .1 ;Bei Fehler nochmal versuchen popa ;Alle Register wiederherstellen mov sp, bp ;Stackpointer in SP übertragen pop bp ;BP wiederherstellen ret ;Return ;------------------------------------------------------------------------ ;Funktion um einen FAT-Eintrag zu lesen ;1. Parameter: Nummer des Eintrags der gelesen werden soll ;In AX wird der Wert des gelesenen FAT-Eintrag zurückgegeben func_ReadFATEntry: push bp ;BP sichern mov bp, sp ;Stackpointer in BP übertragen sub sp, 2 ;Platz für eine lokale Variable auf dem Stack schaffen pusha ;Alle Register sichern mov ax, [Param1] ;Offset errechnen an dem sich der FAT-Eintrag im Speicher befindet mov bx, 3 mul bx mov bx, 2 xor dx, dx div bx mov bx, 0x9200 ;Segmentadresse angeben an der die FAT-Tabelle im Speicher liegt mov es, bx mov bx, ax mov ax, [es:bx] mov [Var1], ax ;FAT-Eintrag (16 Bit) in lokale Variable speichern mov cx, [Param1] ;Testen ob der zu lesende FAT-Eintrag gerade oder ungerade ist test cx, 1 jz .Gerade ;Wenn GERDADE -> Springe ;Wenn der zu lesende FAT-Eintrag UNGERADE ist, HIER fortfahren popa ;Alle Register wiederherstellen mov ax, [Var1] shr ax, 4 ;FAT-Eintrag(12 Bits) aus den 16 Bits extrahieren jmp .Ende .Gerade: ;Wenn der zu lesende FAT-Eintrag GERADE ist, HIER fortfahren popa ;Alle Register wiederherstellen mov ax, [Var1] and ax, 0xFFF ;FAT-Eintrag(12 Bits) aus den 16 Bits extrahieren .Ende: mov sp, bp ;Stackpointer in SP übertragen pop bp ;BP wiederherstellen ret ;Return ;------------------------------------------------------------------------ ;Funktion zum einlesen der FAT-Tabelle in den Speicher func_ReadFATTable: pusha ;Alle Register sichern mov bx, 0x9200 ;Segmentadresse festelegen an welche die FAT-Tabelle gelesen werden soll mov ax, [ResvdSecCnt] ;Startsektor der FAT-Tabelle eintragen mov cx, [FATSize] ;Anzahl der FAT-Tabellen-Sektoren eintragen .A: push bx ;Segmentadresse auf den Stack pushen push ax ;Sektornummer auf den Stack pushen call func_ReadSector ;Sektor lesen lassen add sp, 4 ;2 Parameter vom Stack löschen inc ax ;Nächsten Sektor auswählen add bx, 32 ;Segmentadresse um 32 erhöhen (Dort wird nächster Sektor gespeichert) loop .A ;Solange wiederholen bis alle Sektoren gelesen wurden popa ;Alle Register wiederherstellen ret ;Return ;------------------------------------------------------------------------ ;FUNCTIONS_END ;######################################################################## times 512-($-$$)-2 db 0 ;Den Rest des Bootsektors mit Nullen Füllen dw 0AA55h ;0xAA55 am Ende des Bootsektors schreiben
Hier noch die Macros:
;#######################################################
;Macros für den einfachen Zugriff auf die über den Stack übergebenen Parameter
;ACHTUNG! Diese Macros sind nur bei einem 16-Bit Stack korrekt!%define Param1 bp+4
%define Param2 bp+6
%define Param3 bp+8
%define Param4 bp+10
%define Param5 bp+12;#######################################################
;Macros für den einfachen Zugriff auf lokale Variablen innerhalb einer Funktion
;die auf dem Stack erstellt wurden
;ACHTUNG! Diese Macros sind nur bei einem 16-Bit Stack korrekt!%define Var1 bp-2
%define Var2 bp-4
%define Var3 bp-6
%define Var4 bp-8
%define Var5 bp-10;#######################################################
-
jesus! ...
die funktion readsector hätte ausgereicht.. aber trotzdem dankebei mir gehts jetz,
habs so ähnlich gemacht wie du, mit einer sog. logischen sektornummer..mfg
haMMer