Привет, Хабр! Меня зовут Соколов Дмитрий, я – специалист Positive Labs. В этой статье я расскажу, как мы разработали новый адаптер для атаки DaMAgeCard, благодаря которому можно подключить NVMe-диск к новой приставке от Nintendo.

С выходом интерфейса SD Express всё больше производителей начинают использовать его в своих устройствах. Nintendo Switch 2 – не исключение. Этот интерфейс позволяет запускать игры прямо с карты памяти за счёт значительно возросшей пропускной способности – спасибо PCIe. Но интересен он не только геймерам. В одной из наших ранних публикаций мы уже рассказывали о DMA атаках, связанных с SD Express. Данную атаку мы назвали DaMAgeCard и разработали адаптер для подключения в слот SD Express. Названия у него нет, пусть это будет «Express to PCIe». Чтобы сохранить формат статьи как «easy read», всю более подробную информацию я добавлю в спойлеры.

Express to PCIe

Кратко опишу принцип работы адаптера из прошлой статьи. Основная идея – заставить хост воспринимать устройство как SD Express карту. На практике это требует корректной реакции на процедуру инициализации и соблюдения временных параметров. В адаптере Express to PCIe мне удалось реализовать эмуляцию SD интерфейса для прохождения процедуры инициализации с помощью Raspberry Pi Pico. Однако при работе с Switch появились дополнительные сложности, связанные с особенностями инициализации и поведением хоста.

Проблемы, с которыми столкнулся при отладке

  1. На исходной плате не было выводов для подключения логического анализатора.

    Первая проблема решается просто – напаял проводов для снятия сигнала.

  2. На плате Pi Pico не хватало питания и она не стартовала.

    Вообще, адаптер всегда питается от SD-слота, но тут пришлось добавить питание через USB-кабель напрямую на Pi Pico.

  3. В процессе инициализации хост посылал дополнительные команды.

    Изначально мой подход для определения необходимых команд, на которые требуется ответить для инициализации, выглядел так:

    Мой вечный цикл...
    Мой вечный цикл...

    Каждый раз, обнаруживая новую команду от хоста, мне приходилось добавлять корректный ответ в код моей программы на Pi Pico.

    Спойлер

    До того как мне в руки попался Switch, все устройства принимали примитивное поведение адаптера, который для инициализации слал корректный ответ только на команду CMD8. Именно в этой команде указывается поддержка питания 1.8 В. После этого хост опускает линию PERST#, а мы в этот момент подтягиваем линию CLKREQ к земле. Данное поведение устраивало как различные ноутбуки, так и китайскую приставку AYANEO.

    Ответ на CMD8
    Ответ на CMD8

    Но Switch-у не достаточно ответа на CMD8. Он отправляет большую вереницу команд, на которые ожидает корректного ответа.

    Видим, что ответа на CMD8 приставке не достаточно, и она продолжает инициализацию
    Видим, что ответа на CMD8 приставке не достаточно, и она продолжает инициализацию
    Общий вид инициализации Switch
    Общий вид инициализации Switch

    При инициализации очень часто повторяется команда проверки готовности карты. Но даже если отбросить эти запросы хоста, пул команд, которые он шлет, не маленький.

  4. Хост переключает карту с 400 кГц на 25 МГц и не только.

    Мой код для Express to PCIe был написал на GPIO. Этого хватало, так как весь цикл инициализации происходил на частоте 400 кГц, а частота работы МК в Pi Pico – 133 МГц. Но в случае увеличения частоты SDIO интерфейса до 25 МГц или более – этого не достаточно, даже с учетом разгона МК. Для решения данной проблемы можно было бы переписать код на PIO, но я этого не стал делать, так как заметил еще одну проблему...

    Спойлер

    Согласно документации, инициализация карты памяти происходит на частоте 400 кГц, но хост вправе сменить скорость, что и демонстрирует приставка. Причем переключение происходит несколько раз и каждый раз с повышением частоты интерфейса.

    Начальная частота инициализации
    Начальная частота инициализации
    Хост решил перейти на частоту 25 МГц
    Хост решил перейти на частоту 25 МГц
    А тут уже и все 50 МГц
    А тут уже и все 50 МГц

    Использование стандартных GPIO на RP2040 (МК в Pi Pico) не подходит для работы на частоте 50 МГц. Управление выводами в этом случае выполняется программно, через ядро Cortex-M0+, где каждая операция зависит от длительности инструкций, состояния кеша и обслуживания прерываний. Это приводит к джиттеру и недетерминированным задержкам, из-за чего стабильная генерация сигнала на десятках МГц становится невозможной.

    В отличие от этого, PIO – это специализированный аппаратный блок с собственным тактированием и минимальным набором инструкций, исполняемых детерминированно, синхронно с системной частотой. PIO позволяет формировать точные временные последовательности, генерировать или принимать сигналы с фиксированной частотой и фазой, полностью разгружая центральное ядро. Поэтому при необходимости работы на частотах порядка десятков мегагерц (например, 50 МГц) надёжная реализация возможна только с использованием PIO.

  5. Уровень напряжения сигнала понижается с увеличением частоты.

    Основная проблема, которая поставила крест на решении моей задачи с помощью адаптера Express to PCIe. При повышении частоты до 25 МГц, уровень напряжения сигнала меняется с 3.3 В до 1.8 В. Таким образом вход МК уже не гарантированно видит логическую единицу, и распознавание становится нестабильным. Именно поэтому нужно было разрабатывать новое решение.

  6. Хост отправляет команду CMD6, которая использует 512-битный ответ, отправляемый по всем линиям данных (DAT0-DAT3).

    Вдобавок к основной проблеме у нас не были выведены линии данных SD интерфейса на контакты Pi Pico.

    Спойлер

    Команда CMD6 (Switch Function) в SD Express используется для переключения режимов работы карты и управления её функциональными параметрами. В классическом SD-режиме CMD6 управляет группами функций (Function Groups), определяющими поддерживаемые режимы карты – например, UHS-режимы, DDR-режим, дополнительные функции SDIO и т. д. Хост передаёт аргумент с нужными параметрами, а карта возвращает 512-битный (64-байтный) ответ, содержащий сведения о поддерживаемых, текущих и выбранных функциях.

    Ключевая особенность – ответ по команде CMD6 передаётся не по командной линии (CMD), а по линиям данных (DAT0-DAT3). Это позволяет передать больше информации (512 бит) и обеспечивает совместимость с другими командами, использующими тот же формат ответа.

    Таким образом, CMD6 – основная команда, с помощью которой хост согласует режим работы карты, проверяет успешность переключения и, в случае SD Express, инициирует переход в PCIe-интерфейс.

