Autor Thema: Direkter Zugriff auf Laufwerke?  (Gelesen 13052 mal)

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« am: 12. February 2008, 20:12 »
Hi,
ich habe mal begonnen ein kleines fdisk Programm für LOST zu schreiben. Allerdings stehe ich jetzt vor dem Problem, dass ich einzelne Sektoren direkt lesen muss und keine Ahnung hab, wie man das bewerkstelligen soll. Meine Idee war, das so zu machen:
FILE *dev = fopen("ata:/ata00", "r");
if(dev == 0)
{
printf("Could not open device\n");
return 1;
}
fread(MBR, 1, 512, dev);
fclose(dev);
Allerdings funktioniert das wohl nicht. Es gibt keine Fehlermeldung, aber die eingelesenen Daten stimmen nicht.
Daher meine Frage: Wie löse ich das am elegantesten unter LOST? Oder hab ich nur irgendwas übersehen?

Und noch eine Frage gleich hinterher: Was ist eigentlich für die libs noch geplant in absehbarer Zeit? Etliche Funktionen scheinen ja noch nicht richtig zu funktionieren. Hat das momentan Priorität, oder liegt der Schwerpunkt woanders?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 12. February 2008, 20:16 »
Daher meine Frage: Wie löse ich das am elegantesten unter LOST? Oder hab ich nur irgendwas übersehen?
Der ATA-Treiber ist von Freaky, daher kann ich nur eine zweite externe Meinung bieten: Ich denke, genau so sollte es funktionieren. Jedenfalls, wenn der Dateiname stimmt, ich habe das noch nie benutzt. ;)

Zitat
Und noch eine Frage gleich hinterher: Was ist eigentlich für die libs noch geplant in absehbarer Zeit? Etliche Funktionen scheinen ja noch nicht richtig zu funktionieren. Hat das momentan Priorität, oder liegt der Schwerpunkt woanders?
Die Libs werden halt nach und nach geschrieben, wie sie für Programme gebraucht werden. gcc war wohl ganz gut dafür geeignet, einige Funktionen aufzudecken, die noch geändert werden müssen. Der Schwerpunkt liegt also momentan eher bei den Anwendungen, die Libs kommen dann automatisch mit.
« Letzte Änderung: 12. February 2008, 20:19 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #2 am: 12. February 2008, 20:18 »
Freut uns das zu hören  :-D

Wo hast du denn das Programm so getestet? In qemu tut es garantiert. Und ich habe bei mir auch schon auf mehreren Rechnern getestet, ata funktioniert dort eigentlich auch.

Dein Ansatz ist schon der richtige. :)

Naja die stdlibc wird halt einfach vervollständigt, sobald man was braucht. Die wichtigsten Funktionen sind mittlerweile schon implementiert. Zumindest gcc und binutils lassen sich schon mal mit unserer Libc kompilieren und linken.

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 12. February 2008, 21:42 »
Ich hab jetzt nochmal ein kleines Testprogramm geschrieben. Hier der Code:
#include "stdio.h"
#define _USE_START_
#include "init.h"

int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("Please add a filename\n");
return 0;
}

printf("Opening %s\n", argv[1]);
FILE *dev = fopen(argv[1], "r");
if(dev == 0)
{
printf("Could not open device!");
return 1;
}
unsigned char buffer[512];
fread(buffer, 1, 512, dev);
fclose(dev);

int i;
for(i=0;i<16;i++)
{
printf("%x ", buffer[i]);
}
printf("\n");

return 0;
}

Getestet habe ich das mit Qemu und dieser Commandline:
qemu -boot a -fda build/lost.img -hda build/hdd.img
hdd.img ist einfach eine 20MB große Datei, die nur aus 0-Bytes besteht. Und das Programm selbst rufe ich so auf:
cd apps
test ata:/ata00

Der Output ist dann
Zitat
Opening ata:/ata00
8c 72 0 40 c0 f1 ff ff da 15 0 40 34 70 0 40

Wenn ich das Programm mit ata:/atapi10 als Parameter aufrufe, gibts ne unbehandelte Ausnahme.
Was auch komisch ist ist, dass es im Programm wohl ein größeres Memory Leak gibt...

Vielleicht liegt das Problem ja auch beim Laden vom ATA Modul. Ich hab in die default.cfg jetzt einfach diese Zeile hinzugefügt:
module /ata.mgz

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #4 am: 12. February 2008, 22:25 »
Hm sehr gesund sieht das nicht aus. Könntest du mal prüfen, wie der Rückgabewert von fread aussieht?

