Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
MK4001MTD-USB-Bridge — RP2040 firmware that bridges a Toshiba MK4001MTD 0.85" SDIO microdrive as a USB mass storage device, implementing the full SDIO-ATA protocol stack from scratch with PIO-accelerated reads/writes and bad sector recovery. | Kitploit
Tools/GitHubGitHub/will127534/mk4001mtd-usb-bridge
Embedded Systems SecurityReverse EngineeringData RecoveryHardware HackingHardware SecurityHardware & IoT SecurityFirmware Analysis
GitHub

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
will127534/mk4001mtd-usb-bridge

MK4001MTD-USB-Bridge

RP2040 firmware that bridges a Toshiba MK4001MTD 0.85" SDIO microdrive as a USB mass storage device, implementing the full SDIO-ATA protocol stack from scratch with PIO-accelerated reads/writes and bad sector recovery.

View Repository
4212172 months agoReviewed by Kitploit

MK4001MTD USB Bridge

RP2040 Pico firmware that bridges a Toshiba MK4001MTD 0.85" SDIO microdrive as a USB Mass Storage device. _DSC1170 _DSC1354

The MK4001MTD is a 4 GB Microdrive originally used in the Nokia N91 music phone and some other devices, like MP3 players or USB drives, back when flash storage was still quite expensive.

You might have seen introductions claiming this drive uses the MMC protocol, but that’s actually incorrect. I’ve been investigating this for a while: I tried building an 8-bit MMCplus card reader and tested different SD/MMC readers without success. As a last resort, I bought a Nokia N91 to capture logic traces and confirm what protocol it actually uses.

