
Firmware RP2040 che collega un microdrive SDIO Toshiba MK4001MTD da 0,85" come dispositivo di archiviazione di massa USB, implementando l'intero stack di protocollo SDIO-ATA da zero con letture/scritture accelerate tramite PIO e recupero dei settori danneggiati.
Firmware RP2040 Pico che trasforma un microdrive Toshiba MK4001MTD da 0,85" SDIO in un dispositivo di archiviazione di massa USB.

L'MK4001MTD è un Microdrive da 4 GB originariamente utilizzato nel telefono musicale Nokia N91 e in alcuni altri dispositivi, come lettori MP3 o chiavette USB, quando la memoria flash era ancora piuttosto costosa.
Potreste aver visto introduzioni che affermano che questo drive utilizza il protocollo MMC, ma in realtà è errato. Ho indagato per un po': ho provato a costruire un lettore di schede MMCplus a 8 bit e testato diversi lettori SD/MMC senza successo. Come ultima risorsa, ho acquistato un Nokia N91 per catturare tracce logiche e confermare quale protocollo utilizza effettivamente.
Ecco la foto mentre cercavo di usarlo con la mia scheda lettore 8bit-MMCPlus, e si è scoperto che non è MMC :(

Quindi ho finito per procurarmi un N91 per raccogliere tracce:

A differenza dei microdrive standard ATA/CF, utilizza un'interfaccia SDIO con comandi ATA incapsulati attraverso CMD52/CMD53. Nessun driver esistente supporta questo protocollo, quindi questo firmware implementa l'intero stack da zero.
Questo mi ha sorpreso, perché esiste uno standard SDIO-to-ATA chiamato CE-ATA. Ma se si guarda attentamente alla cronologia dei rilasci, CE-ATA è arrivato dopo questo drive. Di conseguenza, questo drive si basa interamente su comandi SDIO e CE-ATA non è disponibile. CE-ATA ha due nuovi comandi CMD60/CMD61 e utilizza CMD12/39, ma dalle tracce si vede che non ne sta usando nessuno.
Il secondo aspetto hardware da menzionare è che un'altra disinformazione in circolazione—che afferma sia una scheda MMCPlus a 8 bit—non solo è falsa, ma anche il pinout non segue lo standard MMC. È possibile trovare il manuale di servizio del Nokia N91 con un po' di documentazione sul pinout: mentre la numerazione dei pin segue lo standard MMCPlus, la mappatura dei pin no. Questo è un dettaglio importante se lo si cabla da soli: usa lo stesso connettore MMC, ma la mappatura dei pin è diversa, maggiori dettagli nella sezione Hardware.
Infine, si noti che questo è co-sviluppato con Claude/OpenClaw. Ho raccolto le tracce logiche manualmente e ho allestito una stazione di test a ciclo chiuso per permettere a OpenClaw di iterare sullo sviluppo—analizzando le tracce e implementando funzionalità. La documentazione sarà per lo più scritta da Claude; aggiungerò anche le mie note inline. Ho anche letto e ricontrollato la documentazione personalmente, e dovrebbe essere affidabile e facile da seguire.
Per approfondimenti sull'analisi della traccia N91, si trova in /docs/N91_TRACE_ANALYSIS.md, ho anche inserito lì il manuale di servizio N91 insieme alle tracce logiche grezze.
Maggiori dettagli nel post del blog qui: https://www.willwhang.dev/Reading-MK4001MTD/
Vedetelo in azione qui: https://youtu.be/GC4xil3_Bbc
Archiviazione di massa USB completamente funzionante con letture/scritture accelerate da PIO e gestione dell'alimentazione in idle.
| Metrica | Valore |
|---|---|
| Velocità di lettura | ~985 kB/s (limitata dalla velocità USB full-speed) |
| Velocità di scrittura | ~920 kB/s (limitata dalla velocità USB full-speed, cache di scrittura pubblicizzata) |
| Velocità lato SDIO grezza | ~2,35 MB/s in lettura / ~2,15 MB/s in scrittura (limitata dal drive) |
| Capacità | 3,75 GB (7.862.400 settori) |
| File system | FAT32 verificato (mount/unmount/fsck pulito) |
| Integrità dati | Scrittura+rileggere verificato; CRC16 per blocco su tutte e 4 le linee DAT |
| Standby idle | 5 s di inattività o sospensione USB → STANDBY IMMEDIATE + power gate |
Host USB ←→ USB MSC (TinyUSB) ←→ Livello ATA ←→ Livello SDIO (PIO) ←→ MK4001MTD
Il firmware ha quattro livelli:
USB MSC (msc_device.c) — TinyUSB Mass Storage Class. Traduce SCSI READ(10)/WRITE(10) in operazioni sui settori ATA. Buffer EP da 32 KB, raggruppamento fino a 64 settori per trasferimento USB. L'I/O del drive è sovrapposto all'USB in entrambe le direzioni, come un vero bridge ATA-USB con disco cache: un prefetcher di lettura sequenziale recupera il chunk successivo mentre il precedente viene trasmesso all'host, e le scritture vengono bufferizzate e svuotate mentre l'USB riceve il pezzo successivo. Il dispositivo pubblicizza la propria cache di scrittura (Caching mode page, WCE=1 — gli host segnalano "Write cache: enabled" e inviano SYNCHRONIZE CACHE a fsync/unmount/suspend, che il firmware onora). Uno svuotamento in background fallito si manifesta come MEDIUM ERROR sulla successiva WRITE o SYNCHRONIZE CACHE; le scritture su settori noti come danneggiati seguono un percorso sincrono stretto.
ATA-over-SDIO (ata_sdio.c) — Implementa i comandi ATA (IDENTIFY, READ SECTORS, WRITE SECTORS) scrivendo nei registri ATA mappati nello spazio degli indirizzi della funzione SDIO 1 tramite CMD52, e trasferendo i dati dei settori tramite CMD53. Logica di ritentamento a 3 livelli a livello CMD, dati e ATA.
PIO SDIO (sdio_pio.c, sdio.pio) — SDIO accelerato via hardware utilizzando la periferica PIO dell'RP2040 (bus a 4 bit a 10 MHz, 4 cicli PIO per bit con sincronizzatori di ingresso bypassati). Tre programmi PIO condividono una singola macchina a stati mediante swapping dinamico dei programmi:
Pin/Power (sdio_hw.c) — Inizializzazione GPIO e controllo alimentazione HDD. Tutte le comunicazioni SDIO utilizzano PIO.
Note umane: È interessante notare che Claude era molto riluttante a implementare SDIO in PIO, e molti cicli di sviluppo sono stati sprecati in continui passaggi avanti e indietro tra PIO e bit-banging.
L'MK4001MTD si presenta come una scheda SDIO con una funzione I/O. L'inizializzazione standard di una scheda SDIO (CMD5/CMD3/CMD7) imposta il bus, quindi i registri ATA vengono acceduti tramite comandi SDIO:
Accesso ai registri (CMD52): Ogni registro ATA è mappato a un indirizzo della funzione 1:
| Indirizzo | Registro | Utilizzo |
|---|---|---|
| 0x00 | DATA | Destinazione CMD53 per i dati dei settori |
| 0x01 | ERR/FEAT | Errore (lettura) / Caratteristica (scrittura) |
| 0x02 | SECCOUNT | Conteggio settori |
| 0x03 | LBA_LO | LBA bit 0-7 |
| 0x04 | LBA_MID | LBA bit 8-15 |
| 0x05 | LBA_HI | LBA bit 16-23 |
| 0x06 | DEV/HEAD | Dispositivo/Testa + LBA bit 24-27 |
| 0x07 | CMD/STATUS | Comando (scrittura) / Stato (lettura) |