Im Moment habe ich noch nicht wirklich eine Idee, woran das liegen könnte...

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 13. February 2008, 15:03 »
fread gibt 0 zurück, das würde ja schonmal erklären warum da scheinbar zufällige Daten im buffer stehen. ferror gibt aber auch 0 zurück...
Aber ich hab noch ne neue Erkenntnis: Bevor die Shell gestartet wird, weden ja die Module geladen und die Meldungen konnte ich bisher nicht lesen, weil
das relativ chaotisch und schnell abläuft. Naja, ich hab jetzt ein Video davon gemacht und einfach langsamer abgespielt ;) Das hier könnte also noch interessant sein:
Zitat
[...]
ata: pio_in unerwarteter Status: 0x0
ata: pio_in unerwarteter Status: 0x0
[...]
Bus 0  Device 0: ATAPI=0
ata: Fehler beim Verarbeiten der Partitionstabelleata: pio_in unerwarteter Status: 0x0
ata: pio_in unerwarteter Status: 0x0
ata: pio_in unerwarteter Status: 0x0
Bus 1  Device 0: ATAPI=1
[...]
Hoffe, das hilft.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 13. February 2008, 15:11 »
Erwartet ata womöglich, daß die Platte partitioniert sein muß?

Aber um dir für die Zukunft das Aufnehmen von Videos zu ersparen: Benutz einfach -serial stdio, die Ausgaben kommen nämlich auch alle auf der seriellen Schnittstelle raus. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #7 am: 13. February 2008, 15:27 »
Nein, erwartet es eigentlich nicht.

Diese ausgaben sehen gesund aus. Die Meldungen wegen dem unerwarteten Status sind auch in Ordung. Das sind Debugausgaben beim suchen der angeschlossenen Geräte. Und die erkennt er ja scheinbar auch richtig.
Die Fehlermeldung wegen der Partitionstabelle sieht eigentlich auch gut aus, weil es existiert ja auch keine und somit ist die Signatur der Tabelle nicht in ordnung. Darum wird das Erkennen der Partitionen abgebrochen. Das sollte aber eigentlich nichts daran ändern, dass die Festplatte als ganzes angesprochen werden kann... :?

Was geschieht denn wenn du ein cat ata:/ata00 machst?

Edit:
Wie gross ist denn dein Image? Und welche qemu-Version benutzt du?
« Letzte Änderung: 13. February 2008, 15:31 von FreakyPenguin »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 13. February 2008, 15:35 »
Was geschieht denn wenn du ein cat ata:/ata00 machst?
Wäre ein bincat nicht sinnvoller?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #9 am: 13. February 2008, 15:39 »
Hm ist eigentlich egal. Kommt ja eh beiden Orten Mist raus. Aber die Hauptsache ist ja dass das rauskommt. :D

Ich habe hier einen Kleinen Patch fuer ein paar Debugausgaben in ata:
Index: src/modules/cdi/ata/device.c
===================================================================
--- src/modules/cdi/ata/device.c        (Revision 703)
+++ src/modules/cdi/ata/device.c        (Arbeitskopie)
@@ -79,7 +79,7 @@
  *
  * @return 1 wenn ein Geraet vorhanden ist, 0 sonst
  */
-static bool ata_bus_responsive_drv(struct ata_controller* controller)
+static int ata_bus_responsive_drv(struct ata_controller* controller)
 {
     // Slave auswaehlen, da so sicher jemand reagiert, da der Master antworten
     // muss, wenn kein Slave existiert. So sieht es zumindest in der Theorie
@@ -341,13 +341,18 @@

     // Natuerlich nur ausfuehren wenn ein Handler eingetragen ist
     if (dev->read_sectors == NULL) {
+        printf("ata: Handler zum lesen von Sektoren nicht eingetragen\n");
         return -1;
     }

     // Bei einer Partition noch den Offset dazurechnen
     if (partition == NULL) {
+        printf("ata: Nicht partitioniert\n");
+        printf("ata: Lese %lld Sektoren von %lld an\n", count, block);
         return !dev->read_sectors(dev, block, count, buffer);
     } else {
+        printf("ata: Partitioniert\n");
+        printf("ata: Lese %lld Sektoren von %lld an\n", count, block);
         return !dev->read_sectors(dev, block + partition->start, count,
             buffer);
     }
Index: src/modules/cdi/ata/ata.c
===================================================================
--- src/modules/cdi/ata/ata.c   (Revision 703)
+++ src/modules/cdi/ata/ata.c   (Arbeitskopie)
@@ -248,10 +248,17 @@
         dev->storage.block_count = id.max_lba48_address;
     }
     if (id.capabilities.lba) {
+        printf("ata: Laufwerk unterstuetzt LBA28\n");
         dev->lba28 = 1;
         if (!dev->lba48) {
+            printf("ata: Laufwerk unterstuetzt LBA48 nicht\n");
             dev->storage.block_count = id.lba_sector_count;
+            printf("ata: Laufwerk hat %lld Sektoren\n", dev->storage.block_count);
+        } else {
+            printf("ata: Laufwerk unterstuetzt LBA48\n");
         }
+    } else {
+        printf("ata: Laufwerk unterstuetzt LBA28 nicht\n");
     }

     // Wenn keiner der LBA-Modi unterstuetzt wird, muss abgebrochen werden, da