Выбор из двух стульев

Левый стул

  • Добавить недостающие линии данных к контроллеру;

  • Перейти от GPIO на PIO;

  • Разработать механизм переключения уровня сигналов при переходе хоста с 400 кГц на повышенные частоты;

  • Реализовать почти полноценный эмулятор SD Express карты.

Правый стул

  • Использовать реальную SD Express карту для инициализации;

  • После инициализации отключить PCIe линии от SD Express карты и подключить их на M.2 слот, в который будет вставлен NVMe-диск.

По выражению писателя Владимира Ильина в романе «Напряжение» (2015), «человек – он слаб и ленив по своей природе». Зачем писать громоздкий эмулятор, если можно переложить часть работы на настоящую карту памяти. Именно поэтому я выбрал правый стул. Так родился проект MegaSD.

MegaSD

Кратко о компонентах платы. В этот раз я постарался предусмотреть максимум возможных ситуаций, поэтому на плате есть:

  • слот для M.2 (NVMe);

  • слот для SD Express;

  • слот для microSD Express;

  • питание для NVMe-диска;

  • переключатель режима работы;

  • пины для логического анализатора.

Плата поддерживает два режима:

  1. Режим «M.2 disable» – обычная работа карты памяти. Позволяет снифать SDIO сигналы.

  2. Режим «M.2 enable» – переключение линий на слот M.2. Позволяет подключать NVMe-диск и не только вместо SD карты в таргет.

Принцип работы

Принцип простой – увидели 1.8 В на линии, предназначенной для питания карты этим напряжением, и с помощью мультиплексоров переключили нужные линии с SD карты на M.2 разъем.

Откуда 1.8 В?

Карта SD Express – это гибрид между SD и NVMe-устройствами. При запуске – это всегда SD устройство, поэтому хосту нужно общаться с картой при питании в 3.3 В, но как только хост убеждается в работоспособности карты как NVMe-устройства, он переключает режим ее работы, добавляя питание на 1.8 В. После этого карта памяти является NVMe-сущностью и общение хоста происходит через PCIe.

