Device Tree.

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

  • Базовый синтаксис дерева устройств и его компиляция.
  • Простой пример фрагмента дерева устройств.
  • Полная организация дерева устройств.
  • Пример использования дерева устройств.
  • Общие соображения о дереве устройств в Linux.

Возможности пользователя: до дерева устройств.

  • Ядро включает полное описание аппаратной платформы.
  • Загрузчик загружает одиночный бинарный файл, образ ядра, и выполняет это файл — uImage или zImage.
  • Загрузчик подготавливает некоторую дополнительную информацию, вызывает ATAGS, адрес ядра передается в регистр r2. Дополнительную информация — мета информация такая как, размер памяти и расположение, командная строка ядра, и др.
  • Загрузчик говорит ядру для этой платы, это загрузиться через целей машинный тип данных (integer), передав в регистр r1.
  • U-Boot команда: bootm < адрес образа ядра >
  • Barebox переменная: bootm.image

device_tree_1

Возможности пользователя: загрузка с деревом устройств.

  • Ядро не длиннее содержания описания аппаратной части, дерево устройств расположено в отдельном бинарном файле: device tree blob.
  • Загрузчик загружает два бинарных файла: образ ядра и DTB. Название образа ядра остается uImage или zImage. DTB расположено в arch/arm/boot/dts, один файл для платы «название платы».dtb.
  • Загрузчик передает DTB адрес через r2. Это предложено чтобы приспособить DTB с информацией о памяти, командной строкой ядра и потенциально другой информацией.
  • Нет больше машинного типа.
  • bootm < адрес образа ядра > — < dtb адрес >.
  • Barebox переменная: bootm.image, bootm.oftree.

device_tree_2

Возможности пользователя: режим совместимости для DT загрузки.

  • Некоторые загрузчики имеют не специфичную поддержку для дерева устройств, или версия использования для контрактного устройства уже устарела, но должна поддерживаться.
  • Упрощен переход, был добавлен совместимы механизм: CONFIG_ARM_APPENDED_DTB. Сообщаем ядру посмотреть на DTB после образа ядра. Нет встроенного правила для Makefile чтобы собрать такое ядра, так что, процедуру нужно делать вручную. cat arch/arm/boot/zImage arch/arm/boot/dts/myboard.dtb > my-zImage
    mkimage … -d my-zImage my-uImage
  • Кроме того, дополнительная опция CONFIG_ARM_ATAG_DTB_COMPAT сообщает ядру прочитать ATAGS информацию из загрузчика и обновить DT, используя данную информацию.

Что такое дерево устройств?

  • Цитируемым из Power.org стандарт требований для встраивания мощных архитектурных платформ (Standard for Embedded Power Architecture Platform Requirements — ePAPR)
  • ePAPR спецификация — это концепция вызова дерева устройств в описании системного железа (платформы, аппаратной части). Загрузчик загружает дерево устройств в память клиентской программы и отдает указатель на дерево устройств клиенту.
  • ePAPR совместимое дерева устройств описывает информацию об устройстве в системе, что не может быть динамически определено с помощью клиентской программы.

Синтаксис базового дерева устройств.

device_tree_3

Путь от исходного файла к бинарному.

  • На всех ARM, все исходные файлы дерева устройств (Device Tree Source — DTS) имеют следующее расположение arch/arm/boot/dts. .dts
    файлы уровня описания платформы. .dtsi файлы включают файлы, как правило содержащие уровень SoC описания.
  • Инструмент, компилятор дерева устройств (Device Tree Compiler) компилирует из исходных файлов, бинарный файл. Исходных код расположен в scripts/dtc.
  • DTB создает компилятор, и бинарный файл загружается через загрузчик, в свою очередь его анализирует ядро во время загрузки.
  • arch/arm/boot/dts/Makefile содержит список DTB которые должны быть собраны.

Простой пример дерева устройств.

Сопоставимая строка используемая для связывания устройства с драйвером.

