0

I'm working on setting up U-Boot for our systems using raspberry pi 3B plus and cm3. (Though atm I'm working just with cm3. I'm confident the same applies to the 3B plus) I got rid of the default bootcmd run distro_bootcmd and load a first stage boot script first_boot.scr which then loads and sources the respected boot.scr.

%EDIT% In my answer I mentioned already that the failure description is wrong. I just checked the fdt_addr variable at the wrong time, thus leading me on the wrong path. %EDIT% As we already have machines out in the field I'm working on updating them. Here lies the problem. If I setup a fresh device with the new architecture everything works just fine. If I update and older system though, fdt_addr is not setup, thus the boot failes. I can of course manually setup fdt_addt, but I want to understand what could be the reason for fdt_addr not being setup. As far as I could find, the first stage bootloader is responsible. So I imagine something is not beeing triggered.

Updating in our case describes simply copying the new images to the device, moving u-boot.bin and first_boot.scr to the boot partition and then changing the config.txt to start U-Boot not the kernel directly. While setting up a fresh machine is pretty much the same just with formatting the device and placing the files in the exact same places.

bootcmd: load mmc 0:1 ${scriptaddr} /first_boot.scr; source ${scriptaddr}

env load  #<- %EDIT%
if test "${boot_count}" > 4; then
        echo "###Loading factory kernel bootscript###"
        setenv boot_kernel 2;
        load mmc 0:2 ${scriptaddr} images/factory/boot.scr;
        source ${scriptaddr}
elif test "${boot_count}" > 2; then
        echo "###Loading factory kernel bootscript###"
        setenv boot_kernel 1;
        load mmc 0:2 ${scriptaddr} images/previous/boot.scr;
        source ${scriptaddr}
else
        echo "###Loading current kernel bootscript###"
        setenv boot_kernel 0;
        load mmc 0:2 ${scriptaddr} images/latest/boot.scr;
        source ${scriptaddr}
fi

if test "${boot_kernel}" = 2; then
        echo "###Loading factory kernel###"
        load mmc 0:2 ${kernel_addr_r} images/factory/Image;
        load mmc 0:2 ${fdt_addr} images/factory/device_tree.dtb;
elif test "${boot_kernel}" = 1; then
        echo "###Loading previous kernel###"
        load mmc 0:2 ${kernel_addr_r} images/previous/Image;
        load mmc 0:2 ${fdt_addr} images/previous/device_tree.dtb;
else
        echo "###Loading current kernel###"
        load mmc 0:2 ${kernel_addr_r} images/latest/Image;
        load mmc 0:2 ${fdt_addr} images/latest/device_tree.dtb;
fi

setenv bootargs console=ttyAMA0,115200 printk.devkmsg=on usbcore.autosuspend=-1 fsck.mode=force fsck.repair=yes
env save
booti ${kernel_addr_r} - ${fdt_addr}
obvg
  • 129
  • 12
  • Typically environment variable fdt_addr_r is used for the device tree not fdt_addr. – Xypron Sep 09 '22 at 12:39
  • I once stumbled upon this comment [link](https://www.elinux.org/RPi_U-Boot#Booting_from_an_SD_card) stating `# IMPORTANT NOTE: On mainline u-boot, the correct variable to use here is ${fdt_addr} and NOT ${fdt_addr_r}` Also if I use `fdt_addr_r` I just get `ERROR: Did not find a cmdline Flattened Device Tree Could not find a valid device tree`. If I could manage to use `fdt_addr_r` though that would solve my problem potentially. Then on the other hand I'd still like to understand how `fdt_addr` gets set normally and why it is not set in my case. – obvg Sep 09 '22 at 13:17

1 Answers1

0

The culprit was a line I sadly left out in my example as I deemed it unimportant... I work with the boot_count variable also in user land, for that reason I save my environment to the drive so I can interact with it via fw_saveenv. Because of that I need to load the environment at the beginning of first_boot.scr. But if you try to load with env load when there is no uboot.env file alot of the environment information is lost. So now I do a check for uboot.env and save if it is not present and load if so.

I described the problem wrong in my question though. I check the presence of fdt_addr before sourching first_boot.scr at times, thus getting lead on the wrong track.

if test -e mmc 0:1 uboot.env; then
        echo "Loading env"
        env load
else
        echo "Saving default environment to file"
        env save
fi

if test "${boot_count}" > 4; then
        echo "###Loading factory kernel bootscript###"
        setenv boot_kernel 2;
        load mmc 0:2 ${scriptaddr} images/factory/boot.scr;
        source ${scriptaddr}
elif test "${boot_count}" > 2; then
        echo "###Loading factory kernel bootscript###"
        setenv boot_kernel 1;
        load mmc 0:2 ${scriptaddr} images/previous/boot.scr;
        source ${scriptaddr}
else
        echo "###Loading current kernel bootscript###"
        setenv boot_kernel 0;
        load mmc 0:2 ${scriptaddr} images/latest/boot.scr;
        source ${scriptaddr}
fi
obvg
  • 129
  • 12