Device Tree

ARM-компьютеры, в отличие от «классических» x86_64, используют специальный компонент под названием SoC (System on Chip), включающий в себя процессор и много других устройств, которые находятся на одной, как правило небольшой, микросхеме. К таким компьютерам можно отнести, к примеру, Raspberry Pi, Orange Pi, Banana Pi, Repka Pi, Pinebook и т.д.

SoC нуждается разве что во внешнем ОЗУ и некоторой периферии или разъёмов для подключения этой периферии, при этом SoC реализует в себе множество возможных, а иногда и взаимоисключающих конфигураций устройств. Таким образом, в системе должен быть механизм, позволяющийй передать ядру Linux информацию о том, какая из конфигураций соответствует тому, что распаяно на материнской плате. Данным механизмом является Devicetree.

Важно понимать, что Devicetree — это не что-то очень крупное и сложное, а всего лишь формат описания конфигурации оборудования компьютера. Ядро читает эту конфигурацию для обнаружения нужного оборудования в компьютере и, таким образом, обеспечивает поддержку только тех устройств, которые описаны в файле Devicetree (при условии наличия драйверов для этих устройств).

Файлы

*.dts

Файл с расширением *.dts — представление дерева устройств в человекочитабельном текстовом формате, синтаксис которого похож на JSON. Компилируется программой dtc в бинарный файл *.dtb.

Пример содержимого *.dts:

/dts-v1/;

/ {
  interrupt-parent = <0x01>;
  #address-cells = <0x01>;
  #size-cells = <0x01>;
  model = "OrangePi 3 LTS";
  compatible = "xunlong,orangepi-3-lts\0allwinner,sun50i-h6";

  aliases {
    mmc0 = "/soc/mmc@4020000";
    mmc1 = "/soc/mmc@4021000";
    mmc2 = "/soc/mmc@4022000";
    ethernet0 = "/soc/ethernet@5020000";
    serial0 = "/soc/serial@5000000";
  };

  cpus {
    #address-cells = <0x01>;
    #size-cells = <0x01>;

    cpu@0 {
      compatible = "arm,cortex-a53";
      device_type = "cpu";
      reg = <0x00>;
      enable-method = "psci";
      clocks = <0x06 0x15>;
      clock-latency-ns = <0x3b9b0>;
      #cooling-cells = <0x02>;
      operating-points-v2 = <0x07>;
      cpu-supply = <0x08>;
      phandle = <0x0a>;
    };
    ...
  };
  ...
}

*.dtb

*.dtb — уже двоичное (бинарное) представление информации из файла *.dts, которое читается ядром Linux.

*.dtbo (overlay)

В дистрибутивах Raspbian и Armbian есть механизм, позволяющий во время загрузки применять к *.dtb-файлам патчи. Такой патч, содержащий какую-либо аппаратную возможность платы, называется overlay. Формат такого файла идентичен формату *.dtb. Обычно расположены в директории /boot/dtb/<имя SoC>/overlay.

Пример содержимого /boot/dtb/<имя SoC>/overlay/:

$ ls /boot/dtb/allwinner/overlay
sun50i-a64-fixup.dtbo             sun50i-h6-fixup.dtbo
sun50i-a64-pine64-7inch-lcd.dtbo  sun50i-h6-i2c1.dtbo
sun50i-a64-pps-gpio.dtbo          sun50i-h6-i2c2.dtbo
sun50i-a64-uart1.dtbo

Откуда брать эти файлы

В новых версиях ядра существует целая библиотека с ванильными *.dt{b,s} файлами для многих известных компьютеров на архитектуре ARM. Для компиляции этих файлов (нужна программа dtc) , которые находятся в дереве исходного кода Linux, введите:

make CROSS_COMPILE=$LFA_TGT- ARCH=arm64 dtbs

В зависимости от параметров, указанных при конфигурировании ядра (в частности, в зависимости от того, поддержку каких SoC вы включили/отключили), будут скомпилированы нужные файлы *.dtb. После их компиляции вам нужно будет создать в директории /boot поддиректорию, в которую будут скопированы эти файлы.

Если в составе ядра нет *.dts-файла для вашего компьютера, то попробуйте взять его из дстрибутива (Armbian, Raspbian, etc.), где этот файл есть. Однако я не могу гарантировать в этом случае полную работоспособность системы с «чужим» файлом описания устройств.


Смотрите также: