USB Gadget: Mass Storage Emulation

  • Leider finden sich über diese Variante nicht so viele Informationen im Netz beziehungsweise die meisten Artikel sind schon älter...


    Hintergrund:
    Der SoC aller (bisherigen) Pi's hat intern einen einzigen USB Port, einen sog. USB-OTG den man in Master- oder Slave-Modus versetzen kann. Bei den "normalen" RaspberryPi's ist an diesen einen USB-Port vom SoC ein USB-Hub-Controller angeschlossen, der wiederum die weiteren USB-Ports sowie LAN zur Verfügung stellt. Leider kann man dann den USB-OTG nicht mehr derart nutzen..
    Bei den RaspberryPi Modellen A, A+ und Zero hat man aber glücklicherweise auf den USB-Hub-Controller verzichtet und den USB-OTG-Port der SoC direkt herausgeführt. Dadurch hat man dann zwar auch nur einen einzigen USB-Port, der sich aber wie gesagt auch in den Slave-Modus versetzen lässt. Genau das macht man sich hier zu nutze.



    Es gibt viele verschiedene USB-Gadget-Modes, ich möchte hier aber nur auf einen eingehen: g_mass_storage


    Mit einem PiZeroW kann man dadurch einen WLAN-Fähigen-Datenträger realisieren, auf den man zB via Samba zugreifen kann.
    Denkbare Einsatzmöglichkeiten wäre, den PiZeroW an ein Bilderrahmen oder TV anzuschließen - sobald sich der Inhalt verändert kann ein aushängen und neu einstecken des "FlashDrives" hervorgerufen werden etc.. Möglichkeiten gäbe es viele ;)


    Ziel ist es aber nicht Platzhirsche wie KODI den Rang streitig zu machen. Gestreamt o.ä. werden soll nichts, der Pi selbst spielt nichts ab. Das sollte nicht verwechselt werden.


    Grob umschrieben:
    Auf dem Pi wird ein extra Datenträger angelegt - eine Image-Datei.
    Der Pi wird via USB an ein Gerät angeschlossen, auf dem dann ein "Wechseldatenträger" verfügbar ist.
    Die Dateien liegen auf dem Pi, in besagter Image-Datei. Nur mit dem PiZeroW kommt zusätzlich noch WLAN hinzu.
    Sofern das Gerät an ist kann man auf den Pi zugreifen - und zum Beispiel einrichten via Samba auf den extra Datenträger zuzugreifen...
    Der Pi behält ansonsten seine normale Funktionalität.


    [hr]


    Nötige Voraussetzung:

    Code
    1. echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt
    2. echo "dwc2" | sudo tee -a /etc/modules


    Außerdem funktioniert das Unterfangen auf dem Pi erst ab Kernel 4.4
    Derzeit scheint es auch noch Probleme mit Raspbian Stretch zu geben - ich konnte es bisher nur mit Jessie zum laufen bringen, genauer gesagt hiermit (letztes Raspbian-Lite Image das raus kam).


    [hr]


    Man kann nicht die gesamte SD Karte als "FlashDrive" freigeben, sondern muss dafür ein gesondertes/extra Device einrichten - in diesem Fall eine Image-Datei die wir aber erst erzeugen müssen... Es funktioniert aber auch eine extra Partition auf der SD...


    Code
    1. dd if=/dev/zero of=/usbdisk.img bs=1M count=2048

    Es wird eine 2 GB große Datei erzeugt.


    Anschließend ist es wichtig das auf dieser großen Datenträger-Datei auch eine Partition eingerichtet wird:

    ...via copy&paste alles auf einmal in die Konsole einfügen...


    Die Größe der cylinders müsst ihr der von euch gewählten Datenträger-Datei anpassen.
    Die Berechnung solltet ihr hierüber machen: http://www.unitconversion.org/…nverter/data-storage.html


    Nun müsste man eigentlich noch eine Formatierung durchführen, aber das kann auch Windows machen sobald der Datenträger erkannt wurde :fies:
    ...ansonsten geht das aber natürlich auch über Linux...

    Code
    1. losetup -o $((2048*512)) /dev/loop0 /usbdisk.img
    2. mkfs -t vfat -v /dev/loop0 -n usbdisk
    3. losetup -d /dev/loop0

    mit "-n" wird das Label gesetzt.


    Das Offset richtet sich nach dem "Start" Wert der euch über "fdisk -lu /usbdisk.img" angezeigt wird:


    [hr]


    Jetzt folgt der erste Test ob das ganze überhaupt funktioniert - wir laden das Kernel Module:
    ...natürlich solltet ihr den PiZero(W) längst über USB, und natürlich auch der USB Buchse am Pi, mit eurem PC verbunden haben... BTW: die PWR Buchse des Pi's hat keine Datenleitungen.

    Code
    1. sudo modprobe g_mass_storage file=/usbdisk.img stall=0 removable=1 iSerialNumber=1234567890

    Alle verfügbaren Optionen lassen sich wie folgt abrufen:

    Code
    1. modinfo g_mass_storage

    Theoretisch müsste auch folgendes gehen:

    Code
    1. sudo modprobe g_mass_storage file=/usbdisk.img stall=0 removable=1 idVendor=0x0781 idProduct=0x5572 bcdDevice=0x011a iManufacturer="SanDisk" iProduct="Cruzer Switch" iSerialNumber=1234567890


    Zum überprüfen ob das fehlerfrei funktionierte:

    Code
    1. dmesg | tail -n10


    Man kann auch so tun als würde man den "USB-Stick" wieder raus ziehen, indem man einfach das Kernel Module entfernt:

    Code
    1. sudo modprobe -r g_mass_storage


    [hr]


    Wenn man nun unter Linux, also auf dem PiZeroW, auf die Datenträger-Datei zugreifen möchte, muss man diese besonders mounten. Wichtig hierbei ist aber auch das die Datei gerade nicht vom Gadget verwendet wird sonst riskiert ihr eine Beschädigung!


    Einhängen:

    Code
    1. FILE=/usbdisk.img
    2. mkdir -p ${FILE/img/d}
    3. mount -o loop,offset=$((2048*512)) -t vfat $FILE ${FILE/img/d}

    Wer sich wundert, gemounted wird nach: /usbdisk.d/


    Aushängen:

    Code
    1. umount ${FILE/img/d}



    Wichtig:
    Ihr könnt den PiZero(W) problemlos über den USB-Port mit Strom versorgen. Falls ihr den Pi aber permanent laufen lassen wollt und eine separate Stromzufuhr über PWR-IN anschließen wollt, solltet ihr unbedingt das USB-Port Kabel modifizieren und die rote Ader durchtrennen - es ist riskant den Pi über 2 unterschiedliche Spannungsversorgungen zu betreiben!



    [hr]



    Links:



    https://github.com/raspberrypi…ster/boot/overlays/README
    http://www.linux-usb.org/gadget/file_storage.html
    https://isojed.nl/blog/2017/03/13/raspberry-pi-zero-w/
    https://www.raspberrypi.org/magpi-issues/MagPi60.pdf (ab Seite 54)
    https://github.com/ckuethe/usbarmory/wiki/USB-Gadgets
    https://www.kernel.org/doc/Doc…n/usb/gadget_configfs.txt
    http://isticktoit.net/?p=1383

  • Moin meigrafd,
    danke für deinen Artikel!


    Hast du irgendwie einen "Nachweis" über die Aussage, nicht an beiden USB-Buchsen eine Spannung anzuschließen?
    Oder ist es eigene Erfahrung?


    Gruss Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"

  • Zitat von "DG8BR" pid='300118' dateline='1505600163'


    Hast du irgendwie einen "Nachweis" über die Aussage, nicht an beiden USB-Buchsen eine Spannung anzuschließen?


    So stehts in der MagPi#60 https://www.raspberrypi.org/magpi-issues/MagPi60.pdf (auf Seite 55):


    Hab das aber auch irgendwo anders gelesen, weiß aber nicht mehr wo..


    Zitat von "DG8BR" pid='300118' dateline='1505600163'


    Oder ist es eigene Erfahrung?


    Ich hatte meinen PiZeroW ca. einen Tag lang über 2 USB Kabel am PC angeschlossen und er lebt noch - aber wirklich auf die Spitze treiben möchte ich's nicht, und falls ich sowas nicht explizit erwähne könnte sich hier wieder jemand aufregen ...

  • Moin meigrafd,


    danke.
    Ich habe nur gefragt, weil ich letzt einem User geschrieben habe, das er es ohne Bedenken machen könnte.


    Gruss Bernd


    /edit
    Naja, richtig begründet ist es ja nicht.

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"

    Einmal editiert, zuletzt von Bernd666 ()

  • Hallo meigrafd,


    danke nochmals für das Zusammentragen der Infos ... ;)


    Ich habe das noch nicht richtig verstanden und hätte noch ein paar (blöde) Fragen: Läuft dann noch ein Linux im Hintergrund oder anders gefragt: Laufen noch Dienste? Mir geht's dabei um die Konfiguration. Der Zero (W) würde dann ausschließlich als (Daten-)Server fungieren oder?

    "Alles, was wir sind, ist Sand im Wind, Hoschi."

  • Am Zustand des Pi's ändert sich nichts. Alles läuft wie bisher auch. Also alles wie gehabt, ganz normales OS, alle GPIO's usw funktionieren weiterhin, alles was du installierst oder konfiguriert hast bleibt. Es wird einfach nur zusätzlich ein Treiber geladen der die Image-Datei via USB quasi freigibt.


    In meiner obigen Beschreibung wird die "Freigabe" unter Windows als "Wechseldatenträger" angezeigt, man kann den Kernel-Treiber aber auch so einstellen das stattdessen zB ein CDROM angezeigt wird, oder eine starre Festplatte, oder nur "read-only"...


    Einen Schritt weiter würde "g_multi" gehen, das vereint g_ether und g_mass_storage.


    Mithilfe dieser USB-Gadgets kann man auch ganz leicht mehrere Pi's miteinander vernetzen, zum Beispiel vier PiZero an einen Pi2 o.ä. und alle greifen ganz normal via Netzwerk aufeinander zu, nur ohne LAN Kabel ;)

  • Spaßvögel könnten auch auf die Idee kommen, den Treiber per modprobe zu entladen und mit anderer Konfiguration wieder zu laden. Der verwirrte Windows-User bekommt dann mal eine Festplatte, mal einen Stick und mal ne CD ;)


    Oder vielleicht kann man da ja auch mit UDEV Regeln vor jedem Einstecken zufällig was aussuchen...


    Nichts für ungut!

  • Hab auch über das Thema gelesen aber ich nutze dann doch lieber reale SDs, Platten, CDs, DVDs, USB Sticks, .... ;):D

    ;) Gruß Outi :D
    PIs: 2x Pi B (Rente) / 1x Pi B+ (Rente) / 1x Pi 2 B (Tests) / 2x Pi 3 B (RaspberryMatic/Win10IoT) / 2x Pi Zero 1.2 (J. Lite) / 2x Pi Zero 1.3 (J. Lite) / 2x Pi Zero W 1.1 (Stretch) / 1x Pi 3 B+ (Stretch)
    Platinen: Sense HAT / RPI-RF-MOD / PiFi DAC+ V2.0

  • Möchte mich mal an die Umsetzung der obigen Anleitung begeben. Da es aber ja doch ein bisschen Arbeit ist vorweg noch einmal eine Frage: Wenn ich zwei Zeros verbinde und einen der beiden wie beschrieben als virtuellen Datenträger konfiguriere, können dann beide Zeros auf diesen (bzw. auf das Filesystem innerhalb der genannten Image-Datei) gleichberechtigt schreibend und lesend zugreifen? Hat das schon mal jemand probiert?

  • Guten Tag raspberryPi Gemeinschaft,


    ich beschäftige mich derzeit auch mit den usb gadgets und hätte diesbezüglich eine Frage.

    Ist es Hardwaretechnisch möglich einen Hub zu emulieren, an dem dann weitere emulierte usb gadgets hängen können. Ich arbeite mit einem ti prozesser der zwei otg usb ports hat und nutzte außerhalb des prozessors einen hub der mit dem up usb link zum pc verbunden ist. Ich würde aber gerne dynamisch mehr als 2 verschiedene USB Geräte an den PC hängen können und diese an und abmelden und dazu bräuchte ich mehr usb otg Schnittstellen oder gleich einen emulierten hub. Was alles sehr viel flexibler machen würde.


    Wenn jemand hier weiß, wo ich am besten Informationen finden könnte, wie die Hardware grundlegend funktioniert, dann würde ich einen Treiber schreiben können. Ich habe nur bis jetzt gesehen, dass die Hardware 16 Endpunktinterrupt reserviert, aber wo und wie diese abgearbeitet werden und wo die usb device Nummer abgefragt wird habe ich noch nicht gefunden.


    Hoffe ihr helft mir bei meinem kleinen Projekt :)


    Lg Greenlight