Пример взят из drivers/tty/serial/mxs-auart.c

  • of_match_device позволяет получить сопоставимый вход для таблицы mxs_auart_dt_ids.
  • Полезно получать драйвер-спецификацию поля data, типичное использование изменение поведение драйвера зависящего от различных вариантов подключенных устройств.

  • Получение описания тактирования. Описание свойств тактирования. s->clk = clk_get(&pdev->dev, NULL);
  • Получение ресурсов Вх./Вых. регистров. Описание свойств регистров. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  • Получение прерывания. Описание свойств прерывания. s->irq = platform_get_irq(pdev, 0);
  • Получение DMA канала. Описание свойств DMA. s->rx_dma_chan = dma_request_slave_channel(s->dev, «rx»); s->tx_dma_chan = dma_request_slave_channel(s->dev, «tx»);
  • Проверка некоторых пользовательских свойств. struct device_node *np = pdev->dev.of_node; if (of_get_property(np, «fsl,uart-has-rtscts», NULL))

Присоединение дерева устройств.

  • Файлы дерева устройств не монолитны, они могут быть разделены на несколько частей в нескольких файлах, включая каждый из них.
  • .dtsi файлы включают файлы платформы, пока .dts файлы не определят конечный вид дерева устройств.
  • Типичная связь, .dtsi файлы будут включать информацию для SoC уровня(или иногда общее определение к некоторым почти идентичным платам).
  • .dts файл включает информацию уровня отладочной платы (платы разработки).
  • Присоединение работает следующим образом, происходит наложение файлов описывающих платформу (включенных файлов в проект) и формирование единого описания для платформы.
  • Присоединение использует DT(Device Tree) оператор /include/, или с некоторых выпусков ядра, DTS через процессорную обработку #include (рекомендуется).

Пример присоединение дерева устройств.

device_tree_4

device_tree_5

Концепция присоединение дерева устройств.

  • Цитируем ePAPR: данный раздел содержит требования, известные как присоединение (привязки) для специфики типов и классов устройств, представленных в дереве устройств.
  • Совместимое свойство узла устройства описывает специфическое связывание, к которому соответствует узел.
  • При создании нового представления дерева устройств для аппаратной платформы, должна быть создана привязка, которая полностью описывает требуемые свойства и значения устройства. Этот набор свойств должен быть достаточно описательным, чтобы обеспечить драйвер устройства с необходимыми атрибутами устройств.

Документация по связям дерева устройств.

  • Все дерево устройств имеет связи в ядре и имеет описание в документации Documentation/devicetree/bindings.
  • Каждая связь в документации описывает какие свойства могут быть разрешены, с какими значениями, какие свойства обязательные, а какие свойства используются опционально.
  • Все новые связи дерева устройств должны быть описаны в поддержке дерева устройств, и после отправлено на devicetree@vger.kernel.org. Должна гарантироваться корректность и последовательность через связи.

Пример по связям дерева устройств.

Организация дерева устройств на наивысшем уровне описания узла.

Под корнем дерева устройств, используется следующая организация уровня узла дерева устройств:

  • Узел cpus(центрального процессора), который имеет под-узел описания кажущего CPU в системе.
  • Узел memory(узел памяти), который определяет расположение и размер ОЗУ(RAM).
  • Узел chosen(выбора), который определяет параметры выбора или определения времени загрузки системной прошивки. В практике, используется для передачи управления командной строки ядра.
  • Узел aliases(прозвища), по сути дела определение горячих клавиш для основного узла.
  • Один или много узлов определения шин в SoC (система на кристалле).
  • Один или много узлов определения устройств платы.

Организация дерева устройств на imx28.dtsi.

Организация дерева шин в i.MX28.

device-tree-bus

Организация дерева устройств на imx28.dts.

Верхний уровень совместимости свойств.

  • Верхний уровень совместимости свойств в основном описывается совместимой строкой для платы, и для SoC.
  • Значение всегда дается в первом случае в наиболее корректной форме, в последнем случае наименее корректной форме (не специфичной).
  • Использование соответствия с dt_compat поля DT_MACHINE структуры.

  • Можно всегда использовать с кодом для тестирования платы.

Шины, адреса ячеек и размер ячеек.

Для внутренней шины необходимо определить следующие свойства:

  • Совместимые свойства, которые идентифицируют контроллер шины (для случаев I2C, SPI, PCI и других). Особое значение compatible = «simple-bus» способствует простой адресации памяти шины для не специфического обработчика или драйвера. Узел-ребенок может быть зарегистрирован для платформы.
  • Свойство #address-cells показывает, сколько ячеек памяти (32 битных значений) необходимо для части базовой адресации для свойств reg.
  • #size-cells одинаковый, для части размера свойства reg.
  • В свойство ranges(диапазон) может описываться адрес трансляции между шиной-ребенок и шиной-родитель. Когда просто объявляется диапазон, простое объявление имеет ввиду что транслятор идентифицирует трансляцию.

