Skip to content

FreeBSD и device tree overlays

Хочу рассказать простыми словами, т.е., как дилетант для другого дилетанта, то, что пришлось вычитывать, додумывать и подбирать достаточно длительное время: как собрать и использовать device tree overlays на SOC компьютере в ОС FreeBSD.

Для начала о програмно-аппаратном обеспечении:

CODE:
$ uname -a FreeBSD rpi2 12.0-CURRENT FreeBSD 12.0-CURRENT #8 r328806: Sat Feb  3 08:06:35 +04 2018     root@host.domain:/usr/obj/usr/src/arm.armv7/sys/RPI2_CUSTOM  arm

Т.е., это Raspberry PI 2 с 32-разрядной архитектурой armv7 под управлением ОС FreeBSD 12.0-CURRENT ревизия r328806 с кастомным ядром, собранной на другом ПК host.domain с архитектурой amd64 с помощью кросскомпиляции (Как это сделать, худо бедно, но описано в предыдущей статье).
Дисковое пространство организовано с помощью двух разделов (msdos и ufs):
CODE:
$ mount /dev/mmcsd0s2a on / (ufs, local, noatime, soft-updates) devfs on /dev (devfs, local) /dev/mmcsd0s1 on /boot/msdos (msdosfs, local, noatime) tmpfs on /tmp (tmpfs, local) procfs on /proc (procfs, local) fdescfs on /dev/fd (fdescfs)

На разделе msdos лежат файлы, необходимые для загрузки ОС с помощью u-boot, а на ufs - собственно, сама операционная система.
Причина, по которой производились изыскания, это желание сократить связанное с добавлением дополнительных устройств внесение изменений в системный исходный код ОС, а использовать для этого "понятный и доступный" механизм по подключению оверлеев (или, плагинов) к существующему дереву устройств, в сочетании с условностями и ограничениями реализации этого "понятного и доступного" механизма во FreeBSD на текущий момент.
Итак...
Подключение плагинов производится путём редактирования файла /boot/msdos/config.txt, а именно, добавлением команды:
CODE:
dtoverlay=<overlay-name>.dtbo,parameter=value[,parameter2=value2]

Тут следует обратить внимание на особенности реализации:
  • Имя плагина это полное имя файла с его бинарным представлением (blob) вместе с расширением. Такое именование отличается от используемого в linux, где конечное имя файла получается из имени плагина, суффикса (обычно, -overlay) и неочевидного расширения .dtb или .dtbo;
  • Файл с оверлеями должен находиться в /boot/msdos/overlays/, а не в папке /boot/overlays/, которая недавно появилась как системная во FreeBSD, и не в /boot/dtb/, как описывается в некоторых руководствах. Тем более это неочевидно, если учесть, что папки /boot/msdos/overlays/ изначально не существует. Просто создайте её и впоследствии копируйте в нее нужные оверлеи;
  • Параметры, при их наличии, отделяются от имени оверлея запятой, а не двоеточием, как описывается в некоторых руководствах;

Чтобы понять, как выглядит код оверлея, разберём реально работающий пример. При подключении устройства GPS с посекундной синхронизацией PPS необходимо организовать псевдоустройство gpiopps в дереве устройств с помощью оверлея, передать ему номер контакта, на который будет поступать сигнал и подключить драйвер этого псевдоустройства в ядро с помощью штатного модуля gpiopps.ko.
Строка в /boot/msdos/config.txt для подключения этого оверлея будет выглядеть примерно так:
CODE:
dtoverlay=gpio-pps.dtbo,gpiopin=18

А код самого оверлея может выглядеть так:
CODE:
/dts-v1/; /plugin/; / {     compatible = "brcm,bcm2836";     fragment@0 {         target-path = "/";         __overlay__ {             pps: pps@0 {                 compatible = "pps-gpio";                 gpios = <&gpio 18 0>;                 status = "okay";             };         };     };     __overrides__ {         gpiopin = <&pps>,"gpios:4";     }; };

Что мы тут видим?
  • Заголовки /dts-v1/; и /plugin/; указывают на то, что перед нами исходный код плагина дерева устройств;
  • / {... код ...}; код плагина относительно корня дерева;
  • compatible = .... Что тут писать - это вопрос к документации DTS, архитектуры SOC и философии;
  • fragment@<номер> {... код ...} последовательно нумеруемые, начиная с нуля, фрагменты внедряемых в дерево устройств блоков. Каждый фрагмент может внедрять код в разные точки дерева, и в нашем случае такой фрагмент единственный;
  • __overlay__ {... код ...} собственно код из этого блока и будет внедрен, а всё остальное, это описание того, как это будет сделано. В поисковых системах на данный момент имеется определенное количество предложений по модификации существующего дерева устройств для подключения тех или иных устройств к SOC компьютеру. Это тот же самый код, только в нашем случае предлагается модифицировать не всё дерево целиком, а подгружать модификации на этапе загрузки компьютера и размещать описания устройств в нужных местах дерева. Наш код взят из обсуждения на форуме FreeBSD (Сам я ни одного блока кода не разработал, так что даже не спрашивайте меня, как всё это делается);
  • target-path = ... как раз и указывает куда, в какой уже существующий блок, мы помещаем код из блока __overlay_. Тут хочу заметить, что строка описывающая путь должна быть в двойных кавычках. В нашем случае это корень дерева, а в случае плагина часов реального времени это может быть "/axi/bsc1";
  • __overrides__ {... описание ...} тут находится описание принимаемых в строке dtoverlay из файла /boot/msdos/config.txt параметров и переменных блока "__overlay__" (подозреваю, что не только его, а всего дерева), которые мы будем корректировать значениями этих параметров (Ну, согласитесь, не пересобирать же оверлей только из-за того, что нужно поменять ножку для получения сигнала PPS?). О взаимодействии этих двух блоков кода чуть ниже...
Чтобы скомпилировать оверлей, готовый для подключения, поместим исходный его код в файл, например, pps-overlay.dts и выполним команду:
CODE:
dtc -@ -I dts -O dtb -o gpio-pps.dtbo pps-overlay.dts

Получившийся blob gpio-pps.dtbo можно копировать на Raspberry PI, как я уже говорил, в папку /boot/msdos/overlays/, подключить его в /boot/msdos/config.txt, как показано выше, и перезагрузить малинку. Все!
Всё? Осталось рассказать о "вкусняшке" __overrides__...
Если бы мы не собирались использовать параметры при подключении оверлея (например, если нас устраивает объявленная жестко 12-я ножка GPIO18 в строке gpios = <&gpio 18 0>;), то не было бы необходимости в этом блоке, так же как и в метке pps в строке pps: pps@0 {, так как она указана только для того, чтобы адресовать значение 18 в блоке __overlay__ из блока __overrides__ (Буквально, строку gpiopin = <&pps>,"gpios:4"; читаем так: значением параметра gpiopin из директивы dtoverlay в файле /boot/msdos/config.txt заменить значение ячейки памяти gpios со смещением 4 в блоке с меткой pps, т.е. сразу за адресом &gpio). Более того, в стучае такого "простого" оверлея, без ссылок и адресов и, размещающегося прямо в корне DTS, из команды по сборке можно убрать параметр -@. Это немного уменьшило бы размер бинарного образа оверлея. В нашем случае параметр -@ обязателен, и, следует заметить, что его отсутствие не всегда приводит к ошибке компиляции оверлея, но работать последний будет неправильно!
Вот, теперь, всё! И не забудьте подгрузить модуль ядра gpiopps.ko - всё, что мы сделали, мы делали для него.

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
Опции формы