U-Boot tools: инструменты работы с загрузчиком U-Boot

Ошибка bad magic number при загрузке образа через U-Boot почти всегда означает, что ядро собрано без заголовка, который добавляет утилита mkimage из пакета u-boot-tools. Этот пакет — стандартный набор инструментов для работы с загрузчиком Universal Boot Loader: создание образов, чтение и запись переменных окружения прямо из запущенной Linux-системы, подготовка скриптов загрузки.

В статье разберём, что входит в состав u-boot-tools, как установить пакет на разные дистрибутивы, как правильно пользоваться fw_printenv и fw_setenv, чтобы не повредить загрузочную область, и какие типичные ошибки встречаются при работе с образами. Материал ориентирован на разработчиков встраиваемых систем и владельцев одноплатных компьютеров вроде Raspberry Pi, Orange Pi и устройств на базе Allwinner, Rockchip и Amlogic.

Что входит в состав пакета u-boot-tools

Пакет объединяет несколько независимых утилит, каждая из которых решает свою задачу. Набор может незначительно отличаться в зависимости от дистрибутива и версии, но ядро состава стабильно.

  • 🔧 mkimage — создаёт образы в формате U-Boot (uImage), добавляет заголовок с контрольной суммой, упаковывает скрипты boot.scr и FIT-образы.
  • 💾 fw_printenv — читает переменные окружения загрузчика из запущенной системы без перезагрузки в консоль U-Boot.
  • ✏️ fw_setenv — записывает и изменяет переменные окружения U-Boot, позволяя менять параметры загрузки «на лету».
  • 📄 dumpimage — извлекает содержимое из образов формата U-Boot, полезна для анализа чужих прошивок.

Отдельно стоит понимать, что сами утилиты не являются загрузчиком. Это пользовательские инструменты хост-системы, которые работают с файлами и областями памяти, созданными U-Boot. Загрузчик при этом находится на устройстве — во флеш-памяти, на eMMC или SD-карте.

Установка пакета в разных дистрибутивах

В большинстве популярных дистрибутивов пакет доступен в стандартных репозиториях. Название пакета может отличаться, поэтому ниже приведены команды для основных систем.

Для Debian, Ubuntu и производных:

sudo apt update

sudo apt install u-boot-tools

Для Fedora:

sudo dnf install uboot-tools

Для Arch Linux:

sudo pacman -S uboot-tools

После установки проверьте доступность утилит командой which mkimage fw_printenv. Если какая-то из них не найдена, возможно, пакет разбит на части — тогда поиск по репозиторию через apt search u-boot покажет доступные варианты.

Работа с mkimage: создание образов и скриптов

Утилита mkimage — самая востребованная часть пакета. U-Boot не загружает «голые» бинарные файлы ядра: ему нужен заголовок с типом образа, архитектурой, адресом загрузки и контрольной суммой. Именно этот заголовок и формирует mkimage.

Типичный пример упаковки ядра в формат uImage:

mkimage -A arm -O linux -T kernel -C none \

-a 0x80008000 -e 0x80008000 \

-n "Linux kernel" -d zImage uImage

Адреса загрузки (-a) и точки входа (-e) зависят от конкретной платформы и должны соответствовать документации на ваш SoC или defconfig платы. Использовать адреса из чужого примера без проверки — частая причина зависания на этапе Starting kernel....

Вторая частая задача — компиляция загрузочного скрипта. U-Boot ищет на носителе файл boot.scr, который представляет собой текстовый скрипт, обработанный mkimage:

mkimage -C none -A arm -T script -d boot.cmd boot.scr

Здесь boot.cmd — обычный текстовый файл с командами загрузчика. После правки скрипта его нужно пересобрать тем же способом, иначе изменения не попадут на устройство.

⚠️ Внимание: неверные адреса загрузки в mkimage не выдают ошибку на этапе сборки — образ соберётся успешно, но устройство зависнет или уйдёт в перезагрузку при старте. Всегда сверяйте адреса с документацией на вашу плату.

Переменные окружения: fw_printenv и fw_setenv

U-Boot хранит настройки загрузки — команду bootcmd, аргументы ядра, MAC-адрес — в специальной области флеш-памяти, называемой окружением (environment). Утилиты fw_printenv и fw_setenv позволяют работать с этой областью из запущенной Linux-системы, не заходя в консоль загрузчика по UART.

Чтобы утилиты нашли окружение, нужен конфигурационный файл /etc/fw_env.config. В нём указывается устройство, смещение и размер области окружения. Пример строки конфигурации:

/dev/mmcblk0 0x80000 0x40000

Значения смещения и размера строго зависят от того, как собран и развёрнут U-Boot на конкретном устройстве. Узнать их можно из исходников загрузчика (параметры CONFIG_ENV_OFFSET и CONFIG_ENV_SIZE) или из документации производителя платы.

☑️ Перед первым запуском fw_setenv

Выполнено: 0 / 5

Чтение всех переменных выполняется командой fw_printenv, а запись — например, так:

sudo fw_setenv bootdelay 5

Если при чтении вы видите предупреждение о неверной CRC, обычно это означает одно из двух: либо конфигурация указывает не на ту область памяти, либо окружение ещё ни разу не сохранялось из самого загрузчика командой saveenv.

