Device Tree: различия между версиями
Pauli (обсуждение | вклад) м (→*.dtb файл) |
|||
(не показаны 2 промежуточные версии 1 участника) | |||
Строка 2: | Строка 2: | ||
Данная статья посвящена механизму описания структуры периферии, использующемуся в частности в ядре Linux для архитектур [[Ports/arm|armh]] и [[Ports/aarch64|aarch64]]. | Данная статья посвящена механизму описания структуры периферии, использующемуся в частности в ядре Linux для архитектур [[Ports/arm|armh]] и [[Ports/aarch64|aarch64]]. | ||
Одноплатные компьютеры семейств [[RaspberryPi]] | Одноплатные компьютеры семейств [[RaspberryPi]], ''OrangePi'', [[RBS_RepkaPi_3|Repka Pi3]] и многие прочие подобные используют в качестве процессора микросхему - систему на кристалле (SoC). Микросхема SoC нуждается только во внешнем ОЗУ, при этом она реализует в одном чипе множество возможных, часто взаимоисключающих конфигураций периферии интерфейсов ввода-вывода. | ||
Таким образом должен быть механизм, позволяющий передать ядру, какая из конфигураций соответствует тому, что распаяно на печатной плате, а также какое поведение инженер-разработчик ожидает от внешних универсальных контактов (штырьков) ввода-вывода платы (GPIO). Данным механизмом и является описываемое здесь дерево устройств - '''Device Tree'''. | Таким образом должен быть механизм, позволяющий передать ядру, какая из конфигураций соответствует тому, что распаяно на печатной плате, а также какое поведение инженер-разработчик ожидает от внешних универсальных контактов (штырьков) ввода-вывода платы (GPIO). Данным механизмом и является описываемое здесь дерево устройств - '''Device Tree'''. | ||
Строка 8: | Строка 8: | ||
= Форматы файлов = | = Форматы файлов = | ||
== *.dtb файл == | == *.dtb файл == | ||
Device Tree Binary - иерархическое описание структуры периферии в бинарном формате. Именно в таком формате оно | Device Tree Binary - иерархическое описание структуры периферии в бинарном формате. Именно в таком формате оно подгружается в ядро Linux в качестве аргумента через загрузчик. Ядро использует структуру, чтобы узнать о периферийных устройствах - какие включены, какие модули ядра задействовать, символические имена. | ||
== *.dts файл == | == *.dts файл == | ||
Device Tree Strings - представление дерева устройств в человекочитаемом формате. Синтаксис языка похож на JSON. Для связи с описанием в *.dtb формате используется утилита '''dtc'''. | Device Tree Source (aka Strings) - представление дерева устройств в человекочитаемом формате, в виде исходного кода. Синтаксис языка похож на JSON. Для связи с описанием в *.dtb формате используется утилита '''dtc'''. | ||
== Компилятор/декомпилятор '''dtc'''== | == Компилятор/декомпилятор '''dtc'''== | ||
Строка 57: | Строка 57: | ||
status = "okay"; | status = "okay"; | ||
} | } | ||
== Ссылки == | |||
* [https://beagleboard.org/blog/2022-02-15-using-device-tree-overlays-example-on-beaglebone-cape-add-on-boards Using Device Tree Overlays, example on BeagleBone Cape add-on boards] | |||
* [https://www.kernel.org/doc/html/latest/devicetree/usage-model.html Linux kernel: devicetree] |
Текущая версия от 17:07, 11 мая 2024
Введение
Данная статья посвящена механизму описания структуры периферии, использующемуся в частности в ядре Linux для архитектур armh и aarch64.
Одноплатные компьютеры семейств RaspberryPi, OrangePi, Repka Pi3 и многие прочие подобные используют в качестве процессора микросхему - систему на кристалле (SoC). Микросхема SoC нуждается только во внешнем ОЗУ, при этом она реализует в одном чипе множество возможных, часто взаимоисключающих конфигураций периферии интерфейсов ввода-вывода.
Таким образом должен быть механизм, позволяющий передать ядру, какая из конфигураций соответствует тому, что распаяно на печатной плате, а также какое поведение инженер-разработчик ожидает от внешних универсальных контактов (штырьков) ввода-вывода платы (GPIO). Данным механизмом и является описываемое здесь дерево устройств - Device Tree.
Форматы файлов
*.dtb файл
Device Tree Binary - иерархическое описание структуры периферии в бинарном формате. Именно в таком формате оно подгружается в ядро Linux в качестве аргумента через загрузчик. Ядро использует структуру, чтобы узнать о периферийных устройствах - какие включены, какие модули ядра задействовать, символические имена.
*.dts файл
Device Tree Source (aka Strings) - представление дерева устройств в человекочитаемом формате, в виде исходного кода. Синтаксис языка похож на JSON. Для связи с описанием в *.dtb формате используется утилита dtc.
Компилятор/декомпилятор dtc
Для работы с описанием дерева устройств предназначен компилятор dtc (пакет dtc).
Для конвертации бинарного дерева устройств в текстовое представление:
dtc $NAME.dtb -o $NAME.dts
Для компиляции текстового описания дерева устройств обратно в бинарное представление:
dtc $NAME.dts -o $NAME.dtb
Оверлеи *.dtbo
В специализированном дистрибутиве Raspbian реализован механизм, позволяющий во время загрузки накладывать на *.dtb файлы патчи. Такой патч, включающий какую-то аппаратную возможность платы, называется оверлеем. Формат файла - такой же, как у .dtb - файл можно прочитать при помощи утилиты dtc.
Файлы находятся в папке /boot/dtb/overlay системы Raspbian. Исследование их помогает понять, как исправить дерево устройств, чтобы включить какую-либо нужную фичу.
Вроде бы, загрузчик U-Boot умеет их применять. Данный вопрос требует дальнейшего исследования.
Настройки
Ванильные *.dtb файлы ядра
Вместе с ядром Linux (проверено для ядер для 5.*) поставляется библиотека *.dtb файлов под разные одноплатные компьютеры, модули и системы. При установке ядра файлы оказываются в папке
/lib/devicetree/`uname -r`
Для каждого чипа и платы имеется свой файл - одна и та же микросхема может оказаться на разных платах разных производителей.
Настройка устройств под себя
Конфигурации *.dtb, поставляемые вместе с ядром для каждой платы, описывают некоторую базовую конфигурацию, которая подойдёт всем. Учитывая настраиваемость платы, однако же, может потребоваться эту конфигурацию изменить. Для этого следует вскрыть *.dtb файл утилитой dtc, отредактировать его в *.dts формате и сохранить обратно. Какой из многих файлов загружается - можно посмотреть в выводе загрузчика U-Boot во время старта системы, этот файл будет единственный с именем, соответствующем модели платы.
Обновление ядра
Очевидна проблема - при обновлении ядра исправления будут утеряны. Это не является проблемой, если сборка подготавливается для встраиваемой системы, которую не будут обновлять. Иначе следовало бы написать скрипт, делающий исправления автоматически, и прописать его как-то в механизм /etc/initrd.mk. Эта секция требует уточнения.
Синтаксис
Синтаксис *.dts файла достаточно понятен (очевидно!) =) Лучший способ исследования - вскрыть файл и посмотреть, что там внутри.
Приглашаю всех практикующих инженеров писать сюда свои примеры ;)
Включение и отключение устройств
В исходном, "ванильном" дереве многие устройства описаны, но отключены. Примеры таких устройств - контроллеры шины i2c, контроллер uart (serial). Для включения устройства достаточно поправить один параметр.
Отключённое устройство имеет в своём описании поле:
{ status = "disabled"; }
Для включения устройства следует исправить:
{ status = "okay"; }