Here is the photo when I was trying to use it with my 8bit-MMCPlus reader board, and it turns out it is not MMC :( _DSC0484

So I end up getting N91 to collect traces: _DSC1093 _DSC1131

Unlike standard ATA/CF Microdrives, it uses an SDIO interface with ATA commands tunneled through CMD52/CMD53. No existing driver supports this protocol, so this firmware implements the full stack from scratch.

This surprised me, because there is an SDIO-to-ATA standard called CE-ATA. But if you look closely at the release timeline, CE-ATA came later than this drive. As a result, this drive relies entirely on SDIO commands, and CE-ATA is not available. CE-ATA has two new cmd CMD60/CMD61 and utilize CMD12/39, but you can see from the traces it is not using any of those.

The second hardware point to mention is that another piece of misinformation floating around—claiming it’s an 8-bit MMCPlus card—is not only untrue, but the pinout doesn’t follow the MMC standard either. You can find the Nokia N91 service manual with some documentation on the pinout: while the pin numbering follows the MMCPlus standard, the pin mapping does not. This is an important detail if you’re wiring it yourself: it uses the same MMC connector, but the pin mapping is different, more in the Hardware section.

Finally, note that this is co-developed with Claude/OpenClaw. I collected the logic traces manually and set up a closed-loop test station for OpenClaw to iterate on development—analyzing the traces and implementing features. The documentation will mostly be written by Claude; I’ll add my notes inline as well. I’ve also read and double-checked the documentation myself, and it should be reliable and easy to follow.

For insights into the analytics on N91 trace, it is under /docs/N91_TRACE_ANALYSIS.md, I've also put the N91 service manual there along with the raw logic traces.

See more in the blog post here: https://www.willwhang.dev/Reading-MK4001MTD/
See it in activity here: https://youtu.be/GC4xil3_Bbc

Status

Fully functional USB mass storage with PIO-accelerated reads/writes and idle power management.

MetricValue
Read speed~985 kB/s (USB full-speed limited)
Write speed~920 kB/s (USB full-speed limited, advertised write cache)
Raw SDIO-side speed~2.35 MB/s read / ~2.15 MB/s write (drive-limited)
Capacity3.75 GB (7,862,400 sectors)
FilesystemFAT32 verified (mount/unmount/fsck clean)
Data integrityWrite+readback verified; per-block CRC16 on all 4 DAT lines
Idle standby5 s idle or USB suspend → STANDBY IMMEDIATE + power gate

How It Works

Architecture

USB Host ←→ USB MSC (TinyUSB) ←→ ATA Layer ←→ SDIO Layer (PIO) ←→ MK4001MTD

The firmware has four layers:

  1. USB MSC (msc_device.c) — TinyUSB Mass Storage Class. Translates SCSI READ(10)/WRITE(10) into ATA sector operations. 32 KB EP buffer, batching up to 64 sectors per USB transfer. Drive I/O is overlapped with USB in both directions, like a real ATA-USB bridge with a caching disk: a sequential-read prefetcher fetches the next chunk while the previous one streams to the host, and writes are staged and flushed while USB receives the next piece. The device advertises its write cache (Caching mode page, WCE=1 — hosts report "Write cache: enabled" and issue SYNCHRONIZE CACHE at fsync/unmount/suspend, which the firmware honors). A failed background flush surfaces as MEDIUM ERROR on the next WRITE or SYNCHRONIZE CACHE; writes to known-bad sectors take a strict synchronous path.

  2. ATA-over-SDIO (ata_sdio.c) — Implements ATA commands (IDENTIFY, READ SECTORS, WRITE SECTORS) by writing to ATA registers mapped into SDIO function 1 address space via CMD52, and transferring sector data via CMD53. 3-tier retry logic at CMD, data, and ATA levels.

  3. PIO SDIO (sdio_pio.c, sdio.pio) — Hardware-accelerated SDIO using RP2040's PIO peripheral (4-bit bus at 10 MHz, 4 PIO cycles per bit with input synchronizers bypassed). Three PIO programs share a single state machine via dynamic program swapping:

    • CMD tx/rx (24 instructions) — sends SDIO commands and receives responses
    • DAT read (12 instructions) — reads data blocks from 4-bit DAT bus via byte-swapping DMA (no CPU repack); block N's CRC verifies while block N+1 streams
    • DAT write (14 instructions) — writes data blocks to 4-bit DAT bus via DMA, with built-in CRC status reception and busy-wait; block N+1's nibble stream builds while block N transfers
  4. Pin/Power (sdio_hw.c) — GPIO initialization and HDD power control. All SDIO communication uses PIO.

Human notes: Interestingly, Claude was really reluctant to implement SDIO in PIO, and a lot of development cycles were wasted bouncing back and forth between PIO and bit-banging.

The SDIO-ATA Protocol

The MK4001MTD presents itself as an SDIO card with one I/O function. Standard SDIO card initialization (CMD5/CMD3/CMD7) sets up the bus, then ATA registers are accessed through SDIO commands:

Register access (CMD52): Each ATA register is mapped to a function 1 address:

AddressRegisterUsage
0x00DATACMD53 target for sector data
0x01ERR/FEATError (read) / Feature (write)
0x02SECCOUNTSector count
0x03LBA_LOLBA bits 0-7
0x04LBA_MIDLBA bits 8-15
0x05LBA_HILBA bits 16-23
0x06DEV/HEADDevice/Head + LBA bits 24-27
0x07CMD/STATUSCommand (write) / Status (read)

Data transfer (CMD53): Sector data is transferred by issuing CMD53 in block mode targeting the DATA register (address 0x00). For multi-sector reads, a single CMD53 with block_count=N transfers N × 512 bytes in one SDIO multi-block transaction.

Interrupt signaling: The drive signals sector readiness by asserting an SDIO interrupt (INT_PENDING bit 1 in CCCR register 0x05). Reading the ATA STATUS register clears the interrupt.

Read Path (Multi-Block PIO)

For a 16-sector read:

1. Write ATA registers via PIO CMD52:
     SECCOUNT=16, LBA_LO/MID/HI, DEV/HEAD=0xE0, CMD=0x20

2. Poll STATUS via CMD52 until DRQ (bit 3) is set

3. Swap PIO to DAT read program
4. Send CMD53: block_mode=1, fn=1, addr=0x0000, block_count=16

5. PIO DAT read: for each of the 16 blocks:
   a. Wait for start bit (all DAT lines low)
   b. DMA 1024 nibbles (512 bytes) from PIO RX FIFO to buffer
   c. Wait for SM to finish clocking CRC+end nibbles (poll SM PC)
   d. Repack nibbles → bytes in-place
Download Tool