U-Boot на сегодняшний день является основным загрузчиком Linux для встраиваемых систем. Он доступен для большого количества архитектур, включая x86, ARM, MIPS, 68k, SuperH, PPC, RISC-V, MicroBlaze, Blackfin и Nios.
Загрузчик U-Boot в процессе запуска Linux проходит несколько стадий запуска. Самая первая часть запускаемого кода находится по адресу перехода по сбросу (reset vector), и эта часть кода обычно находится в ПЗУ процессора (on-chip BootROM) или BIOS. На этой стадии происходит минимальная инициализация железа процессора, и происходит переход к следующей стадии загрузки.
[User Bootloader]
Следующая стадия загрузки - пользовательский код загрузчика (user bootloader). Это первый код, которым может управлять пользователь. Он производит все необходимые действия (в частности, здесь обычно реализована процедура запуска перепрошивки) и далее запускает код ядра (Linux kernel). Код ядра после своей загрузки запускает все необходимые процессы пространства пользователя.
SPL - Secondary Program Loader. User bootloader в свою очередь состит из нескольких частей. Первая часть называется SPL (сокращение от Secondary Program Loader). Функция SPL заключается в запуске итерактивного shell-а по запросу пользователя, либо в запуске ядра Linux, если этого запроса не было.
Интерфейс входа в SPL может выглядеть следующим образом:
U-Boot SPL 2018.01-00002-g9aa111a004 (Jan 20 2018 - 12:45:29)
Trying to boot from MMC1
U-Boot 2018.01-00002-g9aa111a004 (Jan 20 2018 - 12:45:29 -0600)
CPU : AM335X-GP rev 2.1
I2C: ready
DRAM: 512 MiB
Reset Source: Global warm SW reset has occured.
Reset Source: Power-on reset has occured.
MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
Model: BeagleBoard.org PocketBeagle
Net: usb_ether
Press SPACE to abort autoboot in 2 seconds
=>
В приглашении командной строки => доступны множество функций - запуск дальнейшей загрузки определенного ядра, манипуляции с деревом устройств (device tree), работа с переменными окружения, просмотр и модификация ячеек адресного пространства и многое другое. Поскольку поведение U-Boot может быть автоматизировано настройками, пользователю не обязательно нужно каждый раз вводить управляющие команды, чтобы загрузить рабочую систему Linux с нужными параметрами.
Основные функции SPL:
• Собирается из того же исходного кода, что и U-Boot. • Значительно уменьшенный размер и набор функций. • Используется для инициализации системы и запуска U-Boot или Linux.
TPL - Tertiary Program Loader.
• Собирается из того же исходного кода, что и U-Boot. • Даже меньше, чем SPL. • Используется редко, только на очень ограниченных по ресурсам системах (например OneNAND).
[Назначение файлов и папок исходного кода U-Boot]
README. Общая документация по проекту U-Boot. Здесь приведено описание текущего состояния проекта, ссылки на исходный код, указания по выбору конфигурации и компиляции кода, описание опций компиляции (CONFIG_xxxx, CFG_xxxx, FDT_xxxx, I2C_xxxx и т. п.), поддерживаемые форматы образов, указания по портированию Linux на систему с использованием U-Boot и много другой полезной информации.
configs. В директории configs содержатся все доступные конфигурации, одну из которых можно выбрать для сборки под определенную процессорную платформу. Это файлы, имя которых оканчивается на суффикс _defconfig. Компиляция под выбранную платформу осуществляется командой "make < имя_платы>_defconfig". Пример для модуля TQM823L:
$ cd u-boot
$ make TQM823L_defconfig
[Интерактивный шелл U-Boot]
Могут быть выбраны 2 варианта шелла: оригинальный старый (у которого нет имени) и HUSH (шелл с расширенным набором функций). HUSH изначально был портирован их BusyBox, и этот вариант для большинства ситуаций является лучшим выбором. Он работает наподобие bourne shell, поддерживает постоянное хранилище переменных окружения и скрипты, содержит встроенную систему подсказок по командам.
Командная строка HUSH позволяет выполнять множество низкоуровневых сервисных функций, таких как сравнение областей памяти, копирование областей памяти и вычисление контрольных сумм блоков памяти (cmp, cp, crc32), получение информации об устройствах (coninfo), редактирование переменных окружения и управления ими (editenv, env, printenv, saveenv, setenv, setexpr), стирание памяти FLASH (erase), получение информации о памяти FLASH (flinfo, nand), запуск кода приложения по указанному адресу (go), вывод содержимого памяти и её изменение (md, mm, mw), загрузка через последовательные интерфейсы и TFTP (loadb, loads, loadx, loady, tftp), управление разделами (chpart, mtdparts), управление загрузкой (boot, bootd, bootelf, bootm, bootp, bootvx, nboot, nfs), сброс и перезагрузка (reset), запуск определенных в переменных окружения команд (run) и многое другое.
Интерактивный диалог команд с выводом подсказки может выглядеть следующим образом:
=> help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
bootvx - Boot vxWorks from an ELF image
chpart - change active partition
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
echo - echo args to console
editenv - edit environment variable
env - environment handling commands
erase - erase FLASH memory
exit - exit script
false - do nothing, unsuccessfully
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print command description/usage
iminfo - print header information for application image
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loadx - load binary file over serial line (xmodem mode)
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing address)
mtd - MTD utils
mtdparts - define flash/nand partitions
mw - memory write (fill)
nand - NAND sub-system
nboot - boot from NAND device
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
otp - otp sub-system:
printenv - print environment variables
protect - enable or disable FLASH write protection
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv - set environment variables
setexpr - set environment variable as the result of eval expression
showvar - print local hushshell variables
sleep - delay execution for some time
source - run script from memory
test - minimal test like /bin/sh
tftp - boot image via network using TFTP protocol
tftpboot - boot image via network using TFTP protocol
tftpput - TFTP put command, for uploading files to a server
true - do nothing, successfully
ubi - ubi commands
ubifsload - load file from an UBIFS filesystem
ubifsls - list files in a directory
ubifsmount- mount UBIFS volume
ubifsumount- unmount UBIFS volume
upimgtar - update kernel and rootfs by tar format on luna platform
upvmimg - update kernel and rootfs by vmimg format on luna platform
version - print monitor, compiler and linker version
Можно запрашивать подсказку как по всем командам, так и по конкретной команде:
=> help echo
echo - echo args to console
Usage:
echo [args..]
- echo args to console; \c suppresses newline
=> help bdinfo
bdinfo - print Board Info structure
Usage:
bdinfo
У некоторых команд есть субкоманды, например:
=> help ubi
ubi - ubi commands
Usage:
ubi detach - detach ubi from a mtd partition
ubi part [part] [offset]
- Show or set current partition (with optional VID header offset)
ubi info [l[ayout]] - Display volume and ubi layout information
ubi check volumename - check if volumename exists
ubi create[vol] volume [size] [type] [id] [--skipcheck]
- create volume name with size ('-' for maximum available size)
ubi write[vol] address volume size - Write volume from address with size
ubi write.part address volume size [fullsize]
- Write part of a volume from address
ubi read[vol] address volume [size] - Read volume to address with size
ubi remove[vol] volume - Remove volume
ubi skipcheck volume on/off - Set or clear skip_check flag in volume header
[Legends]
volume: character name
size: specified in bytes
type: s[tatic] or d[ynamic] (default=dynamic)
echo. Команда echo полезна для печати текста. Она не интерпретирует последовательности управления (за исключением \\c, подавляющего newline):
=> echo hello world
hello world
=> echo foo\\c ; echo bar
foobar
bdinfo. Команда bdinfo выводит информационную структуру железа (адреса и размер памяти, MAC и IP адрес, скорость обмена по последовательному интерфейсу консоли).
Команды md, mm, mw полезны для чтения/записи ячеек памяти и регистров.
md. С помощью суффиксов команда md поддерживает выбор ширины доступа к данным - byte/word/long/quad (.b, .w, .l, .q), по умолчанию ширина long, т. е. 32 бита (md == md.l). Поддерживается вывод заданного количества элементов данных (по умолчанию 0x40), например:
mm, nm. Эти команды удобны для интерактивной модификации содержимого памяти и регистров. К ним применимы те же свойства, что и к командам md/mw. Команда mm автоматически инкрементирует адрес, а команда nm этого не делает. Клавиша 'q' выполнит возврат обратно в командную строку U-Boot, а клавиша '-' выполнит возврат к предыдущему адресу. Нажатие Enter без ввода значения пропустит текущий адрес.
cp, cmp. Команда cp позволяет копировать области памяти, а cmp сравнивать их. К этим командам применимы те же свойства, что и к командам md/mw.
[U-Boot environment и команды скриптов]
Environment, или переменные окружения, представляет собой хранилище пар ключ-значение. В нем могут содержаться настроенные конфигурационные значения и скрипты (последовательности выполняемых команд). Окружение по умолчанию встроено в двоичный код U-Boot. Опциональные пользовательские значения могут загружаться из энергонезависимой памяти. Переменные окружения можно изменять, можно их значения сделать постоянными (persistent, т. е. сохраненными в энергонезависимой памяти, чтобы они восстанавливались при последующей перезагрузке). Копия значений переменных окружения находится в RAM, и к ним можно обращаться по имени (ключу) в командах и скриптах.
Поведение команд управления окружением U-Boot очень похоже на поведение аналогичных команд Linux [4].
printenv, env print, echo. Эти команды предназначены для печати переменных окружения. Команда printenv и является псевдонимом (alias) команды env print.
setenv, askenv, editenv. Эти команды предназначены для изменения переменных окружения, и представляют собой legacy-псевдонимы для команд env set, env ask, env edit.
=> env set foo bar
=> env print foo
foo=bar
=> env ask quux "Set quux to ?"
Set quux to ? 1234
=> env print quux
quux=1234
=> env edit quux
edit: 24
=> env print quux
quux=24
Удаление переменных окружения. Установка переменной окружения в пустое значение удалит её из окружения.
=> env set foo bar
=> env print foo
foo=bar
=> env set foo
=> env print foo
## Error: "foo" not defined
saveenv. По умолчанию любые текущие изменения переменной действуют только до перезагрузки, потому что это изменение происходит в текущей копии переменной, находящейся в RAM. Команда saveenv позволит сохранить текущее измененное значение переменной в энергонезависимую память, благодаря чему она восстановится при следующей загрузке.
=> env set foo bar
=> env print foo
foo=bar
=> reset
## Rebooting...
=> env print foo
## Error: "foo" not defined
=> env set foo bar
=> saveenv
=> reset
## Rebooting...
=> env print foo
foo=bar
run. Команда run позволяет запускать скрипты, настроенные в переменных окружения. Скрипт по сути это просто строка текста, состоящая из команд U-Boot. Отдельные команды в этой строке могут быть отделены символом точки с запятой ';'. Эти команды выполняются последовательно, друг за другом. Имейте в виду, что ; игнорирует возвращаемое значение предыдущей команды. Также можно использовать и другие операторы командной строки: |, &, ||, && [].
=> env set foo 'echo hello'
=> run foo
hello
=> env set foo 'echo hello ; echo world'
=> run foo
hello
world
Экранирование символов и расширение переменной. Специальные символы, предназначенные для операторов и для расширения переменной, могут быть экранированы обычным образом с помощью обратного слеша '\'. Вот пример с экранированием символа '$', который расширяет значение переменной:
=> env set foo bar
=> env set quux echo $foo
=> run quux
bar
=> env print quux
quux=echo bar
=> env set quux echo \$foo
=> env print quux
quux=echo $foo
=> env set quux 'echo $foo'
=> env print quux
quux=echo $foo
Специальные переменные. Могут быть определены некоторые переменные для, обладающие зарезервированным назначением. Пример таких переменных:
ver Версия U-Boot.
sddin, stdout, stderr Перенаправление STFIO, см. также команду coninfo.
=> coninfo
List of available devices:
serial 00000003 IO stdin stdout stderr
eserial0 00000003 IO
loadadr. Адрес загрузки по умолчанию.
filesize. Размер загружаемого файла.
bootargs. Аргументы загрузки Linux, передаваемые в её командную строку.
=> echo $bootargs
console=ttyS0,115200
bootcmd. Команда загрузки по умолчанию (см. команды boot и autoboot).
=> echo $bootcmd
if itest.s ${sw_tryactive} == 2; then run boot_by_commit;else run boot_by_tryactive;fi
setexpr. Команда setexpr это многофункциональный инструмент для манипуляции окружением. Она позволяет загрузить содержимое памяти в переменную, поддерживает арифметические операции над переменными и надо памятью (AND, OR, XOR, +, -, *, /, MOD), а также базовые regex-манипуляции над строками и переменными.
Команды true/false. U-Boot поддерживает обработку возвращаемых значений из команд и скриптов. Поддерживаются также автоматические переменные (переменная $? возвратит результат последней выполненной команды). Команды true и false предназначены для возврата результата успеха или неудачи, они установят результат последней выполненной команды.
По традиции программирования успешный результат это значение 0, а ненулевое значение соответствует неудачному результату. Команда true определена для удачного результата, а команда false для неудачного, поэтому их значения довольно неожиданно становятся обратными: true это значение 0, а false это значение 1:
=> true
=> echo $?
0
=> false
=> echo $?
1
Условные выражения. Поддерживаются if, операторы ||, &&. Следует отметить, что не поддерживается "if ! foo ; then ... fi", как обходной маневр вместо этого следует использовать "if foo ; then false ; else ... fi".
=> if true ; then echo "hello" ; else echo "bye" ; fi
hello
=> false || echo "false!"
false!
=> env set foo 'true && echo "true!"'
=> run foo
true!
test. Оболочка HUSH поддерживает минимальную версию команды test.
=> env set i 4
=> test $i -lt 5
=> echo $?
0
=> env set i 6
=> test $i -lt 5
=> echo $?
1
=> if test $i -lt 5 ; then echo "Less than 5" ; \
else echo "More than 5" ; fi
More than 5
for. Пример цикла for:
=> for i in a b c d ; do echo "$i" ; done
a
b
c
d
while. Пример бесконечного цикла while, остановить работу которого можно комбинацией клавиш Ctrl+C:
=> while true ; do echo hello ; done
hello
hello
hello
hello
...
# Ctrl+C
=>
[Команды загрузки данных]
U-Boot поддерживает загрузку из хранилищ различных типов:
• SD/MMC - командой mmc. • USB - командой usb. • SATA - командой sata. • NAND - командой nand. • ...
Поддерживается RAW-носитель и файловые системы:
• Универсальный доступ к файловой системе - команды ls, load. • ExtFS - legacy-команды extls, extload. • VFAT - legacy-команды fatls, fatload. • UBI/UBIFS - команда ubi. • ...
Squashfs [5] не поддерживается, однако делаются попытки её внедрения [6].
Загрузка из сети. U-Boot поддерживает только сетевой стек UDP (соединения TCP не поддерживаются).
• Поддерживается TFTP, NFS (через UDP), DHCP/BOOTP, ... • ping - ICMP Echo. • Команда tftp выполняет загрузку по TFTP (tftpput для выгрузки). • dhcp - получение настроек от DHCP и загрузка файла.
Пример:
=> env set ethaddr 00:aa:bb:cc:dd:ee
=> env set ipaddr 192.168.1.30
=> env set netmask 255.255.255.0
=> env set serverip 192.168.1.1
=> ping $serverip
=> tftp $loadaddr $serverip:somefile
=> dhcp $loadaddr $serverip:somefile
30408.pts-4.0001NBB0203LZB4
Примечание: установка MAC-адреса необязательна, потому что вероятно это уже настроено в окружении U-Boot.
Загрузка через последовательный порт. Когда больше ничего нет, обычно для загрузки доступен UART. U-Boot поддерживает протоколы XMODEM, YMODEM, Srecord и kermit. Пример:
Или из другого шелла того же самого компьютера хоста:
$ screen -x -r -X exec \!\! sb -T yourbinary.bin
[Загрузка kernel]
Существует несколько поддерживаемых форматов образа.
(z)Image:
• Linux binary (с декомпрессором, распаковывающим код в RAM). • Нет защиты от bitrot. • Просто настраивает регистры и выполняет переход в образ. • Опционально отдельное Device Tree.
uImage:
• Старый наследуемый формат. • Обертка над произвольным бинарником (только над одним файлом). • Контрольная сумма CRC32 и небольшое количество метаданных. • Опционально отдельное Device Tree.
fitImage. Это современный формат, образ состоит из нескольких компонентов:
• Основан на Device Tree. • Поддерживает несколько файлов. • Конфигурируемый алгоритм контрольной суммы для каждого элемента. • Поддержка цифровых подписей.
Для загрузки могут использоваться команды:
boot - загрузка по умолчанию, например run 'bootcmd' bootd - то же самое bootelf - загрузка из образа ELF в память booti - загрузка образа ARM64 bootm - загрузка образа приложения из памяти (автодетект формат: fitImage, uImage) bootp - загрузка образа через сеть с использованием протокола BOOTP/TFTP bootvx - загрузка vxWorks из образа ELF bootz - загрузка (z)Image
Пример:
=> help bootz
bootz - boot Linux zImage image from memory
Usage:
bootz [addr [initrd[:size]] [fdt]]
- boot Linux zImage stored in memory
The argument 'initrd' is optional... The optional arg
':size' allows specifying the size of RAW initrd.
When booting a Linux kernel which requires a flat
device-tree a thitd argument is required which is
the address of the device-tree blob.
=> env set bootargs console=tty0,115200
=> load mmc 0:1 0x82000000 boot/zImage-4.9.82-ti-r102
9970640 bytes read in 673 ms (14.1 MiB/s)
=> load mmc 0:1 0x88000000 boot/dtbs/4.9.82-ti-r102/\
am335x-pocketbeagle.dtb
132769 bytes read in 180 ms (719.7 KiB/s)
=> bootz 0x82000000 - 0x88000000
## Flattened Device Tree blob at 88000000
Booting using the fdt blob at 0x88000000
Loading Device Tree to 8ffdc000, end 8ffff6a0 ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.9.82-ti-r102 \
(root@b2-am57xx-beagle-x15-2gb) (gcc version 6.3.0 20170516
(Debian 6.3.0-18) ) #1 SMP PREEMPT Thu Feb 22 01:16:12 UTC)
[ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARM7)
Device Tree. Это структура данных, описывающая оборудование (hardware, HW) устройства. Обычно она передается в OS, чтобы предоставить информацию топологии HW, которая не может быть детектирована или прочитана автоматически. Структура представляет собой нециклический граф, содержащий именованные узлы с их свойствами. Узлы могут содержать свойства и дочерние узлы.
Свойства представлены парами имя-значение. Свойства могут ссылаться на другие узлы с помощью так называемых phandle, где имя узла указывается в угловых скобках. Например, "< &L2>" это сылка на узел кэша L2. phandle могут использоваться для ссылки на узлы в любом месте Device Tree.
bootm $fitimageaddr - boot fitImage/uImage. iminfo - печать информации образа. imxtract - распаковка файла из fitImage/uImage.
=> iminfo $loadaddr
## Checking Image at 0x82000000 ...
FIT image found
FIT description: Linux kernel and FDT blob for am335x-pocketimage
Created: 2018-09-03 0:46:36 UTC
Image 0 (kernel@1)
Description: Linux kernel (Mon Sep 3 02:46:36 CEST 2013)
Created: 2018-09-03 0:46:36 UTC
Type: Kernel Image
Compression: uncompressed
Data Start: 0x02000154
Data Size: 5565328 bytes = 5.4 MiB
Architecture: ARM
OS: Linux
Load Address: 0x80008000
Entry Point: 0x80008000
Hash algo: crc32
Hash value: 1a1062ee
...
=> imxtract $loadaddr kernel@1 0x8a000000
## Copying 'kernel@1' subimage from FIT image at 82000000 ...
crc32+ Loading part 0 ... OK
=> md 0x8a000000
8a000000 e1a00000 e1a00000 e1a00000 e1a00000 ................
8a000010 e1a00000 e1a00000 e1a00000 e1a00000 ................
8a000020 e1a00005 016f2818 00000000 00667230 .....{o.....OrV.
Команда fdt. Команда fdt позволяет выполнять следующие действия:
fdt addr - указывает U-Boot, где находится FDT. fdt resize - добавляет к FDT дополнительное пространство. fdt print - печатает путь FDT. fdt set- добавляет или изменяет элемент FDT.
gpio. Эта команда полезна для переключения уровня выходов GPIO и чтения входов GPIO.
gpio input - чтение уровня на входе GPIO. gpio set - установит уровень лог. 1 на выходе GPIO. gpio clear - установит уровень лог. 0 на выходе GPIO. gpio toggle - переключит уровень на выходе GPIO в противоположное значение.
=> gpio input 45
gpio: pin 45 (gpio 45) value is 1
=> echo $?
1
=> gpio set 53
gpio: pin 53 (gpio 53) value is 1
i2c. Позволяет обращаться к шине I2C.
i2c bus - выведет список доступных шин I2C. i2c dev - выберет шину I2C. i2c md - прочитает регистры из устройства I2C. i2c mv - запишет регистры в устройстве I2C. i2c probe - опрос устройств на I2C. i2c speed - установит скорость шины I2C.
=> i2c dev 2
Setting bus to 2
=> i2c probe
Valid chip addresses: 1C
=> i2c md 0x1c 0x0 0x8
0000: 00 41 ac 01 fc 7f 10 00 .A......
Дополнительную информацию по командам U-Boot см. по ссылкам [2, 3].
[Компиляция U-Boot]
Исходный код доступен по протоколам Git и HTTP в следующих источниках.
$ git clone git://git.denx.de/u-boot.git
$ cd u-boot
$ export CROSS_COMPILE=arm-linux-gnueabihf- # опциональная настройка кросс-компилятора
$ make am335x_evm_defconfig
$ make
Подготовка к кросс-компиляции под нужную целевую платформу. Необходимо настроить переменные окружения: PATH должна содержать путь до используемого тулчейна компиляции, CROSS_COMPILE и ARCH должны содержать название имена, описывающие используемую архитектуру процессора.
Компиляция выполняется переходом в каталог проекта (папка u-boot) и запуском команды make, где в её командной строке указывается файл конфигурации, например так:
$ cd u-boot
$ make TQM823L_defconfig
При завершении успешной компиляции в основном каталоге проекта появится файл u-boot.bin, это двоичный исполняемый код, предназначенный для работы непосредственно в устройстве (он загружается или прошивается в адресное пространство, откуда начинается выполнение кода при сбросе или включении питания устройства).
В частности, также могут использоваться и другие результаты компиляции:
u-boot - исполняемый файл в ELF-формате, используемый для отладчиков. u-boot.img - код наподобие u-boot.bin, но с добавленным заголовком. u-boot.srec - исполняемый код в формате Motorola S-Record, используемый для последовательных соединений. MLO - Secondary Program Loader (собирается только при необходимости).
Кроме целевых процессоров, U-Boot можно скомпилировать для целей демонстрации:
• Песочница U-Boot (sandox_defconfig), позволяет запустить U-Boot как приложение userspace. • Симулятор QEMU (qemu_defconfig), позволяет запустить U-Boot в QEMU как "BIOS".
Эта ошибка возникла из-за того, что исходный код был распакован из ZIP-архива, где не были сохранены атрибуты файлов.
Как исправить:
$ chmod -R +x ./scripts/*.sh
2. Ошибка компиляции:
...
tools/mkeficapsule.c:20:10: fatal error: gnutls/gnutls.h: No such file or directory
20 | #include < gnutls/gnutls.h>
| ^~~~~~~~~~~~~~~~~
.. связана с отсутствием установленной библиотеки gnutls. Как исправить:
Сначала надо узнать имя библиотеки:
$ sudo apt list | grep libgnutls
Из выведенного списка очевидно, что кандидат на имя библиотеки libgnutls28-dev. После этого её надо установить:
$ sudo apt-get install libgnutls28-dev
3. Ошибки компиляции:
cmd/printf.c:403:9: error: ‘errno’ undeclared (first use in this function)
403 | errno = 0;
| ^~~~~
cmd/printf.c:93:1: note: ‘errno’ is defined in header ‘< errno.h>’; did you
forget to ‘#include < errno.h>’?
include/ctype.h:1:1: error: expected identifier or ‘(’ before numeric constant
1 | linux/ctype.h
...
include/ctype.h:1:1: error: expected identifier or ‘(’ before numeric constant
1 | linux/ctype.h
| ^~~~~
.. устраняются правкой заголовка include/ctype.h. По непонятной причине в нем было пропущено ключевое слово #include. Т. е. надо строчку "linux/ctype.h" исправить на:
#include < linux/ctype.h>
4. Ошибка отсутствия утилиты cert-to-efi-sig-list:
CAPSULE_ESL_GEN test/overlay/capsule_esl_file
/bin/sh: 1: cert-to-efi-sig-list: not found
make[1]: *** [scripts/Makefile.lib:392: test/overlay/capsule_esl_file] Error 127
make: *** [Makefile:1915: test/overlay] Error 2
.. связана с ошибкой символической ссылки ./tools/binman/binman, которая должна ссылаться на файл ./tools/binman/main.py. Это проще всего исправить, если заново создать символическую ссылку binman:
Утилита mkimage используется для создания образов U-Boot, в которых содержится Linux kernel, корневая файловая система (root file system), firmware, блок описания дерева устройств (device tree blob, DTB) и многое другое. Образы могут быть либо в legacy-формате uImage или zImage (например для ARM), либо в более современном FIT-формате fitImage (например для PowerPC).
Пример генерации uImage (опция -a указывает адрес загрузки, опция -e указывает точку входа):
$ mkimage -A arm -O linux -T kernel -C gzip -a 0x80008000 -e \
0x80008000 -n 'Linux' -d zImage uImage
Пример генерации fitImage:
$ mkimage -f kernel.its kernel.itb
[Загрузка образов]
Загрузка из систем хранения. Следующая команда может использоваться для загрузки файлов из разделов FAT:
# fatload mmc 0:1 83000000 uImage
Здесь в командной строке fatload используются опции:
mmc - указывает интерфейс карт MMC. 0 - обозначает первое устройство. 1 - обозначает первый раздел на устройстве. 83000000 - выбранная область RAM для загрузки (байтовый адрес в HEX-формате). uImage - файл для загрузки.
Загрузка по сети. Загрузку образа можно выполнить по протоколам TFTP и DHCP. Чтобы произвести загрузку через TFTP, необходимо установить переменные окружения ipaddr для текущего адреса устройства и serverip для адреса сервера, где находится загружаемый файл образа:
Запись NAND. Загруженный образ может быть запрограммирован в flash-память NAND. Для защиты содержимого памяти от повреждений используется кодировка ECC (Error Correction Coding), изучите документацию на вашу плату.
В этом примере 0x400000 байт данных образа, находящихся в RAM по адресу 0x83000000, записываются в память NAND по адресу 0x300000.
Чтение NAND. Подобным образом данные могут быть прочитаны из NAND:
# nand read 83000000 300000 400000
Эта команда вычитывает 0x400000 байт данных из NAND по адресу 0x300000 и помещает их в RAM по адресу 0x83000000.
[Boot Kernel]
Ядро, загруженное в память, может быть запущено командой:
bootm < addr_kernel> < addr_ramdisk> < addr_dtb>
Если не предоставляется initramfs, то за адресом ядра kernel может идти -, и далее идет адрес addr_dtb, указывающий на блок дерева устройств. Пример:
# bootm 83000000 - 84000000
[Автоматизация загрузки]
Чтобы создать скрипты U-Boot:
1. Сохраните все команды U-Boot в текстовый файл. 2. Преобразуйте текстовый файл в образ U-Boot с помощью утилиты mkimage. 3. Загрузите файл с помощью TFTP на целевую машину. 4. Используйте "source" для выполнения скрипта.
Вы можете также создать переменную командой setenv, где содержатся все команды. После этого можно запускать эту переменную как скрипт с помощью команды run.
[Falcon Mode]
Это ускоренная процедура загрузки [9, 10], состоящая из последовательности шагов:
ROM -> SPL -> u-boot.bin -> kernel
Разрешение этой конфигурации требует специальной сборки U-Boot после модификации большого количества параметров, находящихся в нескольких конфигурационных файлах.