Colibri iMX7d NFS rootfs with kernel/DT from UBI

I’m trying to do a proof of concept with the colibri iMX7d to replace a fleet of ~500 raspberry Pi’s used in an automation environment.

We must run a rootfs from NFS but do not want to TFTP load the kernel/DT at each boot.

I’ve been trying to setup U-boot to do this but I keep hanging at Starting Kernel…

Essentially, I am using the ubiboot action and replacing the bootargs passed to the kernel so it loads the rootfs from NFS in lieu of the flash. I suspect that being new to u boot I am missing something simple, but need some other eyes to tell me what it is.

I’ve attached the full u-boot env, here, but in a nutshell here are the interesting ones:

nfs_bakery=root=/dev/nfs rootfstype=nfs ip=dhcp

setup=setenv setupargs console=tty1 console=${console},${baudrate}n8 ${memargs} consoleblank=0 ${mtdparts}

bakeryboot=run setup; setenv bootargs ${defargs} ${nfs_bakery} ${setupargs}; echo Booting Production; ubi part ubi && run m4boot && ubi read ${kernel_addr_r} kernel && ubi read ${fdt_addr_r} dtb && run fdt_fixup && bootz ${kernel_addr_r} - ${fdt_addr_t}

When I execute run bakeryboot the response is this:

 Colibri iMX7 # run bakeryboot
 Booting Production
 UBI: detaching mtd1 from ubi0
 UBI: mtd1 is detached from ubi0
 UBI: default fastmap pool size: 200
 UBI: default fastmap WL pool size: 25
 UBI: attaching mtd1 to ubi0
 UBI: attached by fastmap
 UBI: fastmap pool size: 200
 UBI: fastmap WL pool size: 100
 UBI: attached mtd1 (name "mtd=3", size 507 MiB) to ubi0
 UBI: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
 UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
 UBI: VID header offset: 2048 (aligned 2048), data offset: 4096
 UBI: good PEBs: 4056, bad PEBs: 4, corrupted PEBs: 0
 UBI: user volume: 4, internal volumes: 1, max. volumes count: 128
 UBI: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 0
 UBI: available PEBs: 0, total reserved PEBs: 4056, PEBs reserved for bad PEB handling: 76
 Read 0 bytes from volume kernel to 81000000
 No size specified -> Using max size (5113928)
 Read 0 bytes from volume dtb to 82000000
 No size specified -> Using max size (40257)
 Kernel image @ 0x81000000 [ 0x000000 - 0x4e0848 ]
 Starting kernel ...

And hangs. I know the nfs server is up and running, and it looks like the kernel and device tree are loaded. I don’t understand why the reads say 0 bytes, but they say the same thing during a successful boot from flash

It doesn’t seem like this should be this hard which is why I suspect I’m missing something simple.

Anyone see anything obvious or have debugging hints to find out what is going on?

Hey blondguy,

hmmm I think the NFS portion of your configuration may be correct but I don’t think you are actually getting to that part in the boot sequence. I believe the kernel would come up and greet you with several lines of early initializations before attempting to mount the NFS.

Have you loaded the flash? and how did you do it? Though, if it was empty/corrupt I assume you would see “Bad Linux ARM zImage magic!” …which you aren’t.

Have you verified that it boots normally via ubifs before adding in the NFS portion? Verify the size it is reading out matches the size of the images? Perhaps perform checksums on both the kernel image and DTB in flash from uboot commandline? (tedious, I know)

The “Read 0 bytes” is misleading, Not sure why uboot devs leave it in there, but it shows up when a size isn’t specified to the “ubi read” command. When no size is specified, the command takes the number of “used bytes” in the volume as the size to read, which is why it prints “Using max size” immediately afterwards.

I don’t think I’m getting to loading the rootfs either, but I don’t know why - the section to load the kernel/DT is verbatum from a known good ubifs command.

The module boots perfectly from ubifs via this command:

ubiboot=run setup; setenv bootargs ${defargs} ${ubiargs} ${setupargs} ${vidargs}; echo Booting from NAND…; ubi part ubi && run m4boot && ubi read ${kernel_addr_r} kernel && ubi read ${fdt_addr_r} dtb && run fdt_fixup && bootz ${kernel_addr_r} - ${fdt_addr_r}

Essentiall, my command above to do the boot replaces ${ubiargs} with ${nfs_bakery} (vidargs is empty so left out)

So changing the bootargs to the kernel by removing:
ubi.mtd=ubi root=ubi0:rootfs rootfstype=ubifs ubi.fm_autoconvert=1

and replacing that with:
root=/dev/nfs rootfstype=nfs ip=dhcp nfsroot=,udp,vers=3

is the only intended change.

How do I verify that the kernel image loaded correctly? I tried stepping through the known good ubiboot command step by step, but as soon as I manually enter: ubi read ${kernel_addr_r} kernel, u-boot takes off and tries to boot. I would not expect that until I entered bootz.

What else can I check/verify?

in your u_boot_env.txt in bakeryboot you have bootz ${kernel_addr_r}-${fdt_addr_t} it should be bootz ${kernel_addr_r} - ${fdt_addr_t}

And the winner is dominik. Thank you for noticing that.

I was using an undefined variable for the device tree blob in my call to bootz:
fdt_addr_t but should be fdt_addr_r

Problem solved works great. Thanks for the help.