LINUX.ORG.RU

Embedded: U-Boot + GRUB2

 , , ,


1

1

Добрый день!

Скажу сразу, я в Linux не специалист, но разбираюсь понемногу. Есть задача - вызывать GRUB2 на ARM после U-Boot. Я нашёл несколько статей, где у людей это получалось, к примеру: https://forum.banana-pi.org/t/grub-on-bpi-r2-kernel-starting-problem/10628/7 https://forum.odroid.com/viewtopic.php?t=26894 https://www.hellion.org.uk/blog/posts/grub-on-uboot-on-qemu/ https://2names1scott.com/docs/rockpro64boot.html Но не могу повторить. Что я сделал:

  1. Взял официальный образ Armbian для Orange PI One (Armbian_22.11.1_Orangepione_bullseye_current_5.15.80), записал на SD, загрузился
  2. Обновился, apt install *** (недостающие для компиляции пакеты)
  3. Скачал с гита U-Boot (u-boot-2022.10) и GRUB2 (grub-2.06)
  4. Собрал U-Boot:
    • make orangepi_one_defconfig
    • make menuconfig (включил API и меню)
    • make
  5. Собрал и установил GRUB2
    • ./configure
    • make install
    • grub-install /boot
  6. Записываю на эту же SD новый U-Boot: dd if=/home/u-boot/u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 bs=1024 seek=8
  7. Перезагружаюсь, в консоли U-Boot набираю:
    • ext4load mmc 0:1 0x42000000 /boot/grub/arm-uboot/core.img
    • bootm 0x42000000
Лог по 7-омум пункту:
=> ext4load mmc 0:1 0x42000000 /boot/grub/arm-uboot/core.img
59948 bytes read in 17 ms (3.4 MiB/s)
=> bootm 0x42000000
## Booting kernel from Legacy Image at 42000000 ...
   Image Name:   
   Image Type:   ARM Linux Kernel Image (no loading done) (uncompressed)
   Data Size:    59884 Bytes = 58.5 KiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
EHCI failed to shut down host controller.
   XIP Kernel Image (no loading done)
FDT and ATAGS support not compiled in

resetting ...

Я пробовал другие адреса 0x42000000 - или перезагружается или зависает

Подскажите, что я делаю не так

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

Вы можете помочь с эти адресом? Да и вот с этим: bootm 0x42000000 Везде пишут - заменил на другой, заработало. Но они же не методом «тыка» это делают.

Единственное, что нашёл на просторах: By default grub is built for systems which have RAM at address 0x00000000. However the Versatile Express platform which we are targeting has RAM starting from 0x60000000 so we need to make a couple of modifications. First in grub-core/Makefile.core.def we need to change arm_uboot_ldflags, from: -Wl,-Ttext=0x08000000 to -Wl,-Ttext=0x68000000 and second we need make a similar change to include/grub/offsets.h changing GRUB_KERNEL_ARM_UBOOT_LINK_ADDR from 0x08000000 to 0x68000000.

Как для моей модели узнать начало адресации RAM? Я скачал даташид, нашёл раздел Memory Mapping, там в большой таблице есть строчка DDR-III 0x40000000-0xDFFFFFFF 2G это это? 0x40000000 - начало RAM?

Я готов профинансировать свои знания (если безвозмездно не получится), помогите по шагам

AlexSTAL
() автор топика
Ответ на: комментарий от ValdikSS

Вот ещё нашёл статью: https://linux-sunxi.org/User_talk:Asyring «Grub on u-boot on Cubietruck»:

