Команда 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.
☑️ Проверка результата декомпиляции
Чтобы убедиться, что декомпиляция прошла корректно, выполните обратное преобразование и сравните размеры файлов — они должны быть близки, хотя побайтовое совпадение не гарантируется из-за выравнивания данных:
dtc -I dts -O dtb -o check.dtb decompiled.dts
Что теряется при обратной конвертации
Декомпилированный DTS функционально эквивалентен оригиналу, но текстуально отличается. Понимание этих отличий избавит от ложных тревог при сравнении файлов.
- 🔤 Метки узлов — вместо читаемых имён вида
uart0: serial@...могут появиться автоматические метки, а ссылкиphandleбудут показаны как числовые значения. - 💬 Комментарии — не сохраняются в бинарнике и не восстанавливаются.
- 📎 Директивы препроцессора —
#includeи макросы вродеGPIO_ACTIVE_HIGHзаменяются вычисленными числовыми значениями. - 🧩 Структура dtsi — разбиение на подключаемые файлы теряется, всё собирается в один плоский DTS.
- 🔢 Формат чисел — значения могут выводиться в шестнадцатеричном виде там, где в оригинале были десятичные.
⚠️ Внимание: числовые значения
phandleи флагов в декомпилированном файле — это уже вычисленные константы. Перед правкой сверьтесь с документацией на ваш SoC, что означает каждое число, иначе легко задать неверный режим пина или уровень триггера прерывания.
Извлечение 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-окружении, включая виртуальную машину.