Спойлер

На рисунке ниже представлена типовая структурная схема реализации SD Express хоста. Видно, что интерфейс между хостом и картой имеет линию VDD2, по которой на SD Express карту поступает питание с напряжением 1.8 В. Но фишка в том, что это питание включается синхронно с переключением мультиплексора, отвечающего за коммутацию SDIO и PCIe линий.

Структурная схема SD Express хоста
Структурная схема SD Express хоста

Воспользуемся появлением напряжения 1.8 В как триггером для переключения. Когда хост включает линию питания 1.8 В и переходит в режим работы по PCIe-интерфейсу, необходимо переключить сигнальные линии карты с SD-интерфейса на линии разъёма M.2.

За коммутацию сигналов отвечают мультиплексоры, управляющие направлением линий. Детекция уровня 1.8 В выполняется парой транзисторов, которые подают питание на управляющие входы мультиплексоров. В результате происходит быстрое аппаратное переключение PCIe линий.

Схема детектирования 1.8 В
Схема детектирования 1.8 В

Данная схема предназначена для автоматического определения момента, когда хост включает питание карты напряжением 1.8 В. При отсутствии питания 1.8 В (режим обычной SD-карты) транзистор Q2 закрыт, поэтому затвор MOSFET Q1 подтянут к уровню 3.3 В через резистор R14. Питание карты напряжением 3.3 В здесь используется для дальнейшего управления мультиплексорами. В этом состоянии Q1 закрыт, и на выходе SWITCH_TO_M2 напряжение отсутствует – мультиплексоры остаются в положении SD-интерфейса.

Когда хост подключает напряжение 1.8 В, в базу Q2 через резистор R15 начинает течь ток. Транзистор Q2 открывается, притягивая затвор Q1 к земле через R16, тем самым открывая P-канальный MOSFET Q1. Через него напряжение 3.3 В поступает на SWITCH_TO_M2 – мультиплексоры переключаются в положение PCIe-интерфейса.

Зачем переключать линии?

Поскольку у карт SD Express количество выводов ограничено, а требуется поддержка как SD, так и PCIe интерфейсов, разработчики стандарта решили использовать часть контактов по двойному назначению.

В режиме SD выводы DAT0-DAT3 работают как линии передачи данных, а после перехода карты в режим PCIe эти же пины используются для сигналов REFCLK_P, REFCLK_N, CLKREQ# и PERST#.

Поэтому до подтверждения перехода в PCIe-режим все сигнальные линии остаются подключёнными к SD-интерфейсу, а после инициализации переключаются на разъём M.2, обеспечивая связь по PCIe.

Спойлер

Для наглядности работа мультиплексоров представлена в виде упрощённой структурной схемы.

На ней показано как сигнальные линии от хоста распределяются между слотами SD, microSD и разъёмом M.2, а также каким образом происходит автоматическое переключение режимов и определение активной карты.

Упрощенная структурная схема переключения линий
Упрощенная структурная схема переключения линий

Схема иллюстрирует принцип работы мультиплексоров, которые обеспечивают автоматическое переключение линий между SD-картой, microSD-картой и разъёмом M.2 (PCIe).

Левый мультиплексор выполняет переключение интерфейса между SD-режимом и PCIe-режимом (M.2). Он управляется сигналом 1.8В, который появляется, когда хост переключается в режим работы с картой по PCIe. При обнаружении этого напряжения мультиплексор перенаправляет линии с SD-интерфейса на разъём M.2.

Правый мультиплексор отвечает за выбор активного слота карты: SD или microSD. Управляющий сигнал Card Detect поступает от механического контакта разъёма microSD и определяет установлена ли карта microSD. Если microSD вставлена, линии данных направляются к ней, если нет – к стандартной SD-карте.

Таким образом, схема реализует двойное управление:

  1. Определяет какая карта активна: SD или microSD.

  2. Автоматически переключает интерфейс между SD и PCIe в зависимости от наличия питания 1.8 В.

Для переключения сигнальных линий были выбраны высокоскоростные дифференциальные мультиплексоры, рассчитанные на работу с интерфейсом PCIe Gen3. Эти микросхемы обеспечивают низкое сопротивление в открытом состоянии и минимальное время распространения сигнала, что критично для передачи данных на скоростях до 8 Гбит/с.

