zurück

ext2 Dateisystem-Treiber

Vor einiger Zeit wollte ich in einem Projekt eine SD-Karte zum Abrufen und Speichern von Daten nutzen. Es gab damals bereits etliche Implementierungen für das FAT-Dateisystem, allerdings wollte ich dieses einfach nicht benutzen, sondern viel lieber ein neues Dateisystem verwenden. Meine Wahl fiel dabei auf das EXT-Dateisystem, da ich gerade sehr viel über den Release von EXT4 [1] gelesen hatte, allerdings entschied ich mich bereits damals den Aufwand möglichst gering zu halten, indem ich mich (1) auf EXT2 [2] beschränkten wollte, da dieses weniger Features bereitstellt und daher einfacher zu implementieren sein sollte und (2) zunächst lediglich einen Read-Only-Zugriff realisieren wollte.
Die Anzahl an Informationen über die Arbeitsweise und den Aufbau des Dateisystems ist im Grunde nicht sehr groß, da es zwar einige Ressourcen im Web gibt (z.B. [3]), diese aber oft nicht alle Fragen beantworten. Glücklicherweise ist der Quellcode des EXT2-Dateisystems jedoch OpenSource, da er Bestandteil des Linux-Kernels [4] ist. Hier kann man nach Herzenslust stöbern und nahezu alle Fragen beantwortet bekommen. Der Quellcode ist insbesondere dann nützlich, wenn andere Informationsquellen widersprüchliche Informationen liefern, welche sich auch durch ausprobieren an realen Daten klären lassen!
Nach einigen Wochen habe ich das Proejkt jedoch damals auf Eis gelegt, da ich an einigen Punkten nicht weitergekommen bin und mir auch die Zeit dazu fehlte diese Probleme näher zu beleuchten.

Nun hatte ich mich wieder entschieden die Arbeit an einem EXT2-Dateisystemtreiber wieder aufzunehmen um diesen (endlich) fertig zu stellen. Hierzu habe ich den Treiber vollständig neu geschrieben, da mir dies einfacher schien als mich im alten Code zurecht zu finden. Des Weiteren konnte ich somit einige Schwächen im vorherigen Code umgehen. Die Entwicklungszeit war diesmal auch erheblich kürzer, da ich für die Arbeit von fast zwei Monaten in diesem Anlauf lediglich eine Woche benötigte.
Das Ergebnis der Arbeit ist nun, dass ein vollständiger Read-Only-Zugriff auf ein EXT2-Dateisystem möglich ist. In der Praxis hat sich jedoch gezeigt, dass bei zu großen Partitionen (Partition mit 4 GB hat noch funktioniert) Probleme beim Lesen der Sektoren/Blöcke aufgetreten sind. Hierbei ist mir jedoch noch nicht endgültig klar, ob es an Problemen mit der Adressweite beim Speicherzugriff auf die SD-Karte liegt, oder ein anderes Problem auftritt.
Der Treiber unterstützt des Weiteren rudimentäre Dateioperationen, ähnlich den Funktionen fopen und fread um auch auf einzelne Dateien zuzugrifen.

Eine Erweiterung um das Anlegen von Verzeichnissen, sowie das Schreiben von Dateien ist in Zukunft geplant.

Funktionen

Hier möchte ich kurz die zur Verfügung stehenden Funktionen beschreiben. Diese lassen sich grob in drei Kategorien aufteilen:

Dateisystem-Funktionen

vint8_t ext2_mount(partition_t *partition)

Mithilfe der übergebenen Partitionsdaten wird zunächst überprüft ob die gewählte Partition wirklich eine ext2-Partition ist, anschließend die Dateisystem-Daten ausgelesen und in das Hauptverzeichniss "/" gewechselt.

int8_t ext2_umount()

Derzeit eher aus "kosmetischen Gründen" vorhanden, da lediglich die gespeicherten Partitionsdaten gelöscht werden um einen weiteren Zugriff auf die Partition zu verhindern.

Verzeichnis-Funktionen

int8_t ext2_ls()

Gibt den Ordnerinhalt des aktuellen Verzeichnisses über die Standardausgabe aus.

int8_t ext2_cat(const char *filename)

Gibt anhand eines übergebenen Dateinamens den Inhalt einer Datei dieses Namens im aktuellen Verzeichnis über die Standardausgabe aus.

int8_t ext2_cd(const char *dirname)

Wechselt in das angegebene Verzeichnis relativ zum aktuellen Verzeichnis. Es ist derzeit lediglich möglich um ein Verzeichnis pro Aufruf zu springen!
Einzige Ausnahme ist das direkte Springen in das Hauptverzeichnis indem als Verzeichnisname "/" übergeben wird.

Datei-Funktionen

int8_t ext2_fopen(ext2_file_t *file, const char *filename)

Öffnet anhand eines übergebenen Dateinamens eine Datei im aktuellen Verzeichnis. Die Dateidaten werden dabei in einem Datei-Pointer gespeichert, welcher von der aufrufenden Funktion übergeben wird. Dieser enthält alle wichtigen Daten über die Position und den Zustand der Datei, so dass auf diese jederzeit zugegriffen werden kann.

int8_t ext2_fclose(ext2_file_t *file)

Derzeit eher aus "kosmetischen Gründen" vorhanden, da lediglich die gespeicherten Dateidaten im übergebenen Datei-Pointer gelöscht werden um einen weiteren Zugriff auf die Datei zu verhindern.

int8_t ext2_fseek(ext2_file_t *file, int32_t offset, uint8_t whence)

Setzt die aktuelle Schreib/Lese-Position innerhalb einer Datei. Die jeweilige Datei wird hierbei mittels Datei-Pointer identifiziert.

uint16_t ext2_fread(uint8_t *buffer, ext2_file_t *file, const uint16_t size)

Mithilfe dieser Funktion können Daten beliebiger Länge aus einer Datei ausgelesen und in einen Puffer zur weiteren Verarbeitung geschrieben werden. Die jeweilige Datei wird hierbei mittels Datei-Pointer identifiziert. Die Schreib/Lese-Position wird automatisch erhöht.

Download

Die aktuelle Version des Treibers kann hier heruntergeladen werden: ext2_driver_0V1.rar V0.1 (ca. 12 kB)

Links

[1] https://de.wikipedia.org/wiki/Ext4
[2] https://de.wikipedia.org/wiki/Ext2
[3] http://www.nongnu.org/ext2-doc/ext2.html
[4] https://www.kernel.org/