LINUX.ORG.RU

u-boot некорректно исполняет boot.scr

 , ,


1

2

Поставил задачу - сделать загрузочную SD-карту для Orange Pi Zero с u-boot и ядром 4.15 (для дистрибутива Ubuntu 18.04 LTS)

Имеющиеся дистрибутивы на оф.сайте Orange Pi плохо поддерживаются и практически не обновляются.

Orange Pi Zero (https://linux-sunxi.org/Xunlong_Orange_Pi_Zero), SoC Allwiner H2+ 1 ГГц, ОЗУ 256 Мб

1. ПОДГОТОВКА

Собрал загрузчик из последней ревизии главной ветки проекта u-boot git clone --depth 1 --single-branch --branch master https://github.com/u-boot/u-boot.git

В целях отладки перед сборкой установил в .config параметр CONFIG_LOGLEVEL=8 (вместо стандартного 4).

Получил на выходе:

u-boot-sunxi-with-spl.bin – загрузчик

sun8i-h2-plus-orangepi-zero.dtb – древовидное описание устройства

Собрал ядро Linux версии 4.15 (с этой версией, согласно Википедии, работает LTS дистрибутив Ubuntu 18.04).

Получил на выходе:

uImage – образ ядра

Составил boot.cmd следующего содержания:

echo BOOT.SCR BEGIN
#setenv machid 1029
setenv bootargs console=ttyS0,115200 console=tty1 root=/dev/mmcblk0p2 init=/sbin/init rootwait rootfstype=ext4 panic=10 consoleblank=0 enforcing=0 loglevel=7
load mmc 0 0x42000000 uImage
load mmc 0 0x43000000 sun8i-h2-plus-orangepi-zero.dtb
bootm 0x42000000 - 0x43000000

Преобразовал это в boot.scr mkimage -C none -A arm -T script -d boot.cmd boot.scr

2. ЗАПИСЬ

Записал на флешку с помощью dd u-boot-sunxi-with-spl.bin

На первый раздел с «загрузочным» флагом скопировал файлы: uImage, sun8i-h2-plus-orangepi-zero.dtb, boot.cmd

3. ПРОВЕРКА

Первая загрузка. Вывод консоли контролирую через последовательный порт.

U-Boot SPL 2020.01-rc3 (Nov 19 2019 - 19:19:59 +0300)
DRAM: 256 MiB
Trying to boot from MMC1


U-Boot 2020.01-rc3 (Nov 19 2019 - 19:19:59 +0300) Allwinner Technology

CPU:   Allwinner H3 (SUN8I 1680)
Model: Xunlong Orange Pi Zero
DRAM:  256 MiB
MMC:   mmc@1c0f000: 0, mmc@1c10000: 1
Loading Environment from FAT... *** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   phy interface0
eth0: ethernet@1c30000
starting USB...
Bus usb@1c1a000: USB EHCI 1.00
Bus usb@1c1a400: USB OHCI 1.0
Bus usb@1c1b000: USB EHCI 1.00
Bus usb@1c1b400: USB OHCI 1.0
scanning bus usb@1c1a000 for devices... 1 USB Device(s) found
scanning bus usb@1c1a400 for devices... 1 USB Device(s) found
scanning bus usb@1c1b000 for devices... 1 USB Device(s) found
scanning bus usb@1c1b400 for devices... 1 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
395 bytes read in 4 ms (95.7 KiB/s)
## Executing script at 43100000
BOOT.SCR BEGIN
Wrong Image Format for bootm command
ERROR: can't get kernel image!
SCRIPT FAILED: continuing...
15297 bytes read in 8 ms (1.8 MiB/s)

Device 0: unknown device
_sun8i_emac_eth_init: Timeout
missing environment variable: pxeuuid
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/01-02-42-c1-50-2c-d1
ethernet@1c30000 Waiting for PHY auto negotiation to complete......... TIMEOUT !
*** ERROR: `serverip' not set
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000000

Провал!

Почему-то команды из boot.scr на копирование файлов в память устройства fatload игнорируются, но echo и bootm выполняются.

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

=> crc32 0x42000000 0x3a1570
crc32 0x42000000 0x3a1570
crc32 for 42000000 ... 423a156f ==> aa7c90eb
=> fatload mmc 0 0x42000000 uImage
fatload mmc 0 0x42000000 uImage
3806576 bytes read in 198 ms (18.3 MiB/s)
=> crc32 0x42000000 0x3a1570
crc32 0x42000000 0x3a1570
crc32 for 42000000 ... 423a156f ==> dccd4918

dccd4918 – это правильная контрольная сумма. Т.е. загрузка в память из boot.scr действительно не выполнялась, а вручную файл в память загружается нормально.

Если в самом начале загрузки перехватить управление в u-boot и проверить доступ к SD-карте – всё ОК, доступ есть (да и boot.scr u-boot без проблем берет с карты).

=> fatls mmc 0
fatls mmc 0
    15297   sun8i-h2-plus-orangepi-zero.dtb
  3806576   uImage
      395   boot.scr

3 file(s), 0 dir(s)

Пробую ручную загрузку - ядро загружается и происходит нормальный старт!!!

U-Boot SPL 2020.01-rc3 (Nov 19 2019 - 19:19:59 +0300)
DRAM: 256 MiB
Trying to boot from MMC1


U-Boot 2020.01-rc3 (Nov 19 2019 - 19:19:59 +0300) Allwinner Technology

CPU:   Allwinner H3 (SUN8I 1680)
Model: Xunlong Orange Pi Zero
DRAM:  256 MiB
MMC:   mmc@1c0f000: 0, mmc@1c10000: 1
Loading Environment from FAT... *** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   phy interface0
eth0: ethernet@1c30000
starting USB...
Bus usb@1c1a000: USB EHCI 1.00
Bus usb@1c1a400: USB OHCI 1.0
Bus usb@1c1b000: USB EHCI 1.00
Bus usb@1c1b400: USB OHCI 1.0
scanning bus usb@1c1a000 for devices... 1 USB Device(s) found
scanning bus usb@1c1a400 for devices... 1 USB Device(s) found
scanning bus usb@1c1b000 for devices... 1 USB Device(s) found
scanning bus usb@1c1b400 for devices... 1 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot:  2 
 0 
=> fatload mmc 0 0x42000000 uImage
fatload mmc 0 0x42000000 uImage
3806576 bytes read in 198 ms (18.3 MiB/s)
=> fatload mmc 0 x 0x43000000 sun8i-h2-plus-orangepi-zero.dtb
fatload mmc 0 0x43000000 sun8i-h2-plus-orangepi-zero.dtb
15297 bytes read in 7 ms (2.1 MiB/s)
=> bootm 0x42000000 - 0x43000000
bootm 0x42000000 - 0x43000000
## Booting kernel from Legacy Image at 42000000 ...
   Image Name:   Linux-4.15.0
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3806512 Bytes = 3.6 MiB
   Load Address: 40008000
   Entry Point:  40008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 43000000
   Booting using the fdt blob at 0x43000000
EHCI failed to shut down host controller.
   Loading Kernel Image
   Loading Device Tree to 49ff9000, end 49fffbc0 ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.15.0 (slarti@RUMP) (gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1)) #2 SMP Tue Nov 19 21:05:53 MSK 2019
[    0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt: Machine model: Xunlong Orange Pi Zero
...
[    2.166572] [<c0150380>] (cpu_startup_entry) from [<401017ac>] (0x401017ac)
[    2.173537] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

Учитывая отсутствие второго раздела на SD-карте, ловлю Kernel Panic - это нормально.

Пробовал в boot.cmd менять fatload на load – безрезультатно, пробовал указывать вместо «mmc 0» адрес с разделом «mmc 0:1» – безрезультатно.

printenv ниже:

arch=arm
baudrate=115200
board=sunxi
board_name=sunxi
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_efi_binary=if fdt addr ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr ${fdtcontroladdr};fi;load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootarm.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
boot_net_usb_start=usb start
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_syslinux_conf=extlinux/extlinux.conf
boot_targets=fel mmc0 usb0 pxe dhcp
bootargs=console=ttyS0,115200 console=tty1 root=/dev/mmcblk0p2 init=/sbin/init rootwait rootfstype=ext4 panic=10 consoleblank=0 enforcing=0 loglevel=7
bootcmd=run distro_bootcmd
bootcmd_dhcp=run boot_net_usb_start; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; setenv efi_old_vci ${bootp_vci};setenv efi_old_arch ${bootp_arch};setenv bootp_vci PXEClient:Arch:00010:UNDI:003000;setenv bootp_arch 0xa;if dhcp ${kernel_addr_r}; then tftpboot ${fdt_addr_r} dtb/${efi_fdtfile};if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r}; else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi;fi;setenv bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv efi_fdtfile;setenv efi_old_arch;setenv efi_old_vci;
bootcmd_fel=if test -n ${fel_booted} && test -n ${fel_scriptaddr}; then echo '(FEL boot)'; source ${fel_scriptaddr}; fi
bootcmd_mmc0=devnum=0; run mmc_boot
bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi
bootcmd_usb0=devnum=0; run usb_boot
bootdelay=2
bootfstype=fat
bootm_size=0xa000000
console=ttyS0,115200
cpu=armv7
dfu_alt_info_ram=kernel ram 0x42000000 0x1000000;fdt ram 0x43000000 0x100000;ramdisk ram 0x43300000 0x4000000
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
efi_dtb_prefixes=/ /dtb/ /dtb/current/
eth1addr=12:42:c1:50:2c:d1
ethact=ethernet@1c30000
ethaddr=02:42:c1:50:2c:d1
fdt_addr_r=0x43000000
fdtcontroladdr=4bf59080
fdtfile=sun8i-h2-plus-orangepi-zero.dtb
fileaddr=43000000
filesize=3bc1
kernel_addr_r=0x42000000
load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
mmc_bootdev=0
partitions=name=loader1,start=8k,size=32k,uuid=${uuid_gpt_loader1};name=loader2,size=984k,uuid=${uuid_gpt_loader2};name=esp,size=128M,bootable,uuid=${uuid_gpt_esp};name=system,size=-,uuid=${uuid_gpt_system};
preboot=usb start
pxefile_addr_r=0x43200000
ramdisk_addr_r=0x43300000
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done; setenv devplist
scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootarm.efi; then echo Found EFI removable media binary efi/boot/bootarm.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x43100000
serial#=02c00042c1502cd1
soc=sunxi
stderr=serial
stdin=serial,usbkbd
stdout=serial
usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fi
uuid_gpt_esp=c12a7328-f81f-11d2-ba4b-00a0c93ec93b
uuid_gpt_system=69dad710-2ce4-4e3c-b16c-21a1d49abed3

Environment size: 4665/131068 bytes 
ВОПРОС: почему не выполняются fatload из boot.scr? При этом echo и bootm выполняются исправно.

Ответ на: комментарий от Jetty

Точно нет разницы!

Я пробовал и fatload, и load. И с указанием разделов mmc0, и без. Одинаково безрезультатно.

Пробовал разные версии mkimage – безрезультатно.

Сейчас через костыли сделал так:

  1. В переменную bootcmd прописываю эквивалент boot.cmd

bootcmd=load mmc 0 0x42000000 uImage; load mmc 0x43000000 многобукв.dtb; bootm 0x42000000 - 0x43000000

  1. Удаляю через консоль u-boot лишнее из environment через env delete и сохраняю все через saveenv в файл uboot.env

И ядро стартует без проблем. Но это неверный подход.

Вопрос с boot.scr актуален.

yohabi ()
Ответ на: комментарий от mittorn

Нет, не вантузятник, а пользователь Windows! И собираю образ эпизодической загрузкой livecd.

А преданно лелеять различия в формате перевода строки в 2019 году - это позор адептам Линукса.

И, скажите, «не ужели» ваш неграмотный выпад в таком манере сильно помогает этому форуму?

yohabi ()
Ответ на: комментарий от yohabi

позор адептам Линукса

Вот жеж блин… как пользователь Linux такого позора я еще никогда не испытывал. Сижу вот в кресле, красный, как помидор, с трудом собирая мысли о том, как жить дальше.

seiken ★★★★★ ()
Ответ на: комментарий от yohabi

А преданно лелеять различия в формате перевода строки в 2019 году - это позор адептам Линукса.

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

А ещё они говорили , что «пользователь Windows!» такие все мягкие и пушистые …

anonymous ()

Прошу объяснить

Коллеги, помогите разобраться, пожалуйста. U-Boot, DeviceTree и Linux Kernel по мере развития много раз меняют форматы. В итоге в инете полно рецептов приготовления загрузчика, ядра, в результате которых на выходе появляются самые разные наборы файлов, а именно:

  • MLO
  • u-boot.img
  • uEnv.txt
  • zImage
  • uImage
  • boot.scr
  • vmlinuz-4.14.108
  • initrd.img-4.14.108

Часто в статьях даже не указана дата публикации, потому оценить актуальность становится сложно.

Вопрос: как нужно готовить u-boot, devicetree, kernel по сегодняшним актуальным нормам? Devicetree компилировать с загрузчиком или с ядром? Что получаем на выходе? Где хранить ядро и в каком формате?

Если это имеет значение, то интересует в контексте SOC TI AM335x.

Solncevorot ()