- U-Boot Standard Boot
- 20230804 - Beaglebone uboot printenv
- 20230804 - Lichee Ubuntu Uboot printenv
- 20230805 - Lichee uboot startup logs
- Really nice description of how to add overlays modifying U-Boot
U-Boot is the piece of software that boot an operating system. It is the one that is run on the MangoPi/lichee. I am trying to understand it in order to add overlays to it.
The order of loading different files in U-Boot is generally as follows:
-
U-Boot Binary: This is the first thing that gets loaded. It contains the U-Boot bootloader, which is responsible for initiating the boot process. In your case, this could be handled by variables like
boot_efi_binary
orboot_efi_bootmgr
in the environment variables you’ve provided. -
Device Tree Blob (DTB): The device tree is a data structure for describing hardware. It is not specific to any particular operating system. Instead, a device tree can provide a boot program with the information it needs to boot the system. The variable
load_efi_dtb
orfdtfile
would handle loading the base device tree. -
Overlays: Overlays are a way of modifying the device tree structure to customize or specialize the hardware configuration without modifying the base DTB. According to the script you’ve provided, overlays are loaded after the base DTB, following the list from the
/boot/overlay.txt
file. Theload_overlays_from_file
function is doing this. -
Kernel Image: This is the operating system kernel that will be loaded and executed. The variable
kernel_addr_r
seems to be the one for the kernel address. -
Ramdisk (optional): A Ramdisk or initrd (initial ramdisk) is a scheme employed by various Unix-like operating systems to load a temporary root file system into memory.
ramdisk_addr_r
would be the relevant variable in your environment. -
Boot Command or Boot Script: This is the last part of the boot process where the boot command is executed or the boot script is run, which eventually boots into the operating system. This could be handled by
bootcmd
,bootcmd_dhcp
,bootcmd_fel
or other similar environment variables. In your case, it seems theboot.scr
U-Boot script is being used.
while (get next bootdev)
while (get next bootmeth)
while (get next bootflow)
try to boot it
- bootdevs -> boot_targets (mmc0 mmc1 usb pxe)
- bootmeths -> bootmeths (extlinux efi)
- bootflow -> distro_bootcmd. It specifies a kernel, a ramdisk (initrd) and a directory from which to load devicetree files
Modifying variables of U-Boot
printenv
setenv scan_dev_for_boot "echo Sscanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do echo "SDSD"; run scan_dev_for_extlinux; echo "GHGHG"; run scan_dev_for_scripts; done;run scan_dev_for_efi;"
boot
Load overlays with U-Boot
This document explains how to modify U-Boot in order to load custom overlays on startup. It is by adding some info to the boot.scr of U-Boot. This works in the bast ammount of OS, but not in the official ubuntu becuase the overlay is run by Ubuntu. In that case read 20230806 - How to add your overlay to any Linux and 20230805 - Grub for adding devicetree overlays
Code from th U-Boot of Lichee human readable
# Define the function for scanning the device for boot
scan_dev_for_boot =
# Echo the details of the device being scanned
echo "Scanning ${devtype} ${devnum}:${distro_bootpart}...";
# Loop through the prefixes for the boot
for prefix in ${boot_prefixes}; do
echo "Looking into prefix ${prefix}";
# Run the function for scanning the device for extlinux
run scan_dev_for_extlinux;
echo "Looking into dev scripts";
# Run the function for scanning the device for scripts
run scan_dev_for_scripts;
done;
echo "Done with prefixes, now booting efi"
# Run the function for scanning the device for EFI (Extensible Firmware Interface)
run scan_dev_for_efi;
# Define function for scanning the boot partition of the device
scan_dev_for_boot_part =
# List the bootable partition of the device
part list ${devtype} ${devnum} -bootable devplist;
# If 'devplist' environment variable doesn't exist, then set 'devplist' to 1
env exists devplist || setenv devplist 1;
# Loop through the boot partitions in 'devplist'
for distro_bootpart in ${devplist}; do
# If the filesystem type of the boot partition is valid,
# then run the function for scanning the device for boot
if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then
run scan_dev_for_boot;
fi;
done;
# Set 'devplist' environment variable
setenv devplist
# Define function for scanning the device for EFI (Extensible Firmware Interface)
scan_dev_for_efi =
setenv efi_fdtfile ${fdtfile};
# Loop through the prefixes in efi_dtb_prefixes
for prefix in ${efi_dtb_prefixes}; do
# If the specific device tree file exists in the devices boot partition,
# then load the EFI Device Tree Blob (DTB)
if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then
echo \"Loading dtb ${prefix}${efi_fdtfile}\";
run load_efi_dtb;
fi;
# End the loop
done;
echo \"Running boot_efi_bootmgr\";
# Run the function for booting the EFI Boot Manager
run boot_efi_bootmgr;
echo \"Testing if EFI file exists\";
# If the EFI removable media binary exists in the devices boot partition,
# then echo a message indicating it was found, run the function for booting
# the EFI binary, and echo a message indicating the EFI load failed, before continuing
if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootriscv64.efi; then
echo \"Found EFI removable media binary efi/boot/bootriscv64.efi\";
run boot_efi_binary;
echo \"EFI LOAD FAILED: continuing...\";
fi;
# Reset the efi_fdtfile environment variable
setenv efi_fdtfile
# Define function for scanning the device for extlinux (a bootloader)
scan_dev_for_extlinux =
# If the specific extlinux configuration file exists in the device's boot partition,
# then echo a message indicating it was found, run the function for booting
# extlinux, and echo a message indicating the script failed, before continuing
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
# Define function for scanning the device for scripts
scan_dev_for_scripts =
# For each script in the boot scripts list
for script in ${boot_scripts}; do
# If the specific script file exists in the device's boot partition
if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then
# Echo a message indicating the U-Boot script was found
echo "Found U-Boot script ${prefix}${script}";
# Run the function for booting a script
run boot_a_script;
# Echo a message indicating the script failed before continuing
echo "SCRIPT FAILED: continuing...";
fi;
done
# Define function for scanning the serial flash for scripts
scan_sf_for_scripts =
# Read from the serial flash memory at the specified offset and size, storing the result at the script address
${devtype} read ${scriptaddr} ${script_offset_f} ${script_size_f};
# Source the script stored at the script address
source ${scriptaddr};
# If the script fails to run or complete, print "SCRIPT FAILED: continuing..."
echo "SCRIPT FAILED: continuing...";
The output is:
witch to partitions #0, OK
mmc0 is current device
"Scanning ${devtype} ${devnum}:${distro_bootpart}..."
"Looking into prefix ${prefix}"
"Looking into dev scripts"
"Done with prefixes, now booting efi"
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Scanning disk mmc@4020000.blk...
Scanning disk mmc@4021000.blk...
Disk mmc@4021000.blk not ready
Found 7 disks
** Unable to read file ubootefi.var **
Failed to load EFI variables
BootOrder not defined
EFI boot manager: Cannot load any image
Found EFI removable media binary efi/boot/bootriscv64.efi
151552 bytes read in 28 ms (5.2 MiB/s)
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Booting /efi\boot\bootriscv64.efi
V2
> boot
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:f...
Loading dtb
Failed to load '/allwinner/sun20i-d1-lichee-rv.dtb'
Loading dtb
Failed to load '/dtb/allwinner/sun20i-d1-lichee-rv.dtb'
Loading dtb
Failed to load '/dtb/current/allwinner/sun20i-d1-lichee-rv.dtb'
Running boot_efi_bootmgr
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Scanning disk mmc@4020000.blk...
Scanning disk mmc@4021000.blk...
Disk mmc@4021000.blk not ready
Found 7 disks
** Unable to read file ubootefi.var **
Failed to load EFI variables
BootOrder not defined
EFI boot manager: Cannot load any image
Testing if EFI file exists
Found EFI removable media binary efi/boot/bootriscv64.efi
151552 bytes read in 28 ms (5.2 MiB/s)
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Booting /efi\boot\bootriscv64.efi
From ths output I discovered important things! The overlays are loaded on the EFI. And the EFI us loading grub.… so the device tree is being loaded by the grub!
Extlinux
Extlinux is a bootloader that is part of the SYSLINUX Project. SYSLINUX is a suite of lightweight IBM PC MBR bootloaders for starting up computers with the Linux kernel.
In the context of the U-Boot script provided, scan_dev_for_extlinux
is a function that checks for the existence of a SYSLINUX configuration file on the boot partition. If it finds the configuration file, it attempts to boot using extlinux. This provides flexibility for different boot scenarios, depending on the available filesystem and setup.
EFI
EFI, which stands for Extensible Firmware Interface, is a specification that defines a software interface between an operating system and platform firmware.
In the U-Boot script provided, scan_dev_for_efi
is a function that sets up and attempts to boot an EFI application if one is found on the boot partition. This shows that the system has the ability to boot from an EFI application, providing flexibility in how the system is started.
Boot script
In the project of Armbian, they give some U-Boot script examples