--- grub2-2.02~beta2.orig/grub-core/Makefile.core.def
+++ grub2-2.02~beta2/grub-core/Makefile.core.def
@@ -95,5 +95,5 @@ kernel = {
  i386_qemu_cppflags     = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
  emu_cflags = '$(CFLAGS_GNULIB)';
  emu_cppflags = '$(CPPFLAGS_GNULIB)';
-  arm_uboot_ldflags       = '-Wl,-Ttext=0x08000000';
+  arm_uboot_ldflags       = '-Wl,-Ttext=0x40008000';
  arm_uboot_stripflags    = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';

--- grub2-2.02~beta2.orig/include/grub/offsets.h
+++ grub2-2.02~beta2/include/grub/offsets.h
@@ -121,3 +121,3 @@
#define GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN        0x8
#define GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE        0x4
-#define GRUB_KERNEL_ARM_UBOOT_LINK_ADDR                0x08000000
+#define GRUB_KERNEL_ARM_UBOOT_LINK_ADDR                0x40008000

Смотрю в исходниках grub2-2.06/grub-core/Makefile.core.def нет строки

arm_uboot_ldflags       = '-Wl,-Ttext=0x08000000';

есть строка

arm_uboot_ldflags       = '-Wl,-r,-d';

Скачал более ранние версии GRUB2, там или вообще нет этой строки или уже как в 2.06

Общим поиском по тексту «arm_uboot» находится следующее: grub2-2.06/include/grub/offsets.h

#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0
#define GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN 	0x8
#define GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE	0x4

Помогите понять смысл

AlexSTAL
() автор топика
Ответ на: комментарий от ValdikSS

Три дня и три ночи не ел и не спал я… Пыхтел над задачей…

Сравнивая код grub-2.02_beta2 (последняя версия, где есть GRUB_KERNEL_ARM_UBOOT_LINK_ADDR) и grub-2.06 - пробовал «патчить» разными способами, в разных местах, на разных этапах - или не имело эффекта, или переставало компилироваться. Решил попробовать воспроизвести на версии grub-2.02_beta2. Не компилируется. Попробовал на всех Debian 7, 8, 9, 10, 11, не сдавался. Нашёл на просторах интернета древний образ непосредственно для ARM - Armbian_5.59_Orangepione_Ubuntu_xenial_default_3.4.113_desktop, с ним скомпилировалось! Сделал сразу несколько версий (с разными Load Address). Не взлетело. Думаю, дай попробую на древней версии U-Boot. И о чудо! На u-boot-2020.01 получилось загрузить GRUB (правда с ошибками, но думаю уже пол-дела сделано).

Далее накомпилировал несколько версий U-Boot 2021-2023 годов и начал тестировать:

  • u-boot-2020.01 +
  • u-boot-2021.04 -
  • u-boot-2021.07 +
  • u-boot-2021.10 +
  • u-boot-2022.01 -
  • u-boot-2022.04 -
  • u-boot-2022.07 -
  • u-boot-2022.10 -
  • u-boot-2023.01 -

Как так то? один и тот же код, одни и те же адреса - где-то работает, где-то нет?

Ладно думаю, возьму u-boot-2021.10 и буду пока с ним пробовать дальше, исправить ошибки загрузки:

Starting kernel ...

Welcome to GRUB!

error: variable `root' isn't set.
Entering rescue mode...
grub rescue> 

ls выдаёт только (hd0), без разделов

Начал читать, изучать. Оказывается, для grub-mkimage нужно указывать конкретную директорию с исходниками, иначе она берёт по умолчанию из операционки. Сделал свой load.cfg:

search.fs_label grub root 
set prefix=($root)'/boot/grub'

изменил метку тома, заработало до следующей ошибки:

error: symbol 'grub_calloc' not found.
Entering rescue mode...
grub rescue>

Что ещё ему не хватает?

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

Победил! Если честно, то мне понравилось «ковыряться»!

Но вопросов ещё вагон. Скажите, где почитать про адреса загрузки, какие можно использовать, какие нет и т.д. Т.е. как по пунктам происходит процесс загрузки?

Почему один и тот же код на разных версиях U-Boot то исполняется, то нет?

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

Занимаюсь аналогичными вещами. Видел интересную книгу по данной тематике, но пока не вчитывался: «Практика загрузки. Изучение процесса загрузки Linux, Windows и Unix» Йогеш Бабар.

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

Связался с одним из разработчиков GRUB - Vladimir Serbinenko. Он мне молниеносно ответил, что нужно подправить в новых версиях, что бы компилировать с другим адресом. Скомпилировал я 2.02, 2.04 и 2.06, проверил адрес, всё ок. Но ни на одной из версий U-Boot они не запустились - или в состоянии загрузка ядра или бесконечный ребут.

U-Boot SPL 2022.10 (Jan 21 2023 - 12:32:10 +0000)
DRAM: 512 MiB
Trying to boot from MMC1
 
U-Boot 2022.10 (Jan 21 2023 - 12:32:10 +0000) Allwinner Technology
 
CPU:   Allwinner H3 (SUN8I 1680)
Model: Xunlong Orange Pi One
DRAM:  512 MiB
Core:  62 devices, 19 uclasses, devicetree: separate
WDT:   Not starting watchdog@1c20ca0
MMC:   mmc@1c0f000: 0
Loading Environment from FAT... Unable to use mmc 0:1...
In:    serial
Out:   serial
Err:   serial
Net:   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... 2 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot:  2  1  0 
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot/boot.scr
2400 bytes read in 5 ms (468.8 KiB/s)
## Executing script at 43100000
U-boot loaded from SD
Boot script loaded from mmc
202 bytes read in 5 ms (39.1 KiB/s)
56360 bytes read in 11 ms (4.9 MiB/s)
## Booting kernel from Legacy Image at 50000000 ...
   Image Name:   
   Image Type:   ARM Linux Kernel Image (no loading done) (uncompressed)
   Data Size:    56296 Bytes = 55 KiB
   Load Address: 48000000
   Entry Point:  48000000
   Verifying Checksum ... OK
EHCI failed to shut down host controller.
   XIP Kernel Image (no loading done)
FDT and ATAGS support not compiled in
 
resetting ...
AlexSTAL
() автор топика
3 сентября 2023 г.
Ответ на: комментарий от AlexSTAL

Found U-Boot script /boot/boot.scr

Зачем оно там? Апстримный u-boot с апстримными конфигами должен автоматически находить esp раздел, грузить efi payload и запускать его. Это должно выглядеть как-то так:

Hit any key to stop autoboot:  0

Device 0: unknown device
switch to partitions #0, OK
mmc1 is current device
Card did not respond to voltage select! : -110

Device 0: Vendor: * Rev: * Prod: *
            Type: Hard Disk
            Capacity: 238475.1 MB = 232.8 GB (488397168 x 512)
... is now current device
Scanning nvme 0:1...
Card did not respond to voltage select! : -110
BootOrder not defined
EFI boot manager: Cannot load any image
Found EFI removable media binary efi/boot/bootriscv64.efi
82569 bytes read in 1 ms (78.7 MiB/s)
Booting /efi\boot\bootriscv64.efi
Tsukasa
()