Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
MK4001MTD-USB-Bridge — Firmware RP2040 que faz a ponte entre um microdrive SDIO Toshiba MK4001MTD de 0,85" como um dispositivo de armazenamento em massa USB, implementando toda a pilha de protocolo SDIO-ATA do zero com leituras/escritas aceleradas por PIO e recuperação de setores defeituosos. | Kitploit
Ferramentas/GitHubGitHub/will127534/mk4001mtd-usb-bridge
Segurança de Sistemas EmbarcadosEngenharia ReversaRecuperação de DadosHacking de HardwareSegurança de HardwareSegurança de Hardware e IoTAnálise de Firmware
GitHubwill127534/mk4001mtd-usb-bridge

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

MK4001MTD-USB-Bridge

Firmware RP2040 que faz a ponte entre um microdrive SDIO Toshiba MK4001MTD de 0,85" como um dispositivo de armazenamento em massa USB, implementando toda a pilha de protocolo SDIO-ATA do zero com leituras/escritas aceleradas por PIO e recuperação de setores defeituosos.

Ver Repositório
4212há 1 mêsRevisado pelo Kitploit

Ponte USB MK4001MTD

Firmware RP2040 Pico que faz a ponte de um microdrive SDIO Toshiba MK4001MTD de 0,85" como dispositivo de armazenamento em massa USB. _DSC1170 _DSC1354

O MK4001MTD é um Microdrive de 4 GB originalmente usado no telefone musical Nokia N91 e em alguns outros dispositivos, como tocadores de MP3 ou unidades USB, na época em que o armazenamento flash ainda era bastante caro.

Você pode ter visto introduções afirmando que este drive usa o protocolo MMC, mas isso está incorreto. Estou investigando isso há algum tempo: tentei construir um leitor de cartão MMCplus de 8 bits e testei diferentes leitores SD/MMC sem sucesso. Como último recurso, comprei um Nokia N91 para capturar traces lógicos e confirmar qual protocolo ele realmente usa.

