Загрузчик U-Boot |
![]() |
Добавил(а) microsin |
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
В приглашении командной строки => доступны множество функций - запуск дальнейшей загрузки определенного ядра, манипуляции с деревом устройств (device tree), работа с переменными окружения, просмотр и модификация ячеек адресного пространства и многое другое. Поскольку поведение U-Boot может быть автоматизировано настройками, пользователю не обязательно нужно каждый раз вводить управляющие команды, чтобы загрузить рабочую систему Linux с нужными параметрами. Основные функции SPL: • Собирается из того же исходного кода, что и U-Boot. TPL - Tertiary Program Loader. • Собирается из того же исходного кода, что и U-Boot. [Назначение файлов и папок исходного кода 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 ubi
ubi - ubi commands
echo. Команда echo полезна для печати текста. Она не интерпретирует последовательности управления (за исключением \\c, подавляющего newline): => echo hello world
hello world
=> echo foo\\c ; echo bar
foobar
bdinfo. Команда bdinfo выводит информационную структуру железа (адреса и размер памяти, MAC и IP адрес, скорость обмена по последовательному интерфейсу консоли). => bdinfo
boot_params = 0x8f735408
memstart = 0x80000000
memsize = 0x10000000
flashstart = 0x00000000
flashsize = 0x00000000
flashoffset = 0x00000000
ethaddr = 00:E0:4C:86:70:01
IP addr = 192.168.1.3
baudrate = 115200 bps
relocaddr = 0x8ff70000
reloc off = 0x0c370000
[Команды доступа к памяти] Команды md, mm, mw полезны для чтения/записи ячеек памяти и регистров. md. С помощью суффиксов команда md поддерживает выбор ширины доступа к данным - byte/word/long/quad (.b, .w, .l, .q), по умолчанию ширина long, т. е. 32 бита (md == md.l). Поддерживается вывод заданного количества элементов данных (по умолчанию 0x40), например: => md 0x80000000
80000000: 10000001 40804800 2408fff0 3c098040 ....@.H.$...< ..@
80000010: 0128e824 27bdff54 03a8e824 03a0d021 .(.$'..T...$...!
80000020: 240a0400 03aae823 03a8e824 03a0f021 $......#...$...!
80000030: 03404021 ad000000 0109082a 1420fffd .@@!.......*. ..
80000040: 25080004 af5d009c 3c1983c0 27396e54 %....]..< ...'9nT
80000050: 0320f809 00000000 00002021 3c1983c1 . ........ !< ...
80000060: 27395d90 03200008 0000f821 00000000 '9].. .....!....
80000070: 40027800 00021382 30420001 10400009 @.x.....0B...@..
80000080: 00000000 4008a000 2409fffd 01094024 ....@...$.....@$
80000090: 4088a000 35080002 4088a000 03e00008 @...5...@.......
800000a0: 00000000 40088001 00082402 30840007 ....@.....$.0...
800000b0: 20840001 00082cc2 30a50007 20a50001 .....,.0... ...
800000c0: 00083582 30c60007 20c60006 24080001 ..5.0... ...$...
800000d0: 00c53020 00c83004 70c41002 00a81804 ..0 ..0.p.......
800000e0: 3c048000 00822820 00804021 bd000000 < .....( ..@!....
800000f0: 0000000f 21080010 0105082a 1420fffb ....!......*. ..
Если было указано количество выводимых элементов памяти, то оно впоследствии запоминается как умолчание. => md.b 0x80000000 0x8
80000000: 10 00 00 01 40 80 48 00 ....@.H.
=> md.l 0x80000000
80000000: 10000001 40804800 2408fff0 3c098040 ....@.H.$...< ..@
80000010: 0128e824 27bdff54 03a8e824 03a0d021 .(.$'..T...$...!
Простое нажатие Enter после команды md позволяет последовательно выводить адреса блоков с автоматическим инкрементом адреса: => md 0x80000000 8
80000000: 10000001 40804800 2408fff0 3c098040 ....@.H.$...< ..@
80000010: 0128e824 27bdff54 03a8e824 03a0d021 .(.$'..T...$...!
=>
80000020: 240a0400 03aae823 03a8e824 03a0f021 $......#...$...!
80000030: 03404021 ad000000 0109082a 1420fffd .@@!.......*. ..
=>
80000040: 25080004 af5d009c 3c1983c0 27396e54 %....]..< ...'9nT
80000050: 0320f809 00000000 00002021 3c1983c1 . ........ !< ...
mm, nm. Эти команды удобны для интерактивной модификации содержимого памяти и регистров. К ним применимы те же свойства, что и к командам md/mw. Команда mm автоматически инкрементирует адрес, а команда nm этого не делает. Клавиша 'q' выполнит возврат обратно в командную строку U-Boot, а клавиша '-' выполнит возврат к предыдущему адресу. Нажатие Enter без ввода значения пропустит текущий адрес. => mm 0x4804c134
4804c134: ffffffff ? fe1fffff
4804c138: f0002300 ?
4804c13c: 00000000 ? 00400000
4804c140: 00000000 ? q
=>
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. => env print
_updev=tftp ${tftp_base} ${ubi_device_img_name} && nand erase ${fl_ubidevice} ${fl_ubidevice_sz} \
&& nand write ${fileaddr} ${fl_ubidevice} ${filesize} && run set_comm0
_updev_bk=ubi read ${tftp_base} ubi_Config && ubi detach && setenv tftp_tmp ${tftp_base} \
&& setenv tftp_base ${tftp_base_bk} && run _updev && setenv tftp_base ${tftp_}
baudrate=115200
boot_by_commit=if itest.s ${sw_commit} == 0;then run set_act0;run ub0;else run set_act1;run ub1;fi
boot_by_tryactive=if itest.s ${sw_tryactive} == 0;then setenv sw_tryactive 2;setenv sw_active 0; \
saveenv;run en_wdt;run ub0;else setenv sw_tryactive 2;setenv sw_active i
bootargs=console=ttyS0,115200
bootargs_base=console=ttyS0,115200
bootcmd=if itest.s ${sw_tryactive} == 2; then run boot_by_commit;else run boot_by_tryactive;fi
bootdelay=1
bootloader_crc=a1bbb412
...
Environment size: 6299/131067 bytes
=>
=> env print serverip
serverip=192.168.1.1
=> printenv serverip
serverip=192.168.1.1
=> echo "$serverip"
192.168.1.1
setenv, askenv, editenv. Эти команды предназначены для изменения переменных окружения, и представляют собой legacy-псевдонимы для команд env set, env ask, env edit. => env set foo bar
=> env print foo
foo=bar
Удаление переменных окружения. Установка переменной окружения в пустое значение удалит её из окружения. => 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 bar
=> env set quux echo $foo
=> run quux
bar
=> env print quux
quux=echo bar
Специальные переменные. Могут быть определены некоторые переменные для, обладающие зарезервированным назначением. Пример таких переменных: 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
preboot. Скрипт, выполняемый перед autoboot. ipaddr, netmask, serverip, gatewayip. Настройки сети. ethaddr, eth1addr, ... MAC-адрес Ethernet. setexpr. Команда setexpr это многофункциональный инструмент для манипуляции окружением. Она позволяет загрузить содержимое памяти в переменную, поддерживает арифметические операции над переменными и надо памятью (AND, OR, XOR, +, -, *, /, MOD), а также базовые regex-манипуляции над строками и переменными. => md 0x9ff4e000 1
9ff4e000: ea0000b8
=> setexpr foo *0x9ff4e000
=> env print foo
foo=ea0000b8
[Условные выражения и циклы shell] Команды 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!
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. Поддерживается RAW-носитель и файловые системы: • Универсальный доступ к файловой системе - команды ls, load. Squashfs [5] не поддерживается, однако делаются попытки её внедрения [6]. Пример загрузки с карты MMC: => mmc rescan
=> mmc part
Загрузка из сети. U-Boot поддерживает только сетевой стек UDP (соединения TCP не поддерживаются). • Поддерживается TFTP, NFS (через UDP), DHCP/BOOTP, ... Пример: => 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. Пример: U-Boot> loady
< отправка файла по протоколу ymodem, например sb -T>
Или из другого шелла того же самого компьютера хоста: $ screen -x -r -X exec \!\! sb -T yourbinary.bin
[Загрузка kernel] Существует несколько поддерживаемых форматов образа. (z)Image: • Linux binary (с декомпрессором, распаковывающим код в RAM). uImage: • Старый наследуемый формат. fitImage. Это современный формат, образ состоит из нескольких компонентов: • Основан на Device Tree. Для загрузки могут использоваться команды: boot - загрузка по умолчанию, например run 'bootcmd' Пример: => help bootz
bootz - boot Linux zImage image from memory
Device Tree. Это структура данных, описывающая оборудование (hardware, HW) устройства. Обычно она передается в OS, чтобы предоставить информацию топологии HW, которая не может быть детектирована или прочитана автоматически. Структура представляет собой нециклический граф, содержащий именованные узлы с их свойствами. Узлы могут содержать свойства и дочерние узлы. Свойства представлены парами имя-значение. Свойства могут ссылаться на другие узлы с помощью так называемых phandle, где имя узла указывается в угловых скобках. Например, "< &L2>" это сылка на узел кэша L2. phandle могут использоваться для ссылки на узлы в любом месте Device Tree. Подробнее про Device Tree см. Википедию [7]. Пример Device Tree: /dts-v1/ #include "arm-realview-eb-mp.disi" / { model = "ARM RealView EB Cortex A9 MPCore"; [...] cpus { #address-cells = < 1>; #size-cells = < 0>; enable-method = "arm,realview-smp"; A9_0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a9"; reg = < 0>; next-level-cache = < &L2>; }; [...] pmu: pmu@0 { interrupt-affinity = < &A9_0>, < &A9_1>, < &A9_2>, < &A9_3> }; }; Пример fitImage: /dts-v1/; Компиляция: $ mkimage -f fit-image.its fitImage
Команды fitImage: bootm $fitimageaddr - boot fitImage/uImage. => iminfo $loadaddr
Команда fdt. Команда fdt позволяет выполнять следующие действия: fdt addr - указывает U-Boot, где находится FDT. => 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)
=> fdt addr 0x88000000
=> fdt resize
=> fdt print /chosen
chosen {
stdout-path = "/ocp/serial@44e09000";
};
=> fdt set /chosen/ foo bar
=> fdt resize
=> fdt print /chosen
chosen {
foo = "bar";
stdout-path = "/ocp/serial@44e09000";
};
=> bootz = 0x82000000 - 0x88000000
[Другие команды U-Boot] gpio. Эта команда полезна для переключения уровня выходов GPIO и чтения входов GPIO. gpio input - чтение уровня на входе 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 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 master: http://git.denx.de/?p=u-boot.git;a=summary $ 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 должны содержать название имена, описывающие используемую архитектуру процессора. PATH=${HOME}/x-tools/arm-unknown-linux-gnueabi/bin/:$PATH export CROSS_COMPILE=arm-unknown-linux-gnueabi- export ARCH=arm Компиляция выполняется переходом в каталог проекта (папка u-boot) и запуском команды make, где в её командной строке указывается файл конфигурации, например так: $ cd u-boot
$ make TQM823L_defconfig
При завершении успешной компиляции в основном каталоге проекта появится файл u-boot.bin, это двоичный исполняемый код, предназначенный для работы непосредственно в устройстве (он загружается или прошивается в адресное пространство, откуда начинается выполнение кода при сбросе или включении питания устройства). В частности, также могут использоваться и другие результаты компиляции: u-boot - исполняемый файл в ELF-формате, используемый для отладчиков. Кроме целевых процессоров, U-Boot можно скомпилировать для целей демонстрации: • Песочница U-Boot (sandox_defconfig), позволяет запустить U-Boot как приложение userspace. $ qemu-system-arm -M virt -bios u-boot.bin
[Практические лабораторные работы] Примеры работы с PocketBeagle и Techlab: https://beagleboard.org/pocket Компиляция и запуск U-Boot в "песочнице", т. е. на машине хоста: $ git clone git://git.denx.de/u-boot.git
$ cd u-boot
$ chmod -R +x ./scripts/*.sh
$ make sandbox_defconfig
$ make -j $(nproc)
$ ./u-boot
1. Ошибка доступа к скриптам в каталоге scripts: $ make sandbox_defconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
YACC scripts/kconfig/zconf.tab.c
LEX scripts/kconfig/zconf.lex.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
sh: 1: ./scripts/gcc-version.sh: Permission denied
sh: 1: ./scripts/gcc-version.sh: Permission denied
Kconfig:66: syntax error
Kconfig:65: invalid option
sh: 1: ./scripts/clang-version.sh: Permission denied
Kconfig:74: syntax error
Kconfig:73: invalid option
make[1]: *** [scripts/kconfig/Makefile:97: sandbox_defconfig] Error 1
make: *** [Makefile:586: sandbox_defconfig] Error 2
Эта ошибка возникла из-за того, что исходный код был распакован из 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
.. решается установкой efitools: $ sudo apt install efitools
5. Ошибка binman: /bin/sh: 1: ./tools/binman/binman: Permission denied
make: *** [Makefile:1135: .binman_stamp] Error 126
.. связана с ошибкой символической ссылки ./tools/binman/binman, которая должна ссылаться на файл ./tools/binman/main.py. Это проще всего исправить, если заново создать символическую ссылку binman: $ rm ./tools/binman/binman
$ cd ./tools/binman
$ ln -s main.py binman
$ chmod +x binman
$ chmod +s main.py
$ cd ../..
[U-Boot и mkimage] Утилита 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. Загрузка по сети. Загрузку образа можно выполнить по протоколам TFTP и DHCP. Чтобы произвести загрузку через TFTP, необходимо установить переменные окружения ipaddr для текущего адреса устройства и serverip для адреса сервера, где находится загружаемый файл образа: # setenv ipaddr 192.168.100.2
# setenv serverip 192.168.100.1
# saveenv
Запуск загрузки через TFTP: # tftpboot 83000000 uImage
Запись NAND. Загруженный образ может быть запрограммирован в flash-память NAND. Для защиты содержимого памяти от повреждений используется кодировка ECC (Error Correction Coding), изучите документацию на вашу плату. # nandecc hw
# nand erase 300000 400000
# nand write 83000000 300000 400000
В этом примере 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 в текстовый файл. Вы можете также создать переменную командой setenv, где содержатся все команды. После этого можно запускать эту переменную как скрипт с помощью команды run. [Falcon Mode] Это ускоренная процедура загрузки [9, 10], состоящая из последовательности шагов: ROM -> SPL -> u-boot.bin -> kernel Разрешение этой конфигурации требует специальной сборки U-Boot после модификации большого количества параметров, находящихся в нескольких конфигурационных файлах. [Ссылки] 1. Tutorial: Introduction to the Embedded Boot Loader U-boot - Behan Webster, Converse in Code site:youtube.com. |