aow rootfs что это
Образ rootfs
Содержание
Что такое rootfs
rootfs, то есть root file system, корневая файловая система — это архив с минималистичной системой, грубо говоря, это как если бы вы открыли файловый менеджер в корне своего Linux и запаковали всё найденное в архив, только здесь предустановлено минимально необходимое количество пакетов.
Для чего нужен rootfs
Где скачать rootfs Росы
Раз в день автоматически выполняются сборки rootfs архитектур x86_64 и i586 на платформах rosa2016.1 и rosa2014.1.
Найти и скачать самые свежие сборки можно здесь.
Образы rootfs-min — это минималистичный образ (ввиду того, что некоторые пакеты в репозитории сейчас тянут лишние зависимости, в rootfs также есть лишние пакеты, например, grub2). Образы rootfs-std — это более расширенный набор пакетов, добавлены пакеты, необходимые для сборки других пакетов (rpm-build, git-core и др.).
Порядок скачивания последней сборки rootfs
Как собрать rootfs самому
Нужно взять скрипты сборки и запустить mkimage-urpmi.sh.
Патчи и пулл-реквесты для улучшения скриптов сборки принимаются на Github.
Пример использования rootfs
Разберем на примере ежедневной сборки №25111. Контейнер назовем «rosa1».
В команде wget выше
Пример использования на BTRFS для быстрого клонирования контейнеров
/var/lib/machines должно быть внутри раздела BTRFS.
В итоге у нас есть 3 одинаковых контейнера: /var/lib/machines/rosa1, /var/lib/machines/rosa2, /var/lib/machines/rosa3. Поскольку они одинаковые, место на диске занимается 1 раз, а не 3. После запуска каждого из контейнеров рекомендую менять hostname, чтобы было удобно их различать.
Запуск 32-битного контейнера на 64-битном хосте
Без доп. параметров всё запустится, но, например, uname и lscpu будут выдавать x86_64, в результате чего утилиты типа rpm будут думать, что они работают на 64-битной Ос, а не 32-битной.
Бездисковая загрузка по сети и жизнь после нее
История
Теория
По сути, для того, чтобы система загрузилась ей необходимо 3 компонента — ядро, начальное окружение initramfs и корневой каталог, в котором система будет работать.
Практика
Все действия проводятся на машине с ubuntu precise.
Для начала настроим PXE. Мануалов на эту тему уйма, поэтому я расскажу только самую суть.
Ставим ваш любимый dhcp сервер, например isc-dhcp-server, который будет раздавать машинкам ip адреса и указывать путь к файлу pxelinux.0, который будет отдавать tftp сервер (tftp-hpa или же atftp).
Пример конфига dhcp сервера. В примере pxe-сервер находится по адресу 10.0.0.1.
Запускаем tftp сервер (в ubuntu он имеет init-скрипт, но вполне вероятно, что вам придется запускать его и через inetd/xinetd).
Проверяем работоспособность. Кладем файл в каталог /var/lib/tftpboot и пробуем стянуть его tftp клиентом.
В принципе неважно, где вы возьмете файл pxelinux.0, так как он является просто начальным загрузчиком, в который мы передаем то, что надо грузить дальше.
Вы можете сделать красивую менюшку в загрузчике, но сейчас нам это не нужно, поэтому мой pxelinux.cfg/default выглядит так
rootfs
Образ rootfs собираем через debootstrap, чрутимся в него и ставим необходимые программы. Настраиваем сеть, hostname, фаервол и прочее, чем больше сделаем настроек, тем больше будет образ. Главное не забудьте сменить пароль на рута.
С нашим минимальным набором система получилась весом 200Мб.
Initramfs
В этом примере мы будем забирать образ корневой фс с веб-сервера, расположенного на нашем сервере сетевой загрузки, то есть на 10.0.0.1. Решение было таким просто потому, что в нашем initramfs была утилита wget. Чтобы не тянуть большой объем данных по сети, мы решили сжать образ. Это можно было бы сделать и обычным tar, но можно попробовать squashfs, тем более, что обычно в initramfs tar не встроен, с другой стороны, ничего не мешает его туда добавить.
Squashfs
Squashfs — это сжимающая файловая система, которая включена в ядро с версии 2.6.29. С ее помощью можно заархивировать каталог, примонтировать на loop устройство и читать с него, для записи же необходимо провести процедуру добавления файлов в архив. Так как при обращении к squashfs, вы читаете из архива, то это дает дополнительную нагрузку на cpu.
Далее надо научить init из initramfs забирать образ корня и помещать его в оперативную память.
init в initramfs — это скрипт на sh, который производит разбор опций из cmdline, монтирует фс, делает switch_root и запускает гланый init-процесс системы.
Воспользуемся этим и допишем свои опции для cmdline. Напишем скрипт ram, который будет вызываться при значении опции boot=ram.
Через параметр rooturl можно указывать откуда качать образ корневой фс. Для работы со squashfs необходимо подгрузить ее модуль в ядро. Указываем в /etc/initramfs-tools/initramfs.conf BOOT=ram и пересобираем initramfs
Включаем машинку, на которой будем тестировать, и смотрим на происходящее. После успешной загрузки мы получили бездисковую систему, которая занимает в памяти около 300Мб, при этом мы может писать в нее, но после ребута, система вернется в свое первоначальное состояние.
В это примере, мы использовали squashfs просто для сжатия образа, но почему бы нам не попробовать примонтировать корневой раздел в squashfs и не посмотреть, что получится? Меняем наш скрипт, в функции do_rammount() оставляем только монтирование squashfs.
Пересобираем initramfs, запускаем, смотрим. Система загружается в режиме ro, но зато занимает в памяти всего около 180Мб.
В каких-то случаях монтирование в режиме ro это хорошо, но нас это не устраивает, но и просто так тратить оперативную память нам тоже не хочется. Выход же был найден при помощи Aufs.
Aufs
Aufs позволяет делать каскадно-объединённое монтирование файловых систем — одну в режиме только на чтение, а вторую в rw. Работает она в режиме copy-on-write, то есть все изменения записываются на rw систему и после этого чтение производится с нее же.
Опять переписываем наш скрипт.
В фукнцию mountroot() добавляем
А фукнцию do_rammount() приводим к следующему виду:
Пересобираем initramfs, запускаем, смотрим. Система занимает в памяти 181Мб, при этом мы можем менять ее, писать, читать. Все изменения хранятся отдельно в /mnt/rw, а сама система хранится в /mnt/ro.
В результате мы получили систему, которая грузится по сети, занимает небольшой объем в памяти, при этом после каждой перезагрузки пропадают все изменения (поэтому надо заранее собирать все нужные продукты жизнедеятельности системы в надежное место).
Все вышеперечисленные способы имеют право на жизнь. Надеюсь, что эта информация вам пригодится, а мне же будет интересно почитать/послушать ваши комментарии.
Спасибо за внимание.
Установка Linux на калькулятор. Часть II
Как вы помните, в прошлой статье мне удалось стартануть linux на калькуляторе. Однако, работать на нём было невозможно, и я считаю это незачётом. Тогда я понял, что кроличья нора достаточно глубока и придётся полностью пересобирать всю систему, разбираясь с кодом. В итоге, я кратко прошёлся по всем этапам, которые описывал автор проекта. И результат полностью того стоит. Итак, поехали!
Аппаратные доработки: подключаем UART
Я написал обо всех моих бедах создателю этого linux, заодно попросив прислать мне бекап его прошивки (хотя его лучше, не заливать). И спросил, как же мне подключить UART к моему калькулятору? На что он мне прислал следующую картинку, и сказал: ищи это на другой стороне платы.
В результате, мне предстоял сложный квест — отклеить плату от дисплея, не расколов дисплей и не сломав плату. Пихая туда все возможные металлические предметы, очень аккуратно, в течении часа мне удалось её отделить. Самое сложное было не оборвать тончайшие шлейфы.
Наконец-то, нашему вниманию представляется просто невероятный зоопарк тестовых падов, выводы JTAG и, по моему, SPI, интерфейс SD. Но, самое главное, наш отладочный UART.
Скорее всего там использована логика 1,8 В, но у меня не было такого адаптера, и я решил рискнуть и использовать адаптер с логикой 3,3 В (вам же настоятельно рекомендую использовать 1,8). Попытка, заставить мой адаптер работать на напряжении 1,8 вольта, не увенчалась успехом. Таким образом, я вывел сигналы на гребёнку, в т.ч. опорные 1,8 вольта (но они не пригодились).
Можно приклеивать плату обратно и продолжать работать.
Давайте сразу посмотрим, почему же у нас не запускается система, при загрузке в ОЗУ? Хотя вроде всё работает. Во-первых, давайте глянем скрипт запуска. Содержимое файла run_linux_in_ram.uu:
Загружаем в память загрузчик u-boot, ядро, dts (точнее, скомпилированный бинарник dtb), initramfs и передаём управление загрузчику, после чего с успехом завершаем приложение uuu.
По логам всё идёт отлично, до момента окончательной загрузки ядра, а там начинается вот такая петрушка.
И так до посинения. Всё банально, /dev/ не создана. И проблема эта открылась позже, при конфигурировании rootfs. Шикарно, мы теперь имеем отличный инструмент отладки. Начнём всё собирать!
Сборка софта
Если вы дойдёте самостоятельно до этого этапа, то надеюсь у вас есть какой-никакой опыт сборки ядра, rootfs, конфигурирования через make menuconfig. Так как описывать весь необходимый список установочных пакетов мне уже лениво (надо установить как минимум кросскомпилятор arm-linux-gnueabihf-, ncurses и многое другое, у меня просто уже всё давно стоит). Будем считать, что вы всё умеете, я лишь заострю ваше внимание на некоторые моменты. Для начала процитирую, то как рекомендуется делать сборку на официальном сайте проекта, а потом я внесу некоторые комментарии.
4. Сборка из исходника
4.1 u-boot
Как правило, пересобирать u-boot вам не нужно, и нижеприведенные инструкции даются в качестве справочного материала.
Чтобы собрать u-boot из исходника:
В результате получится бинарный файл u-boot-dtb.imx.
4.2 Ядро
Для включения/отключения конкретных модулей драйверов/ядра потребуется пересобрать все ядро.
4.2.1 Компиляция с помощью Buildroot
buildroot соберет ядро автоматически. Конфигурацию же можно изменить с помощью make linux-menuconfig.
4.2.2 Сборка ядра вручную
В итоге будут собраны файлы arch/arm/boot/dts/imx6ull-14×14-prime.dts и arch/arm/boot/zImage.
4.3 Корневая файловая система (rootfs)
На данный момент hp-prime-linux использует для построения корневой файловой системы buildroot. Пакетного менеджера пока что нет, и если вам нужно добавить или удалить пакет, то потребуется пересобрать rootfs.
Для установки модулей ядра в rootfs, перейдите в директорию ядра и выполните следующие команды:
После этого повторно сгенерируйте образы с помощью buildroot.
Для начала, я решил проверить, что, как минимум, всё это собирается из исходников, поэтому решил потренироваться на самом простом — сборке u-boot. Это важно, так как бывает такой момент, что автор написал инструкцию по сборке и прошивке, а забыл закоммитить последние изменения, и в результате его инструкция оказывается бесполезным мусором.
U-boot собирается совершенно 1 в 1 по инструкции, без каких либо тонкостей. В корневой папке после компиляции, мы получим кучу файлов, но нас интересует файл u-boot-dtb.imx.
Скопируем его в нашу флеш-утилиту (предварительно создав там папку my):
И создадим там новый загрузочный скрипт, на котором всё и будем обкатывать:
Проверяем на калькуляторе (всё как обычно, запускаем скрипт, потом вставляем USB. И в результате должны получить такой результат.
Это полный успех, значит код рабочий и мы можем продолжать. Если вы дойдёте до сборки, то настоятельно рекомендую поглядеть git log и git diff между коммитами, чтобы оценить масштабы проделанной работы. Это восхищает и мотивирует!
Со сборкой ядра у меня тоже практически не возникло никаких проблем, разве что пришлось поставить дополнительный пакет lzop, чтобы ядро корректно сжалось. Протестировать можно точно так же (не забыв добавить загрузку dtb-файла, иначе ядро не стартанёт).
Самым сложным оказалась сборка rootfs, как оказалось, дефолтный конфиг мне не подойдёт для сборки. Для начала. делаем всё точно, как написано в инструкции:
А вот теперь начинается самое интересное, хождение по битым ссылкам :). В релизах, кроме flash_utility.tar.gz есть ещё файл Source code, который, совершенно неочевидным образом содержит в себе необходимые конфиги для сборки rootfs! Скачиваем файл prinux-0.1.zip и распаковываем его в удобное для нас место. Либо клонируем репозиторий. У меня это вышел путь /home/dlinyj/tmp/calc/prinux.
Там внутри есть папка buildroot — это и есть внешние конфигурационные файлы для сборки buildroot! И вот этот путь, именно до этой папки указываем в следующей команде:
Допереть до этого самостоятельно было невозможно, покуда я не прошерстил вообще все репозитории, файлы и не прочитал как же собирается buildroot (к своему стыду, впервые собираю его вот так, с нуля).
Этой конфигурации мало, в целом можно конечно собрать, и даже попробовать запустить, но initramfs он будет слишком здоровым (там стоят Иксы), больше 25 МБ, и он не запустится. А для прошивки на nand мы будем получать ту же самую проблему, как и в тесте загрузки в память: не будут созданы файл-устройства.
Первое, я отредактировал файл /home/dlinyj/tmp/calc/prinux/buildroot/configs/prime_defconfig и привёл его к виду:
Выкинув совершенно лишние на данный момент пакеты иксов (мне бы стартануть систему, а потом всё остальное).
В опции Filesystem images включаю:
Прохожусь по всем пакетам и отрубаю вообще всё, чтобы не было лишнего.
В разделе System configuration ставлю:
Тем самым ещё более уменьшая образ, и наконец у нас будет корректно работать менеджер устройств!
Выходим и сохраняем. И собираем:
После успешной компиляции, топаем обратно в папку с собранным ядром и нам необходимо теперь установить модули ядра в нашу rootfs, для этого выполняем:
И возвращаемся в buildroot и вновь выполняем make. В результате мы получим собранные пакеты в папке /home/dlinyj/tmp/calc/buildroot/output/images:
Стартуем!
Переписываю готовые образы rootfs в папку my и не забываем переписать туда же свежесобранное ядро из папки /home/dlinyj/tmp/calc/linux/arch/arm/boot, файл zImage. Далее беру за основу скрипт прошивки на nand-флеш и привожу его к виду:
Обращаю внимание, что у нас используется специальный образ rootfs для прошивки nand-флеш. Я выкинул прошивку u-boot (так и не понял в чём проблема, и пока не смог победить). device tree blob загружается из другой папки, но никто не мешает его собранный так же переписать либо из u-boot, либо из папки с ядром.
Запускаем этот скрипт, и у нас успешно прошивается nand-флеш. Поскольку загрузчик у нас не прошит, при подаче питания linux не стартанёт. Поэтому вновь правим (или пишем новый скрипт) для загрузки u-boot:
Запускаем этот скрипт, и шалость удалась!
К сожалению, мне удалось успешно загрузиться на nand только один раз, потом я решил поправить один файл и у меня уже сыпалось всё с паникой ядра. Чуть ниже расскажу о проблемах.
А как на счёт логина с клавиатуры калькулятора и работы экрана?
А, вы хотите нормальной работы калькулятора, прям как настоящего компьютера? Независимо от большого ПК, не работая через консоль? Да?
Да ладно. Их есть у меня, пожалуйста. Для этого, согласно той же инструкции надо поправить один файл. Цитирую:
5.3.1 Активация консоли VT
В данном релизе она активна по умолчанию.
Хочу обратить внимание, что в оригинальной статье ошибка (забыт нолик), в этой цитате я исправил данную команду. Вписываем эту строку, и перекомпилируем снова rootfs.
Далее пишем загрузочный скрипт, для загрузки нашей сборки initramfs:
Запускаем его, и вот вам демонстрация работы экрана и клавиатуры, ну чем не компьютер.
После чего я немного разошёлся, и накидал ещё в /root несколько графических файлов, и вывел их с помощью программы fbi (вы их видели в заходниках статей).
Итого
Фух, была проделана громадная работа, растянувшаяся на две недели, но оно того по настоящему стоило!
Если, вы вдруг имеете подобный калькулятор, то вполне можете повторить запуск линукс (как минимум в ОЗУ), с помощью обновленной утилиты, которую можете скачать вот тут.
flash_utility.tar.gz.
К сожалению, с nand-флеш мне не удалось подружиться. После редактирования файлика, и дальнейшей перезагрузки, я получил вот такое сообщение.
Я так и не понял почему так получается, как я не бился, второй раз загрузиться на nand-флеш мне не удалось. Скорее всего, это связанно с тем, что я затёр вспомогательные области nand-флеша, и где-то rootfs и u-boot попадает на эти битые сектора, которые я варварским образом перемаркировал в нормальные. Уже буквально в ночи, перед выходом данной статьи решил собрать initramfs с утилитами mtd и nand и посмотреть, что же происходит. А происходит весьма любопытная петрушка. При загрузке ядро у меня выдаёт.
Но при этом в системе пятый раздел, на котором собственно и находится rootfs после загрузки отсутствует. Ошибок в логе загрузки нет:
Странная, пока непонятная мистика, куда подевался раздел.
Точно так же, мне не удалось прошить u-boot на nand. При прошивке командой:
Происходит следующая ошибка:
Это всё, что удалось поймать по UART. Я уже и в исходниках kobs-ng поковырялся, но всё бестолку. Пока непонятно как разрешить этот вопрос.
Zynq 7000. Собираем Linux и RootFS при помощи Buildroot
Рекомендуемые источники для более глубокого изучения
Перед началом повествования хотелось бы отдельно отметить источники информации, которые помогли мне при подготовке этого материала:
Книга Криса Симмондса Встраиваемые системы на основе Linux.
Стрим ребят из команды FPGA-Systems.ru по сборке Linux: https://www.youtube.com/watch?v=339hpNuRZDo
Что такое Buildroot и зачем он нужен?
Чтобы решить эту проблему профессионалы придумали нечто такое, что позволило бы автоматизировать всю процедуру сборки, настройки всего необходимого! Звучит заманчиво, не правда ли?
В результате реализации этой идеи на свет появился Buildroot! Это система автоматизированной сборки на основе GNU Make и Kconfig.
Основная идея автоматизированной сборки состоит в том, что эта система должна уметь собрать из полученного исходного кода с репозиториев всё необходимо для работы, набор для кросс-компиляции, всех инструментов, начальный загрузчик, ядро ОС, откомпилированный файл device-tree и корневую файловую систему.
Самое удобное и полезное в этой ситуации то, что всё необходимое собирается из исходного кода. В этом случае у нас есть уверенность, что мы можем пересобрать код в любое время и без лишнего гемороя с внешними зависимостями. Также мы можем быть уверенными в том, что используется самые последние версии программ со всеми патчами и исправлениями.
Общая последовательность шагов которые выполняются при работе с системами сборки мне видится таковой:
Конфигурирование. В этом шаге выполняется настройка всего того, что будет в последствии собрано: от загрузчика до программ которые будут скомпилированы и включены в корневую файловую систему. Самый трудоемкий и объемный шаг, который в последствии облегчается тем, что наработки можно сохранять в файлы конфигурации и детальная настройка нужна только один раз. В дальнейшем можно переиспользовать уже готовую конфигурацию.
Скачивание исходных кодов и сохранение всего того, что было выбрано на этапе конфигурации. Также докачиваются зависимости и всё необходимое для успешной сборки.
Сборка и компиляция исходных кодов. Занимает достаточно много времени, длительность зависит от объема выбранных программ и того, насколько сложную систему вы хотите собрать.
Создание корневой файловой системы и конечная компоновка.
Создание финальных образов с возможностью выбора их форматов, пригодных для загрузки на устройстве.
В дополнение к этому, есть еще ряд плюшек которые предоставляются системой сборки:
Можно добавлять свои программы и пакеты.
Есть возможность выбора различных профилей файловой системы, с оптимизацией по размеру. с поддержкой разных опций влияющих на размер образа.
Очень удобно использовать при создании автономного SDK и распространения его среди других разработчиков.
Возможность создавать обновления, которые можно применить к уже установленным системам.
Наличие удобного интерфейса для взаимодействия с пользователем.
Наверняка, пытливый пользователь может спросить “А ведь есть же PetaLinux который базируется на Yocto. Зачем нужен buildroot?”. И я немного разобравшись в вопросе смело могу заявить, что это абсолютно две разные системы которые подходят к решению задачи сборки довольно таки разных по сложности и преследуют совершенно разные цели.
Возможно когда-нибудь в будущем я попробую разобраться и с Yocto, но точно не в этой статье. Едем дальше…
Переходим от разговоров к делу!
Перейдем к установке
Как обычно все начинается с клонирования репозитория на локальный компьютер. Привожу пример получения последней версии на момент написания статьи:
После клонирования репозиториев необходимо установить все требуемые зависимости:
Конфигурирование
Давайте посмотрим, что находится рабочем каталоге buildroot:
Всё, что будет скомпилировано будет положено в папку output, либо в папку указанную в параметрах компиляции с ключом O= , в которой появятся два основных каталога:
Создадим файл, запуская который у нас будет открываться меню конфигурации:
Запишем в него следующее:
Теперь можно начинать конфигурацию и подготовить конфигурацию, которую после будем использовать для работы с нашей платой.
Первым пунктом заходим в меню Target options и выбираем архитектуру ARM (little endian) и выбираем вариант архитектуры Cortex-A9, что собственно соответствует тому, что мы имеем на плате. Устанавливаем также опции связанные с Hard Floating Point. После проведения правильной конфигурации окно примет следующий вид:
Переходим обратно в главное меню и заходим в меню Build options. Для ускорения процедуры сборки можно поставить опцию Number of jobs to run simultaneously в соответствии с количеством ядер CPU. Остальные опции оставляем по умолчанию.
Переходим к настройке Toolchain.
В нашем случае мы воспользуемся toolchain встроенным в Buildroot. Оставляем без изменений пункт Toolchain type.
Меняем используемую C library на glibc.
В пункте Kernel Headers выбираем Custom Git Repository и в меню URL of custom repository указываем путь, к cклонированному в прошлом занятии, ядру Linux. Либо клонируем репозиторий в папку /home:
После в поле Custom repository version необходимо указать хэш текущего указателя на master-ветку в репозитории:
Смотрим версию ядра, склонированную в репозитории linux-xlnx:
Будет выведено окно настройки конфигурации ядра для последующего компилирования и в заголовке будет указана версия:
Выбираем версию ядра 5.10.х в опции Custom kernel headers series.
Устанавливаем опцию Install glibc utilities.
Выбираем версию компилятора gcc. В моем случае это gcc 9.x. Установим его в поле GCC compiler Version.
Установим поддержку C++ в поле Enable C++ support.
Далее выбираем опции Enable compiler link-time-optimization support.
Ставим поддержку мультипроцессорного режима работы программ с использованием OpenMP в поле Enable compiler OpenMP support.
Настроим параметры ядра для последующей компиляции следующим образом.
Таким же образом указываем Custom Git repository с указанием пути до репозитория и хэша.
Указываем что корневой файл конфигурации будем использовать из in-tree источника: Kernel configuration (Using an in-tree defconfig file).
Файл defconfig указываем тот, что использовали по умолчанию при компиляции ядра в прошлом уроке: записываем в поле Defconfig name xiinx_zynq без постфикса “_defconfig”.
Выбираем опцию Kernel binary format и ставим uImage и тип компрессии gzip
Устанавливаем адрес загрузки Load address в 0x8000.
Остальные опции в этом меню остаются по умолчанию. Выглядит меню настройки следующим образом:
Переходим в меню Target options. В этом меню мы можем выбрать весь набор необходимых программ которые будут включены в состав будущего образа.
Переходим в меню Filesystem images. Выбираем интересующие нас образы, я выбираю только cpio и метод сжатия lzma.
В меню Host Utilites ставим опции:
host dosfstools
host genimage
host mtools
Все настройки завершены, записываем их путем нажатия клавиши F6 сохраняем файл с именем .config.
На этом мы можем считать, что предварительная настройка Linux закончена. Можно запускать компиляцию. Для этого я сделал скрипт br-build и записал в него следующее:
После этого необходимо присвоить ему права на исполнение и запустить:
После окончания компиляции в папке images/ появятся необходимые образы:
После этого можно попробовать загрузить то, что у нас получилось. Копируем на загрузочную microSD файлы uImage и uramdisk.image.gz и файл devicetree.dtb который у нас был сделан в прошлом занятии.
Проверим, что получилось
Запускаем плату и попадаем в меню U-Boot. В этом меню вводим команды:
В целом основная задача выполнена и достигнутое можно считать хорошей заготовкой для дальнейшей кастомизации используемого образа Linux. Можно пробовать добавлять свои скрипты и проводить более углубленное изучение buildroot, например, осуществить сборку Device Tree через buildroot.