Aqui está a foto quando eu estava tentando usá-lo com minha placa leitora 8bit-MMCPlus, e descobriu-se que não é MMC :( _DSC0484

Então acabei comprando um N91 para coletar traces: _DSC1093 _DSC1131

Ao contrário dos microdrives ATA/CF padrão, ele usa uma interface SDIO com comandos ATA tunelados através do CMD52/CMD53. Nenhum driver existente suporta esse protocolo, então este firmware implementa toda a pilha do zero.

Isso me surpreendeu, porque existe um padrão SDIO-para-ATA chamado CE-ATA. Mas se você observar atentamente a linha do tempo de lançamento, o CE-ATA veio depois deste drive. Como resultado, este drive depende inteiramente de comandos SDIO, e o CE-ATA não está disponível. O CE-ATA tem dois novos comandos CMD60/CMD61 e utiliza CMD12/39, mas você pode ver pelos traces que ele não está usando nenhum deles.

O segundo ponto de hardware a mencionar é que outra desinformação circulando—afirmando que é um cartão MMCPlus de 8 bits—não é apenas falsa, mas a pinagem também não segue o padrão MMC. Você pode encontrar o manual de serviço do Nokia N91 com alguma documentação sobre a pinagem: embora a numeração dos pinos siga o padrão MMCPlus, o mapeamento dos pinos não. Este é um detalhe importante se você estiver fazendo a fiação você mesmo: ele usa o mesmo conector MMC, mas o mapeamento dos pinos é diferente, mais na seção Hardware.

Finalmente, note que isso foi desenvolvido em conjunto com Claude/OpenClaw. Eu coletei os traces lógicos manualmente e montei uma estação de teste em malha fechada para o OpenClaw iterar no desenvolvimento—analisando os traces e implementando funcionalidades. A documentação será escrita principalmente por Claude; também adicionarei minhas anotações inline. Também li e verifiquei a documentação pessoalmente, e ela deve ser confiável e fácil de seguir.

Para insights sobre as análises do trace do N91, está em /docs/N91_TRACE_ANALYSIS.md, também coloquei o manual de serviço do N91 lá junto com os traces lógicos brutos.

Veja mais no post do blog aqui: https://www.willwhang.dev/Reading-MK4001MTD/
Veja em atividade aqui: https://youtu.be/GC4xil3_Bbc

Status

Armazenamento em massa USB totalmente funcional com leituras/escritas aceleradas por PIO e gerenciamento de energia ociosa.

Como Funciona

Arquitetura

root@kitploit:~
USB Host ←→ USB MSC (TinyUSB) ←→ ATA Layer ←→ SDIO Layer (PIO) ←→ MK4001MTD

O firmware tem quatro camadas:

  1. USB MSC (msc_device.c) — TinyUSB Mass Storage Class. Traduz SCSI READ(10)/WRITE(10) em operações de setor ATA. Buffer EP de 32 KB, agrupando até 64 setores por transferência USB. A E/S do drive é sobreposta com USB em ambas as direções, como uma ponte ATA-USB real com um disco de cache: um pré-buscador de leitura sequencial busca o próximo bloco enquanto o anterior é transmitido ao host, e as escritas são enfileiradas e liberadas enquanto a USB recebe a próxima parte. O dispositivo anuncia seu cache de escrita (Caching mode page, WCE=1 — os hosts reportam "Write cache: enabled" e emitem SYNCHRONIZE CACHE em fsync/desmontagem/suspensão, que o firmware honra). Uma liberação de fundo com falha surge como MEDIUM ERROR no próximo WRITE ou SYNCHRONIZE CACHE; escritas em setores conhecidamente ruins seguem um caminho estritamente síncrono.

  2. ATA-over-SDIO (ata_sdio.c) — Implementa comandos ATA (IDENTIFY, READ SECTORS, WRITE SECTORS) escrevendo em registradores ATA mapeados no espaço de endereço da função 1 SDIO via CMD52, e transferindo dados de setor via CMD53. Lógica de retry em 3 níveis nos níveis CMD, dados e ATA.

  3. PIO SDIO (sdio_pio.c, sdio.pio) — SDIO acelerado por hardware usando o periférico PIO do RP2040 (barramento de 4 bits a 10 MHz, 4 ciclos PIO por bit com sincronizadores de entrada desviados). Três programas PIO compartilham uma única máquina de estado via troca dinâmica de programas:

    • CMD tx/rx (24 instruções) — envia comandos SDIO e recebe respostas
    • DAT read (12 instruções) — lê blocos de dados do barramento DAT de 4 bits via DMA com troca de bytes (sem reempacotamento pela CPU); o CRC do bloco N verifica enquanto o bloco N+1 é transmitido
    • DAT write (14 instruções) — escreve blocos de dados no barramento DAT de 4 bits via DMA, com recepção de status CRC embutida e busy-wait; o fluxo de nibbles do bloco N+1 é construído enquanto o bloco N é transferido
  4. Pin/Power (sdio_hw.c) — Inicialização de GPIO e controle de energia do HDD. Toda comunicação SDIO usa PIO.

Notas humanas: Curiosamente, Claude estava realmente relutante em implementar SDIO em PIO, e muitos ciclos de desenvolvimento foram desperdiçados indo e voltando entre PIO e bit-banging.

O Protocolo SDIO-ATA

O MK4001MTD se apresenta como um cartão SDIO com uma função I/O. A inicialização padrão do cartão SDIO (CMD5/CMD3/CMD7) configura o barramento, então os registradores ATA são acessados através de comandos SDIO:

Acesso a registradores (CMD52): Cada registrador ATA é mapeado para um endereço da função 1:

Transferência de dados (CMD53): Os dados do setor são transferidos emitindo CMD53 em modo bloco visando o registrador DATA (endereço 0x00). Para leituras de múltiplos setores, um único CMD53 com block_count=N transfere N × 512 bytes em uma transação multi-bloco SDIO.

Sinalização de interrupção: O drive sinaliza prontidão do setor afirmando uma interrupção SDIO (bit INT_PENDING 1 no registrador CCCR 0x05). A leitura do registrador ATA STATUS limpa a interrupção.

Caminho de Leitura (PIO Multi-Bloco)

Para uma leitura de 16 setores:

root@kitploit:~
1. Escrever registradores ATA via PIO CMD52:
     SECCOUNT=16, LBA_LO/MID/HI, DEV/HEAD=0xE0, CMD=0x20

2. Poll STATUS via CMD52 até DRQ (bit 3) ser definido

3. Trocar PIO para programa de leitura DAT
4. Enviar CMD53: block_mode=1, fn=1, addr=0x0000, block_count=16

5. Leitura PIO DAT: para cada um dos 16 blocos:
   a. Aguardar bit de início (todas as linhas DAT baixas)
   b. DMA de 1024 nibbles (512 bytes) do FIFO RX do PIO para o buffer
   c. Aguardar SM terminar de clockear nibbles CRC+fim (poll SM PC)
   d. Reempacotar nibbles → bytes no local

6. Trocar PIO de volta para programa CMD

Caminho de Escrita (PIO Multi-Bloco)

Para uma escrita de 16 setores:

root@kitploit:~
1. Escrever registradores ATA via PIO CMD52:
     SECCOUNT=16, LBA, DEV/HEAD=0xE0, CMD=0x30

2. Poll STATUS via CMD52 até DRQ (bit 3) ser definido
   (STATUS 0xD8 = BSY+DRQ tratado como DRQ-pronto, conforme trace N91)

3. Trocar PIO para programa de escrita DAT
4. Enviar CMD53: block_mode=1, fn=1, addr=0x0000, block_count=16

5. Escrita PIO DAT: para cada um dos 16 blocos:
   a. Pré-calcular CRC16-CCITT por linha DAT (4 CRCs independentes)
   b. Construir fluxo de nibbles: start(0x0) + dados(1024 nibbles) + CRC(16) + end(0xF)
   c. DMA do fluxo de nibbles para FIFO TX do PIO
   d. PIO clockea todos os nibbles, então:
      - Alterna DAT para entrada
      - Clockea 16 ciclos para status CRC do cartão
      - Poll DAT0 até cartão liberar busy
      - Dispara IRQ 0 para sinalizar conclusão do bloco

6. Trocar PIO de volta para programa CMD

Troca de Programa PIO

O RP2040 PIO tem 32 slots de instrução por bloco. Nossos três programas totalizam 55 instruções, então não podem coexistir. Em vez disso, uma única SM0 no PIO0 é usada, e os programas são trocados escrevendo diretamente na memória de instrução PIO:

root@kitploit:~
static void load_program_raw(const pio_program_t *program) {
    for (uint i = 0; i < program->length; i++)
        pio->instr_mem[FIXED_OFFSET + i] = program->instructions[i];
}

Isso contorna o alocador pio_add_program/pio_remove_program do SDK. A troca de programa leva ~1 µs. Cada troca é seguida por uma reinicialização específica do programa que define mapeamentos de pinos, direção de deslocamento e divisor de clock.

Gerenciamento de Energia

A análise dos traces lógicos do Nokia N91 revela gerenciamento de energia agressivo:

  • Modo inativo: STANDBY IMMEDIATE (0xE0) a cada ~7,5 segundos, mesmo sem E/S. Cada standby aciona reinicialização completa do SDIO (retry CMD5 → CMD3 → CMD7 → configuração CCCR). 28 ciclos de standby observados em uma sessão inativa.
  • Modo ativo: Standby emitido entre rajadas de E/S (24 ciclos durante operações de arquivo no drive USB).
  • Nenhum outro comando de energia (IDLE, SLEEP, CHECK POWER MODE) ou acessos ao registrador de energia CCCR foram observados.

O firmware replica esse comportamento com um tempo limite configurável para inatividade:

root@kitploit:~
#define IDLE_STANDBY_MS 5000  // in main.c

Dois caminhos acionam o corte de energia do HDD:

  1. Tempo limite inativo (5 segundos) — loop principal detecta nenhuma atividade de E/S
  2. Suspensão USB — host suspende a porta USB

Ambos os caminhos enviam ATA STANDBY IMMEDIATE (0xE0) para liberar o cache de escrita e estacionar as cabeças, depois cortam a energia via GP9.

Sequência de ativação (acionada pelo primeiro READ/WRITE após o corte):

  1. Ligar HDD, aguardar 500ms para estabilização da alimentação
  2. Reinicialização SDIO baseada em PIO: CMD5 (OCR) → 10ms de espera → CMD3 (RCA) → CMD7 (selecionar)
  3. Mudar para clock PIO rápido, configurar CCCR via CMD52 (barramento de 4 bits, blocos de 512B, fn1 habilitada)
  4. Poll fn1 pronta (bit IO_READY do CCCR 1)
  5. Poll DRDY estilo N91 por 30ms até drive estar pronto para ATA

Tratamento de Setores Ruins

Quando uma transferência de múltiplos setores atinge um setor ruim:

  1. Leitura do bloco falha → recuperação de erro (IO_ABORT + reset fn1, ~500ms)
  2. Recai para E/S por setor para identificar o bloco com falha precisamente
  3. A camada ATA espera tempo suficiente para capturar os bits finais de STATUS/ERROR em vez de colapsar a falha em um DRQ timeout genérico
  4. Qualquer bloco não recuperado falha o comando SCSI imediatamente com MEDIUM ERROR (leitura: 03/11/00, escrita: 03/0C/00)
  5. LBA do setor ruim em cache → leituras repetidas falham rapidamente sem martelar o drive (proteção anti-martelo contra tempestades de retry do host)
  6. Escritas sempre tocam o meio, conforme SBC — uma escrita bem-sucedida em um LBA ruim em cache o remove do cache, exatamente como um drive limpando um setor pendente

O ponto 6 não é acadêmico: este drive tinha um setor ilegível de longa data no LBA 1952 (READ: ST=0x51 ERR ERR=0x40 UNC). Depois que a ponte permitiu que uma escrita realmente o alcançasse, o drive reescreveu o setor e ele tem sido lido limpo desde então:

root@kitploit:~
[ATA] FAST-RD: ST=0x51 ERR ERR=0x40 UNC LBA=1952
[MSC] BAD SECTOR read LBA=1952
[MSC] Bad sector LBA=1952 repaired by write

Construção

Pré-requisitos

  • Raspberry Pi Pico SDK — original, não modificado, fixado na versão 2.2.0
  • Cadeia de ferramentas ARM (arm-none-eabi-gcc)
  • CMake

A versão do SDK é travada: se PICO_SDK_PATH estiver definida (variável de ambiente ou CMake) ela é usada e sua versão é verificada contra o travamento — uma incompatibilidade falha a configuração com instruções (substituir com -DMK4001_ALLOW_SDK_MISMATCH=ON). Sem PICO_SDK_PATH alguma, a versão travada do SDK é baixada do GitHub automaticamente no momento da configuração, então um simples git clone && cmake && make é totalmente reproduzível.

O firmware precisa de um driver de classe MSC TinyUSB corrigido (dados sense preservados em erros de leitura/escrita + uma página de modo Caching com WCE=1). Esse arquivo está fornecido neste repositório em lib/tinyusb_patched/msc_device.c — a construção automaticamente o compila em vez da cópia do SDK, portanto nenhuma cirurgia no SDK é necessária. O diff contra o TinyUSB upstream (0.18.0, como incluído no pico-sdk 2.2.0) está em lib/tinyusb_patched/; o travamento do SDK existe precisamente porque este arquivo fornecido deve rastrear o TinyUSB do SDK.

Construir e Gravar

root@kitploit:~
cd /home/pi/mk4001_bridge/build
cmake ..
make -j4

sudo openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg \
  -c "adapter speed 1000" -c "init" -c "reset halt" -c "sleep 200" \
  -c "program /home/pi/mk4001_bridge/build/mk4001_bridge.elf verify" \
  -c "reset run" -c "exit"

Fiação do Hardware

Nota: GP0 e GP1 estão mortos nesta unidade Pico específica. Todas as atribuições de pinos SDIO estão deslocadas +2.

Notas humanas: Claude estava errado aqui porque não percebeu que GP0 e GP1 estavam sendo usados para o terminal UART em sua configuração de construção. Ele continuava esquecendo isso, a tal ponto que eu simplesmente movi os GPIOs SDIO para fora daquela UART.

O HDD_PWR não é necessário. Você não precisa desligar e ligar o drive para usá-lo; é mais uma conveniência de desenvolvimento para resetar o HDD quando muitas coisas estão codificadas. Dito isso, se você quiser economia de energia, pode usar esse sinal, mas ele pode lidar com reset a quente sem problemas.

Você verá mensagens de depuração pela UART. Elas não passam pelo USB-CDC porque foi mais fácil para Claude configurar um link de registro UART-para-USB separado que não desconecta ou se torna instável durante o desenvolvimento inicial.

O log UART também reporta a temperatura do drive a cada 30 segundos enquanto o drive está ativo ([TEMP] drive temperature: 29 C). O sensor foi descoberto por engenharia reversa do comando proprietário Toshiba 0xC2 — o N91 o lê no início de cada sessão do drive para impor seus limites de temperatura operacional do HDD. Detalhes em docs/N91_TRACE_ANALYSIS.md §4.

Aqui está um exemplo do log:

root@kitploit:~
========================================
  MK4001MTD USB Bridge v0.11
  SDIO-ATA → USB Mass Storage (PIO)
========================================

[MAIN] Pre-delay 5000ms...
[PIO] Init OK: clkdiv=3.12 (~10.0 MHz), CMD@0
[MAIN] Power cycling HDD...
[SDIO] HDD power OFF
[SDIO] HDD power ON
[MAIN] SDIO init (PIO)...
[SDIO] CMD5 ready (OCR=0x901F8000)
[SDIO] RCA=0x0001
[SDIO] fn1 ready (attempt 0)
[MAIN] ATA IDENTIFY...
[ATA] IDENTIFY complete
Model:    [TOSHIBA MK4001MTD]
Serial:   [           763B004HA]
Firmware: [VH173A]
Sectors:  7862400 (3839 MB)
SMART:    not supported (supported=0, enabled=0)
IDENTIFY: W0=0040 W47=0000 W49=0000 W59=0000
  ATA W80=0000  Cmd W82=0000 W83=0000 W84=0000
  En  W85=0000 W86=0000 W87=0000  W89=0008 W128=0001

[DIAG] === Drive Diagnostics ===
[DIAG] Standard SMART: not supported (IDENTIFY W82 bit0 = 0)
[DIAG] Toshiba vendor CMD 0xC2:
  FEAT=0x01 unknown_01                       → SC=00 LBA=02/00/00 ST=50
  FEAT=0x02 unknown_02                       â SC=00 LBA=02/00/00 ST=50
  FEAT=0x03 unknown_03                       → SC=00 LBA=02/00/00 ST=50
  FEAT=0x04 unknown_04                       → SC=00 LBA=02/00/00 ST=50
  FEAT=0x10 diag_10 (LBA_LO varies)          → SC=00 LBA=00/00/00 ST=50
  FEAT=0x11 diag_11                          → SC=00 LBA=00/00/00 ST=50
  FEAT=0x12 diag_12 (LBA_LO varies)          → SC=00 LBA=01/00/00 ST=50
  FEAT=0x20 query_20 (N91: SC=0xFF always)   → SC=FE LBA=00/FF/00 ST=50
  FEAT=0x21 query_21 (N91: SC varies per boot) → SC=1B LBA=00/FF/00 ST=50

[MAIN] MBR: valid 0x55AA
[MAIN] Warming up...
[MAIN] PIO OK, STATUS=0x50
[MAIN] Drive: 7862400 sectors (3839 MB)
[MAIN] Ready.
[PWR] Idle 5000ms → STANDBY + power gate
[PWR] STANDBY IMMEDIATE → power gate
[SDIO] HDD power OFF

Finalmente, aqui está a fiação para o drive real.
_DSC1176-2 Aqui está um recorte do esquema N91, você pode mapear o número do pino também. image

Nota lateral: este é um drive de 3V, mas acho que 3.3V é aceitável, principalmente para economizar trabalho de mudança de nível.

HW especificamente projetado para este drive está em /hardware! image

Arquivos Fonte

Histórico de Versões

Testes

root@kitploit:~
# Verificar se o dispositivo apareceu
lsblk -dno NAME,MODEL | grep MK4001

# Teste de sistema de arquivos — montar, copiar arquivos, verificar
sudo mount /dev/sdX1 /mnt/mk4001
cp /tmp/testfile /mnt/mk4001/
sync
md5sum /tmp/testfile /mnt/mk4001/testfile    # deve coincidir
sudo umount /mnt/mk4001

# Benchmarks de velocidade (dispositivo bruto, NÃO monte primeiro — corromperá o sistema de arquivos)
# Use um deslocamento seguro além do sistema de arquivos ou um drive não particionado
sudo dd if=/dev/sdX of=/dev/null bs=64k count=128 iflag=direct     # leitura
sudo dd if=/dev/zero of=/dev/sdX bs=64k count=64 oflag=direct seek=1024  # escrita (deslocamento além do FS)

Notas humanas aqui, fato divertido: Quando começou a fazer testes de velocidade, ele na verdade executou dd diretamente no drive e danificou os sistemas de arquivos..... Felizmente isso não importa muito durante os desenvolvimentos, mas sempre tenha em mente ao lidar com o OpenClaw sua configuração.

Licença

Eu não me importo.

Baixar ferramenta
MetricValue
Velocidade de leitura~985 kB/s (limitado pela USB full-speed)
Velocidade de escrita~920 kB/s (limitado pela USB full-speed, cache de escrita anunciado)
Velocidade bruta do lado SDIO~2,35 MB/s leitura / ~2,15 MB/s escrita (limitado pelo drive)
Capacidade3,75 GB (7.862.400 setores)
Sistema de arquivosFAT32 verificado (mount/unmount/fsck limpo)
Integridade dos dadosEscrita+releitura verificada; CRC16 por bloco em todas as 4 linhas DAT
Espera ociosa5 s inativo ou suspensão USB → STANDBY IMMEDIATE + corte de energia
EndereçoRegistradorUso
0x00DATAAlvo CMD53 para dados de setor
0x01ERR/FEATErro (leitura) / Feature (escrita)
0x02SECCOUNTContagem de setores
0x03LBA_LOLBA bits 0-7
0x04LBA_MIDLBA bits 8-15
0x05LBA_HILBA bits 16-23
0x06DEV/HEADDispositivo/Cabeça + LBA bits 24-27
0x07CMD/STATUSComando (escrita) / Status (leitura)
Pico GPIOFunçãoNotas
GP2SDIO_CLKSaída de clock do host
GP3SDIO_CMDLinha de comando bidirecional
GP4SDIO_DAT0Bit de dados 0
GP5SDIO_DAT1Bit de dados 1
GP6SDIO_DAT2Bit de dados 2
GP7SDIO_DAT3Bit de dados 3
GP9HDD_ENAtivação de energia do drive (HIGH=ligado)
GP12UART TXSaída de depuração @ 115200
GP13UART RXEntrada de depuração
GP16LED: Energia HDDAtivo baixo
GP17LED: HDD SaudávelAtivo baixo
GP18LED: LeituraAtivo baixo
GP19LED: EscritaAtivo baixo
FileLinesPurpose
main.c210Inicialização, standby inativo, suspensão/retomada USB
msc_device.c400Callbacks USB MSC, ativação de corte de energia, cache de setor ruim
ata_sdio.c390Comandos ATA, recuperação de erros, diagnósticos de fornecedor
sdio_pio.c635PIO SDIO: CMD52, CMD53 leitura/escrita, troca de programa, CRC16
sdio_hw.c45Inicialização de pinos + controle de energia do HDD
sdio.pio200Montagem PIO + auxiliares de inicialização SDK C
led.h37Auxiliares de LED (GP16–GP19, ativo baixo)
usb_descriptors.c77Descritores de dispositivo/configuração/string USB
tusb_config.h20Configuração TinyUSB (MSC, buffer EP de 32KB)
VersionReadWriteKey Change
v0.1–v0.3105 kB/s93 kB/sSDIO bit-bang, CRC16, lógica de retry
v0.5374 kB/s—PIO SM único, troca direta de memória de instrução
v0.6583 kB/s93 kB/sLeituras CMD53 multi-bloco, correção de dreno de clock CRC
v0.8588 kB/s274 kB/sEscritas PIO, correção de liberação OSR
v0.9475 kB/s371 kB/sBlocos de 64 setores, verificação de leitura CRC16
v0.10453 kB/s329 kB/sRemapeamento de LED, pino HDD EN, UART em GP12/GP13
v0.11~450 kB/s~340 kB/sCorte de energia HDD, ativação PIO, sense de setor ruim, suspensão USB
v0.12~985 kB/s~920 kB/sSobreposição Drive/USB (pré-busca de leitura + cache de escrita anunciado com escrita posterior), blocos PIO em pipeline, DMA bswap, loops PIO de 4 ciclos, semântica de setor ruim estilo SBC (reparo por escrita), driver MSC TinyUSB fornecido