⚠️ Внимание: запись через fw_setenv при неверно указанном смещении может затереть служебные области флеш-памяти, включая сам загрузчик. Сначала убедитесь, что fw_printenv корректно читает осмысленные переменные, и только потом выполняйте запись.
📊 Для какой задачи вы используете u-boot-tools?
Сборка образов ядра через mkimage
Изменение переменных окружения из Linux
Отладка загрузки одноплатника
Разбор чужих прошивок и образов

Типичные ошибки и их диагностика

Большинство проблем при работе с u-boot-tools сводится к нескольким повторяющимся сценариям. Таблица ниже поможет быстро сориентироваться.

СимптомВероятная причинаЧто проверить
Bad Magic Number при загрузкеОбраз без заголовка U-Boot или повреждёнПересобрать образ через mkimage, проверить тип образа
Wrong Image Format for bootmНесоответствие типа образа команде загрузкиИспользовать bootm для uImage, booti/bootz — для raw-образов
CRC error в fw_printenvНеверное смещение в fw_env.config или пустое окружениеСверить CONFIG_ENV_OFFSET, выполнить saveenv из U-Boot
Зависание на Starting kernelНеверные адреса загрузки или точки входаПроверить адреса по документации на SoC
boot.scr игнорируетсяСкрипт не пересобран после правки или лежит не в том разделеПересобрать через mkimage, проверить путь поиска в bootcmd

Полезный приём диагностики — команда iminfo в консоли самого U-Boot. Она показывает, как загрузчик видит образ: тип, архитектуру, адреса, контрольную сумму. Если iminfo сообщает об ошибке, проблема в образе; если образ распознаётся корректно, но загрузка не идёт, причину стоит искать в адресах или в самом ядре.

Чем uImage отличается от FIT-образа

Классический uImage содержит один компонент (ядро, ramdisk или скрипт) с простым заголовком. FIT (Flattened Image Tree) — современный формат на основе Device Tree, который упаковывает ядро, dtb и initramfs в один файл с описанием конфигураций и поддержкой проверки подписей. FIT собирается тоже через mkimage, но по its-файлу описания. Для новых проектов производители SoC чаще рекомендуют FIT.

Практические сценарии использования

Ниже — несколько обобщённых ситуаций, где u-boot-tools незаменим. Конкретные пути и имена файлов зависят от вашей платы и сборки системы, поэтому ориентируйтесь на документацию производителя.

  • 🔄 Смена раздела загрузки — через fw_setenv можно переключить переменную с корневым разделом, например для A/B-схемы обновлений.
  • 🧪 Тестовая загрузка с TFTP — временно изменить bootcmd на загрузку по сети, не перепрошивая устройство.
  • 🛠 Восстановление после неудачной правки — если окружение испорчено, загрузчик обычно откатывается к значениям по умолчанию, встроенным при сборке.
  • 📦 Подготовка образа для производства — автоматическая сборка uImage и boot.scr в CI-конвейере через mkimage.

Для одноплатных компьютеров важно помнить: многие дистрибутивы для ARM-плат поставляют собственные скрипты генерации boot.scr, и ручная правка файла без пересборки не даст результата. Проверьте, есть ли в системе пакет с шаблонами загрузочных скриптов, и правьте именно исходник.

Меры предосторожности при работе с загрузочными областями

Работа с u-boot-tools относительно безопасна, пока речь идёт о файлах образов на хост-машине. Риски появляются при записи в сырую флеш-память устройства. Несколько правил помогут избежать «окирпичивания».

Во-первых, перед любыми изменениями окружения сохраните текущее состояние: fw_printenv > env_backup.txt. Это займёт секунды, но позволит восстановить рабочую конфигурацию. Во-вторых, не записывайте данные напрямую через dd в область загрузчика, если точно не знаете её границы. В-третьих, помните, что неверное смещение в fw_env.config превращает безобидную fw_setenv в инструмент порчи прошивки — проверка чтения всегда предшествует записи.

⚠️ Внимание: процедуры обновления самого бинарника U-Boot различаются между платами и несут риск полной потери загрузочности. Используйте только инструкции производителя вашего устройства и имейте под рукой способ восстановления (UART-консоль, маскром-режим, загрузка с SD).

Часто задаваемые вопросы

Чем отличается fw_printenv от команды printenv в консоли U-Boot?

printenv выполняется внутри самого загрузчика до старта системы, а fw_printenv — из запущенного Linux, читая ту же область флеш-памяти через файл конфигурации. Результат должен совпадать, если fw_env.config настроен верно.

Почему mkimage не находится после установки пакета?

В некоторых дистрибутивах утилита входит в отдельный пакет (например, u-boot-tools и uboot-mkimage могут быть разделены). Поищите по репозиторию: apt search mkimage или аналог для вашего пакетного менеджера.

Можно ли редактировать boot.scr напрямую текстовым редактором?

Нет. Файл boot.scr — бинарный, с заголовком U-Boot. Редактируется исходный текстовый файл boot.cmd, после чего скрипт пересобирается командой mkimage с типом script.

Что делать, если fw_printenv выдаёт ошибку CRC?

Проверьте, что смещение и размер в /etc/fw_env.config соответствуют параметрам сборки U-Boot (CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE). Если конфигурация верна, возможно, окружение ещё не сохранялось — выполните saveenv из консоли загрузчика.

Подходит ли u-boot-tools для Raspberry Pi?

Да, если на плате используется U-Boot в качестве загрузчика (это характерно для многих сторонних дистрибутивов). Штатный загрузчик Raspberry Pi OS работает иначе, и утилиты пакета там не применяются. Проверьте, какой загрузчик использует ваша сборка.