Дизайн

Форма платы выполнена в виде SD-карты – отсюда и название MegaSD.

Вид спереди
Вид спереди
Вид сзади
Вид сзади

Опыт использования

После изготовления платы нам не терпелось проверить её в деле, поэтому взяли первый попавшийся диск и стали включать.

Подключение MegaSD в Switch 2
Подключение MegaSD в Switch 2

При первом подключении Switch не смог использовать подключенный диск.

Приставка предлагает форматирование
Приставка предлагает форматирование

Нажимаем «Форматировать» и у нас возникает проблема: приставка не может отформатировать диск. И да, приставка не дает делать скрины своих ошибок. Спасибо, Nintendo.

Ошибка форматирования
Ошибка форматирования

Проблема решилась вручную: отформатировали диск на компьютере в exFAT (так же, как и на вставленной рядом карте) и решили указать разделу необычный размер – 372 ГБ.

Приставка видит наш диск
Приставка видит наш диск

И вот успех! Мы можем наблюдать, как на нашей приставке стала доступнаен карта диск объемом 372 ГБ. Но работает ли перенос данных? Для этого мы решили перенести два скриншота на данный диск.

И после прочтения данного диска убеждаемся, что все данные перенеслись (кстати, все скрины я сохранял именно на этот диск :)).

Свет клином не сошёлся на Switch

Хотя Nintendo Switch 2 и стала удобной платформой для тестирования, проект изначально задумывался как универсальный адаптер для любых устройств, поддерживающих SD Express. Switch здесь, скорее, стал причиной для разработки новой версии адаптера. Применение же самого адаптера не ограничено рамками консоли. Он спокойно работает с любыми хостами, где доступен SD Express – и тем самым открывает путь для дальнейших экспериментов.

Адаптер работает и с другими устройствами
Адаптер работает и с другими устройствами

Так что свет клином, как ни крути, на Switch не сошёлся.
Это лишь одно из множества применений устройства, которое изначально создавалось как универсальный инструмент для исследований и практических задач.

Заключение

Иногда небольшая «ленивость» – это путь к простому и надёжному решению. В нашем случае именно такой подход позволил создать адаптер, совместимый с устройствами, поддерживающими SD Express, без необходимости полностью эмулировать все алгоритмы инициализации карты на уровне прошивки.

Всё, что обычно требует сложной логики и программной обработки, здесь реализовано аппаратно. При этом всегда остаётся возможность подключить анализатор и захватить обмен сигналами между хостом и картой.

Исходники проекта есть в открытом доступе. Каждый сможет собрать такой адаптер для исследований игр. Теперь можно будет скачать ВСЕ игры. А нам этот адаптер пригодится дальше – в исследованиях безопасности устройств. Следите за новыми публикациями!

Комментарии (7)


  1. Alexsey
    28.10.2025 10:57

    Когда я вижу все эти sd express адаптеры у меня возникает главный вопрос что к китайцам, что к вам - почему коннектор microsd не сделан на гибком шлейфе? Ну кроме удешевления производства.


    1. aik
      28.10.2025 10:57

      В данном случае не вижу какого-то смысла - это же девкит, а не серийное устройство.


      1. Alexsey
        28.10.2025 10:57

        Ну как минимум в данной конструкции есть минус с тем что отломить/повредить microsd часть не составляет никакого труда, хорошо если вместе с этим не вырвется/повредится принимающий разъем. Даже для условного дев-кита мне кажется это важный нюанс, тем более учитывая размеры платы, которая выступает вполне неплохим таким рычагом.


        1. soko1ov_dmitry Автор
          28.10.2025 10:57

          При изготовлении гибко-жесткой печатной платы увеличиваются И стоимость И сроки изготовления. Нам хотелось как можно скорее проверить работоспособность данного решения. Ну и раз мы говорим про девкит, то девкит аккуратно лежит на столе, чтобы ничего не повредилось))


          1. Kirillko312
            28.10.2025 10:57

            Разъем ставим. И соединяем проводом


        1. aik
          28.10.2025 10:57

          В общем, уже всё сказали - просто аккуратно пользоваться надо.


  1. PoksPoks
    28.10.2025 10:57

    Крутое инженерное решение. Аппаратный подход проще и надежнее, чем эмуляция