Autor Thema: FAT Dateiadressierung  (Gelesen 13611 mal)

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« am: 22. November 2010, 18:31 »
Hallo zusammen,
ich habe ein Problem mit der FAT12 Dateiadressierung. Das Image und der Hexdump ist wie immer unter http://sesdll1.se.funpic.de/lowlevel/floppy.img bzw. http://sesdll1.se.funpic.de/lowlevel/floppy.img.hex zu finden. Hier der wichtigste Teil:
Zitat
00002620  54 4d 50 30 20 20 20 20  54 58 54 20 00 64 43 6b
00002630  73 3d 73 3d 00 00 43 6b  73 3d 03 00 06 00 00 00
Es handelt sich um die erste Datei. Der Hexdump sagt mir, dass die Datei am fett hinterlegtem Cluster 0x0300 beginnt. Weil bei FAT12 ein Cluster einem Sektor entspricht, und weil bei einer Floppy (zumindest so wie ich meine formatiert habe) ein Sektor 512 byte (=0x200) groß ist, sollte die Datei bei 0x300*0x200 = 0x60000 liegen. Laut Hexdump liegt die Datei aber schon bei 0x4400 byte bzw. Sektor 0x22.
Wie kann ich jetzt aus dem Cluster des Hexdumps (=0x300) den Sektor nach LBA berechnen?

Spaceemotion

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #1 am: 22. November 2010, 19:40 »
Ich glaube, ich habe die Lösung selber gefunden: Der Cluster bezieht sich schließlich auf den Eintrag in der FAT  :-D

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 22. November 2010, 19:41 »
Wenn ich mich grad nicht sehr irre, ist FAT Little Endian. Dein "03 00" ist also nicht 0x0300, sondern 0x0003.

Und die Datencluster fangen nicht vorne an, sondern an einem Offset, das im BPB steht. Und von Clusternummern muss zumindest manchmal noch 2 abgezogen werden. Ich weiß nicht, was für ein Ausschnitt das ist, den du hier reinkopiert hast - ein Verzeichniseintrag?
« Letzte Änderung: 22. November 2010, 19:43 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #3 am: 22. November 2010, 20:49 »
Das klärt für mich vieles auf. Was ich euch gepostet habe, war ein Eintrag in die Root Directory. Wie benutze ich den einen Little Endian in C?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 22. November 2010, 21:56 »
x86-Prozessoren arbeiten auch mit Little Endian, du brauchst also gar nichts besonderes zu machen, sondern musst einfach nur einen uint16_t* darauf zeigen lassen und den auslesen. Das kannst du dir auch schonmal merken, falls du dir den RAM irgendwann mal byteweise dumpen lässt. Dann musst du auch "falschrum" lesen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Programm Noob

  • Gast
Gespeichert
« Antwort #5 am: 22. November 2010, 23:14 »
Das hat mich bei meinemDisassembler zwischenzeitlich fast um den Verstand gebracht.

PNoob

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #6 am: 23. November 2010, 19:33 »
x86-Prozessoren arbeiten auch mit Little Endian, du brauchst also gar nichts besonderes zu machen, sondern musst einfach nur einen uint16_t* darauf zeigen lassen und den auslesen. Das kannst du dir auch schonmal merken, falls du dir den RAM irgendwann mal byteweise dumpen lässt. Dann musst du auch "falschrum" lesen.
Gut, muss ich jetzt also schreiben?
uint16_t x = ...; //Clusternummer laut Root directory
uint16_t *p = &x;
//Und in *p ist jetzt die Variable, wie ich sie brauche?
Also, das ist definitiv falsch. Ich glaube ich habe dich nicht ganz verstanden, taljeth.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 23. November 2010, 20:26 »
Naja, deine Variante ist schon richtig, wenn am Anfang die richtige Clusternummer hast. Dein Code ändert an der Nummer nämlich überhaupt nichts, also ist sie hinterher immer noch richtig. Aber ich glaube, dein Problem war, wie du die richtige Nummer am Anfang kriegst. ;)

uint8_t buf[GANZVIEL];
uint16_t* cluster_number;