simple-bus, адреса ячеек и размер ячеек.

Шина I2C, адреса ячеек и размер ячеек.

Обработка прерываний.

  • interrupt-controller (контроллер прерывания) бинарное свойство, показывает что текущий узел контроллер прерывания.
  • #interrupt-cells (ячейка прерывания) показывает номер ячеек в свойстве прерываний, для менеджера прерываний, с помощью выбора контроллера прерывания.
  • interrupt-parent (родитель-прерывания) phandle указатель на контроллер прерывания для текущего узла. Основной наивысший уровень родитель-прерывания описывает поведение для главного контроллера прерывания.

Пример прерывания imx28.dtsi.

Пример совместимости на Tegra 20.

tegra-20

Пример прерывания tegra20.dtsi.

Пример прерывания tegra20-harmony.dts.

Пример дерева тактирования, Marvell Armada XP.

device-tree-clock

Создание экземпляра объекта тактирования.

Пример тактирования: распределение тактирования.

CPU, использует cpuclk

Таймер, использует один из 2-х сигналов тактирования coreclk или refclk.

USB, использует gateclk

Связи pinctrl: клиентская сторона.

  • Подсистема pinctrl позволяет управлять мультиплексированием ног микропроцессора.
  • В дереве устройств, ноги микропроцессора должны быть мультиплексированы и для них должна быть объявлена конфигурация pinctrl.
  • pinctrl- — свойства позволяющие дать список pinctrl, конфигурация нужная для основного состояния устройства.
  • pinctrl-names свойство позволяющее дать имя каждому состоянию.
  • Когда устройство проверено, начальное pinctrl состояние использует определение по умолчанию, после, состояние определяется с помощью запроса.

Конфигурация pinctrl.

  • Конфигурация pinctrl предоставляет список ножек микроконтроллера и их конфигурацию.
  • Подобная конфигурация определяет под-узел pinctrl устройства, для одного из уровня, уровня SoC или уровня платы.
  • Связи для такой конфигурации очень зависят от спецификации pinctrl используемого устройства.

i.MX28

Marvell Kirkwood

DT — описание железа, не конфигурация.

  • Дерево устройств — настоящий язык описания железа.
  • Необходимо описать уровень(слой) железа и понимать как это работает.
  • Но нет конкретного описания, конфигурации, железа нацеленного именно под ваши интересы.
  • Для примера. Вы можете описать DT который может использовать DMA или Вы наоборот можете не использовать DMA. Также Вы можете не описывать DT для DMA, если в DMA нет необходимости.

DT связи для ABI(application binary interface — бинарный интерфейс приложений).

  • С тех пор как появилось дерево устройств, ядро операционной системы стало более независимое.
  • Данная оригинальная идея позволяет записать DTB на на различные устройства производителей, так же данный факт позволяет записать пользователю любой дистрибутив операционной системы.
  • Дерево устройств связано в DTB и после этого не может быть изменено.
  • Данная вещь обычно обозначает, что связь дерева устройств становиться частью ядра ABI, необходимо с осторожностью обращаться с данным функционалом.
  • Однако, разработчики ядра не понимают, что этого очень тяжело добиться и замедляют интеграцию драйверов.
  • На саммите ARM ядра ведутся дебаты по поводу упрощения правил. Добавляются дискуссионные вопросы для саммита ядра, и после публикуются отчеты.

Базовое руководство для проектирования связей.

  • Точная совместимость строки лучше, чем расплывчатая одна. У Вас есть драйвер который может быть наложен поверх вариантов T320 и T330 для Вашего железа. Вы можете временно использовать foo, t3xx для совместной строки описания. Плохая идея, что если T340 немного отличается, в широком смысле? Лучше будет использовать foo, t320 для обеих T320 и T330.
  • Не создавайте слишком большого описания деталей железа в дереве устройств. Когда две платформы отличаются незначительно, разработчики могут добавить все изменения в дерево устройств, это может быть включаемые регистры смещения, битовые маски или др.
  • Плохая идея: создавать связи для большого комплекса устройств, это может привести к проблемам в будущем. Для этого лучше использовать 2 строки совмещения и обработчик для различных устройств.

Направление развития на будущее.

  • Построения более разнообразных вариантов подсистем связей дерева устройств.
  • Инструмент который проверит систему дерева устройств.
  • Уменьшить количество вычислений за пределами ядра.