@@ -350,7 +357,7 @@
         count_left -= current_count;
         lba += current_count;
     }
-
+    printf("ata: Read result: %d\n", result);
     return result;
 }


DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 13. February 2008, 15:43 »
Aber um dir für die Zukunft das Aufnehmen von Videos zu ersparen: Benutz einfach -serial stdio, die Ausgaben kommen nämlich auch alle auf der seriellen Schnittstelle raus. ;)
Gut danke. :-D

Weder cat noch bincat bringen irgendeinen Output. Das Image ist wie gesagt 20MB groß, Qemu Version ist 0.9.1

--EDIT--
Zitat
ata: pio_in unerwarteter Status: 0x0
ata: pio_in unerwarteter Status: 0x0
ata: Laufwerk unterstuetzt LBA28
ata: Laufwerk unterstuetzt LBA48
Bus 0  Device 0: ATAPI=0
ata: Read result: 1
ata: Fehler beim Verarbeiten der Partitionstabelleata: pio_in unerwarteter Status: 0x0
ata: pio_in unerwarteter Status: 0x0
ata: pio_in unerwarteter Status: 0x41
Bus 1  Device 0: ATAPI=1
« Letzte Änderung: 13. February 2008, 15:53 von DarkThing »

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #11 am: 13. February 2008, 16:05 »
Ah das erklärt das natürlich. Qemu ist auch 0xd00f. Warum aktiviert der bei diesem Laufwerk auch LBA48... ;-)
Na dann versuchen wirs mal mit ignorieren. Solange du es nicht übertreibst mit der Imagegrösse müsste das eigentlich gehen. ;-)
Ich überlege mir dann mal, das ganze sauber zu implementieren, mit LBA48.

Versuch es mal mit diesem Patch.
Index: src/modules/cdi/ata/device.c
===================================================================
--- src/modules/cdi/ata/device.c        (Revision 703)
+++ src/modules/cdi/ata/device.c        (Arbeitskopie)
@@ -79,7 +79,7 @@
  *
  * @return 1 wenn ein Geraet vorhanden ist, 0 sonst
  */
-static bool ata_bus_responsive_drv(struct ata_controller* controller)
+static int ata_bus_responsive_drv(struct ata_controller* controller)
 {
     // Slave auswaehlen, da so sicher jemand reagiert, da der Master antworten
     // muss, wenn kein Slave existiert. So sieht es zumindest in der Theorie
@@ -341,13 +341,18 @@

     // Natuerlich nur ausfuehren wenn ein Handler eingetragen ist
     if (dev->read_sectors == NULL) {
+        printf("ata: Handler zum lesen von Sektoren nicht eingetragen\n");
         return -1;
     }

     // Bei einer Partition noch den Offset dazurechnen
     if (partition == NULL) {
+        printf("ata: Nicht partitioniert\n");
+        printf("ata: Lese %lld Sektoren von %lld an\n", count, block);
         return !dev->read_sectors(dev, block, count, buffer);
     } else {
+        printf("ata: Partitioniert\n");
+        printf("ata: Lese %lld Sektoren von %lld an\n", count, block);
         return !dev->read_sectors(dev, block + partition->start, count,
             buffer);
     }
Index: src/modules/cdi/ata/ata.c
===================================================================
--- src/modules/cdi/ata/ata.c   (Revision 703)
+++ src/modules/cdi/ata/ata.c   (Arbeitskopie)
@@ -248,10 +248,17 @@
         dev->storage.block_count = id.max_lba48_address;
     }
     if (id.capabilities.lba) {
+        printf("ata: Laufwerk unterstuetzt LBA28\n");
         dev->lba28 = 1;
-        if (!dev->lba48) {
+        //if (!dev->lba48) {
+        //    printf("ata: Laufwerk unterstuetzt LBA48 nicht\n");
             dev->storage.block_count = id.lba_sector_count;
-        }
+            printf("ata: Laufwerk hat %lld Sektoren\n", dev->storage.block_count);
+        /*} else {
+            printf("ata: Laufwerk unterstuetzt LBA48\n");
+        }*/
+    } else {
+        printf("ata: Laufwerk unterstuetzt LBA28 nicht\n");
     }

     // Wenn keiner der LBA-Modi unterstuetzt wird, muss abgebrochen werden, da
@@ -350,7 +357,7 @@
         count_left -= current_count;
         lba += current_count;
     }
-
+    printf("ata: Read result: %d\n", result);
     return result;
 }


DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 13. February 2008, 16:21 »
Yeah, funktioniert!  :-)

 

Einloggen