read(disk, buf, GANZVIEL);
cluster_number = &buf[offset_von_der_cluster_nummer_im_rootdir];
Eher irgendwie so. In Wirklichkeit willst du da natürlich eine struct dir_entry über den ganzen Verzeichniseintrag drüberlegen und nicht einzelne 16-Bit-Werte abgreifen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #8 am: 24. November 2010, 16:17 »
Funktioniert bei mir leider nicht.  :cry:
Folgende Situation:
const int sysbuffer = 0x1000; //Fuer DMA notwendig
#define GANZVIEL 224*0x20
...
kmemset((void*) sysbuffer, 0x0, 0x2400); //Systembuffer loeschen
readSector(19); // start at 0x2600: root directory (14 sectors)

uint8_t buf[GANZVIEL];
kmemcpy( (void *) buf, (void *) sysbuffer, GANZVIEL);
akfile->clusterID = (uint16_t*) &buf[0x20*i + 0x1A];
...
So wie ich das jetzt habe, funktioniert es nicht. Ich habe jetzt Werte wie 0x22FA statt 0x3 bzw. vom FAT 0x0300. Wie hängt das alles zusammen?

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #9 am: 24. November 2010, 17:36 »
Also die Konvertierung zwischen dem, was die FAT mir gibt, und dem, was ich brauche, hab ich jetzt:
akfile->clusterID = ( akfile->clusterID >> 8 ) | ( (akfile->clusterID & 0xF0)  ) | ( (akfile->clusterID & 0xF)  << 8 ) ;

Die Zahl steht in akfile->clusterID drin. Beispiel:
akfile->clusterID = 0x345;
akfile->clusterID = ( akfile->clusterID >> 8 ) | ( (akfile->clusterID & 0xF0)  ) | ( (akfile->clusterID & 0xF)  << 8 ) ;
//                =   0x003                    |     0x04                        | (   0x005                    << 8 ) ;
//                =   0x003                    |     0x04                        |     0x500                           ;
//                =   0x543                                                                                            ;

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #10 am: 25. November 2010, 14:27 »
Gut, jetzt habe ich zwar den richtigen FAT Eintrag. Der ist für die erset Datei laut hexdump 0xF0F. Ich glaube ich muss den EIntrag mit 2 subtrahieren. Also habe ich 0xF0D. Wie komme ich jetzt von 0xF0D bzw. 0xF0F auf die Dateiadresse 0x0004400?
Danke

Programm Noob

  • Gast
Gespeichert
« Antwort #11 am: 25. November 2010, 19:08 »
kannst du etwas genauer erklären, woher du jetzt diese Werte hast. Ich verstehe den Zusammenhang zwischen deinen Werten nicht.

PNoob

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #12 am: 26. November 2010, 15:23 »
Also: Ich habe ein FAT-12 Floppy Image ( http://sesdll1.se.funpic.de/lowlevel/fdc/floppy.img ). Der Hexdump liegt unter http://sesdll1.se.funpic.de/lowlevel/fdc/floppy.hex. Wir wollen jetzt erstmal nur Datei 1 ("TEST1.TXT") betrachten:
  • Laut hexdump, beginnt die Datei bei Cluster 0x0300. Also (weil in der Rootdirectory der Cluster als Little Endian steht) beginnt die Datei 0x1.
  • Im ersten (0x1) FAT Eintrag steht: 0xF0F.
  • Die Datei beginnt tatsächlich bei dem Byte 0x4400, also bei Cluster (bzw. Sektor) 0x22.
Wie komme ich jetzt von dem FAT-Eintrag (0xF0F) auf den Cluster (0x22)?

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 26. November 2010, 16:09 »
Hallo,


Wie komme ich jetzt von dem FAT-Eintrag (0xF0F) auf den Cluster (0x22)?
Du ließt den falschen FAT-Eintrag aus. Wenn Du auf die FAT zugreifst musst Du immer die echte Cluster-Nummer (die im Directory-Eintrag steht und bei Cluster-Ketten auch in der FAT selber benutzt wird) nehmen aber wenn Du den Sektor ausrechnen möchtest in dem der Cluster liegt dann musst Du vorher von der Cluster-Nummer 2 abziehen. Die beiden ersten Einträge in der FAT sind für spezielle Werte reserviert (keine Ahnung ob die irgendeine Bedeutung haben) also es wird niemals ein Cluster 0 oder Cluster 1 benutzt. Die Cluster 0 und 1 existieren auch nicht im Datenbereich (deswegen die Subtraktion mit 2). Das ist ein klein wenig verwirrend, am besten Du ließt Dir mal die Spezifikationen zur FAT durch (gibt es bei MS) und auch den Wikipedia-Artikel.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #14 am: 26. November 2010, 17:00 »
Super! Vielen Dank, aber: Jetzt habe ich 0x00F (=15). Was bedeutet das jetzt? Ist das der Startsektor? Der ist aber 0x22 (=36). Gibt es eine Verschiebung oder wie kann ich jetzt den Startsektor 0x22 berechnen?

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 27. November 2010, 10:19 »
Hallo,


Jetzt habe ich 0x00F (=15). Was bedeutet das jetzt?
Hm, keine Ahnung. Leider hat meine Kristallkugel ihr freies Wochenende. Wenn ich raten müsste würde ich denken die 15 bedeutet das Du 15 lose Hosenknöpfe gezählt hast aber sicher bin ich mir da auch nicht.

Ist das der Startsektor?
Das hängt davon ab wo Du diese Zahl her hast. Falls ich mit den Hosenknöpfen richtig geraten habe würde ich Dir empfehlen zu Nadel und Faden zu greifen um die Hosenknöpfe an die richtige Stelle zu installieren. ;)

