Конвертация DTB в DTS: инструкция по декомпиляции Device Tree

Команда dtc -I dtb -O dts -o output.dts input.dtb преобразует бинарный файл Device Tree Blob обратно в текстовый исходник DTS — это стандартный способ посмотреть, какое описание оборудования реально загружает ядро Linux на вашем устройстве. Такая декомпиляция нужна, когда исходники дерева устройств утеряны, когда требуется проверить, какой DTB прошит в boot-разделе, или когда вы портируете прошивку на другую плату и хотите понять, как настроены узлы периферии.

Обратное преобразование не восстанавливает оригинальный файл один в один: комментарии, метки узлов в исходном виде и директивы препроцессора (#include, макросы) при компиляции в DTB теряются безвозвратно. Но вся функциональная информация — структура узлов, свойства, значения регистров, прерывания, тактовые частоты — сохраняется полностью и доступна для чтения и правки.

Что такое DTB и DTS и чем они отличаются

DTS (Device Tree Source) — это текстовый файл, который человек пишет и редактирует. Он описывает аппаратную конфигурацию: какие у процессора ядра, где в адресном пространстве находятся контроллеры, какие GPIO задействованы под кнопки и светодиоды. Из одного DTS через директиву #include могут подключаться файлы .dtsi с общими описаниями SoC.

DTB (Device Tree Blob) — результат компиляции DTS утилитой dtc. Это компактный бинарный формат, который загрузчик (например, U-Boot) передаёт ядру Linux при старте. Ядро читает DTB и на его основе инициализирует драйверы устройств, не зашивая описание железа в сам код.

Ключевой момент: компиляция DTS → DTB — это дорога в одну сторону с точки зрения удобства чтения. Именно поэтому обратная конвертация dtb to dts — рабочий инструмент разработчика встраиваемых систем, а не экзотика.

Установка компилятора device-tree-compiler

Утилита dtc входит в пакет device-tree-compiler и есть в репозиториях практически всех дистрибутивов Linux. На Debian, Ubuntu и производных установка выполняется одной командой:

sudo apt install device-tree-compiler

На Fedora и RHEL-подобных системах пакет называется dtc и ставится через dnf. Если вы работаете на самом встраиваемом устройстве с Linux, проверьте наличие утилиты командой which dtc — в минимальных сборках её может не быть, и проще скопировать DTB на рабочую машину.

Проверить, что установка прошла успешно, можно запросом версии:

dtc --version

Пошаговая конвертация DTB в DTS

Сам процесс декомпиляции занимает одну команду. Синтаксис у dtc такой: флаг -I задаёт формат входа, -O — формат выхода, -o — имя результирующего файла.

dtc -I dtb -O dts -o decompiled.dts original.dtb

После выполнения откройте полученный файл в любом редакторе. Вы увидите стандартную структуру: корневой узел /, секции cpus, memory, chosen и узлы периферии со свойствами вида compatible, reg, status.

☑️ Проверка результата декомпиляции

Выполнено: 0 / 5

Чтобы убедиться, что декомпиляция прошла корректно, выполните обратное преобразование и сравните размеры файлов — они должны быть близки, хотя побайтовое совпадение не гарантируется из-за выравнивания данных:

dtc -I dts -O dtb -o check.dtb decompiled.dts

Что теряется при обратной конвертации

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

  • 🔤 Метки узлов — вместо читаемых имён вида uart0: serial@... могут появиться автоматические метки, а ссылки phandle будут показаны как числовые значения.
  • 💬 Комментарии — не сохраняются в бинарнике и не восстанавливаются.
  • 📎 Директивы препроцессора#include и макросы вроде GPIO_ACTIVE_HIGH заменяются вычисленными числовыми значениями.
  • 🧩 Структура dtsi — разбиение на подключаемые файлы теряется, всё собирается в один плоский DTS.
  • 🔢 Формат чисел — значения могут выводиться в шестнадцатеричном виде там, где в оригинале были десятичные.

⚠️ Внимание: числовые значения phandle и флагов в декомпилированном файле — это уже вычисленные константы. Перед правкой сверьтесь с документацией на ваш SoC, что означает каждое число, иначе легко задать неверный режим пина или уровень триггера прерывания.

📊 Для какой задачи вам понадобилась конвертация DTB в DTS?
Портирование прошивки на другую плату
Анализ чужого DTB без исходников
Отладка — ядро не видит устройство
Изучение Device Tree в учебных целях

Извлечение DTB из прошивки или с работающего устройства

Часто готового файла .dtb под рукой нет — он зашит в boot-раздел или живёт только в памяти запущенной системы. На работающем устройстве с Linux дерево устройств доступно через виртуальную файловую систему: каталог /proc/device-tree (он же /sys/firmware/devicetree/base) содержит все узлы и свойства в виде файлов.

Скопировать живое дерево в DTS можно прямо из этого каталога, указав его как источник в формате fs:

dtc -I fs -O dts -o running.dts /proc/device-tree

Если нужен DTB из образа прошивки Android или кастомной сборки, файл обычно лежит в boot-образе либо в отдельном разделе dtb/dtbo. Способ извлечения зависит от устройства и формата образа, поэтому сверяйтесь с документацией конкретной платформы. Для boot-образов Android существуют инструменты распаковки, но их применимость различается между версиями загрузчика.

Почему /proc/device-tree может отличаться от файла на диске

Загрузчик может патчить дерево перед передачей ядру: подставлять объём памяти, параметры командной строки в узел chosen, отключать узлы. Поэтому «живое» дерево отражает фактическую конфигурацию, а не исходное содержимое DTB-файла.

Типичные ошибки и их решение

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

СимптомВероятная причинаЧто сделать
dtc выдаёт syntax error при компиляции DTSПропущена точка с запятой или скобка после правкиПроверить строку из сообщения об ошибке
Ядро не видит устройство после замены DTBСвойство status стоит в disabledУстановить status = "okay" у нужного узла
Устройство есть в дереве, но драйвер не цепляетсяСтрока compatible не совпадает с тем, что ищет драйверСверить compatible с документацией ядра
dtc: неизвестный формат входаОпечатка во флагах -I/-OИспользовать ровно dtc -I dtb -O dts
Ссылки на узлы выглядят как числаМетки потеряны при декомпиляцииЭто норма; искать узел по phandle-значению

⚠️ Внимание: перед заменой DTB на устройстве сохраните оригинальный файл и убедитесь, что у вас есть способ загрузиться со старой версией (recovery, UART-консоль, загрузка по сети). Повреждённое дерево устройств — частая причина того, что плата перестаёт стартовать, и без запасного пути восстановление может оказаться трудоёмким.

Практические сценарии использования

Знание обратной конвертации пригождается в нескольких реальных ситуациях. Первая — аудит чужой прошивки: вы достаёте DTB из готового образа, декомпилируете и видите, какие узлы включены, какие частоты и напряжения заданы регуляторам. Это быстрее, чем искать исходники, которых может и не быть в открытом доступе.

Второй сценарий — отладка. Когда драйвер сообщает, что не нашёл устройство, сравнение «живого» дерева из /proc/device-tree с вашим исходным DTS показывает, доехали ли ваши изменения до ядра или загрузчик подсунул другой DTB.

Третий случай — миграция между версиями ядра. Декомпилированный DTS от старой прошивки служит референсом: вы переносите узлы в актуальные .dtsi нового ядра, сверяя compatible и привязки (bindings), которые могли измениться между версиями.

FAQ: частые вопросы о конвертации DTB в DTS

Можно ли получить из DTB оригинальный DTS с комментариями?

Нет. Комментарии, макросы и структура include-файлов не сохраняются в бинарном формате. Декомпиляция даёт функционально полный, но текстуально «плоский» файл.

Чем отличаются DTB и DTBO?

DTBO — это overlay, накладка поверх основного дерева устройств, которая изменяет отдельные узлы без пересборки всего DTB. Декомпилируется он той же командой dtc -I dtb -O dts.

Почему после декомпиляции вместо имён узлов числа?

Метки узлов — удобство исходного формата. В бинарнике ссылки превращаются в числовые phandle, и dtc при обратной конвертации показывает именно их. На работоспособность это не влияет.

Можно ли редактировать декомпилированный DTS и прошивать обратно?

Да, это стандартная практика: правите DTS, компилируете командой dtc -I dts -O dtb и заменяете файл на устройстве. Обязательно сохраните резервную копию оригинала и продумайте способ отката.

Работает ли dtc на Windows?

Нативно утилита ориентирована на Linux, но её можно запустить через WSL или собрать из исходников. Проще всего выполнять конвертацию в Linux-окружении, включая виртуальную машину.