Hast Du Dir den mal die FAT-Spezifikation gezogen und vor allem auch gelesen? Oder den Wiki-Artikel? Wenn nein dann solltest Du das ganz schnell nachholen.


SCNR
Erik
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 27. November 2010, 12:51 »
Die FAT-Spec anzuschauen ist unter Umständen rechtlich problematisch, wenn du kein EFI schreibst, weil dort ausdrücklich Beschränkungen stehen, wofür man sie benutzen darf. Ich habe vorsichtshalber bei meinem FAT-Treiber darauf verzichtet.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Programm Noob

  • Gast
Gespeichert
« Antwort #17 am: 27. November 2010, 12:55 »
kann doch am ende keiner Nachweisen wo du die Infos herhast oder?

PNoob

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 27. November 2010, 14:22 »
Hallo,


Die FAT-Spec anzuschauen ist unter Umständen rechtlich problematisch....
Es geht um ein Button den man drücken muss bevor man die Spezifikation runterladen kann, glaubst Du das ist nach deutschem Recht ein verbindlicher Vertrag? Oder glaubst Du das MS (bzw. die deutsche Polizei) Deine Computer beschlagnahmen wird um festzustellen ob Du das Wissen was man für einen FAT-Treiber braucht (welches man im iNetz 1000fach findet) ausgerechnet aus deren Spezifikation gezogen hast? Nimm es mir nicht übel aber dafür sind selbst größere Hobby-OSe nicht relevant genug als das sich MS diese aussichtslose Mühe macht (mal von den Negativ-Schlagzeilen ganz abgesehen). Mit Patenten kann MS Dir auch kaum kommen da diese sich nur auf die Implementierung von langen Dateinamen beziehen (was glaubst Du warum die Fotoapparate ihre Bilder als BILD0815.JPG benennen) und selbst gegen Linux ist da nie was unternommen worden obwohl Linux die langen Dateinamen spezifikationsgerecht implementiert und damit IMHO gegen geltendes Patentrecht verstößt.

Wenn Du Dich wegen der gespeicherten IP unwohl fühlst dann nimm einfach ein Anonymisierungsproxy (das hab ich auch gemacht).


Zum Thema:
vielleicht sollte in den Wiki-Artikel noch die Formel rein wie man aus der Cluster-Nummer (die in den Verzeichniseinträgen und in der FAT selber benutzt werden) auf die Sektor-Nummer kommt. Wenn ich heute Abend noch etwas Zeit finde mache ich das auch gerne.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 27. November 2010, 14:52 »
Super! Vielen Dank, aber: Jetzt habe ich 0x00F (=15). Was bedeutet das jetzt? Ist das der Startsektor? Der ist aber 0x22 (=36). Gibt es eine Verschiebung oder wie kann ich jetzt den Startsektor 0x22 berechnen?
Man fängt immer bei 0 an zu zählen.
Also komme ich für Cluster 3(test1.txt) auf 0xfff und für Cluster 4(test2.txt) auch auf 0xfff.

Aus den Einträgen 0x11 0x21 0x22 bekommt  man 2 Cluster: 0x111 und 0x222.


Was die Einträge in der FAT bedeuten darfst du selbst nach lesen. www.lowlevel.eu wiki.osdev.org de.wikipedia.org
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

 

Einloggen