OE4T / meta-tegra

BSP layer for NVIDIA Jetson platforms, based on L4T
MIT License
389 stars 219 forks source link

c-boot sources for warrior 32.2 #297

Closed lfdmn closed 3 years ago

lfdmn commented 4 years ago

Hi,

Is there a reason why warrior 32.2 branch uses pre-built cboot?

I'd like to enable A/B redundancy for rootfs and would need to patch cboot

ashwoods commented 4 years ago

My guess is that it isn't released yet: https://forums.developer.nvidia.com/t/where-is-jetpack-4-3-xavier-cboot-source/111438/2

madisongh commented 4 years ago

Yeah, source releases for cboot have been spotty at best. The last cboot source drop NVIDIA provided for the TX2 was for R28.3, IIRC. For Xavier, they included the cboot sources as part of the L4T public_sources package for a couple of the R32.x releases, but then removed them again in R32.3.1.

That's why the recipes default to using the prebuilt version. The recipes for building cboot from source are present in the warrior branch, and should build OK. I don't know whether the R28.3 cboot would really work with L4T R32.x , though.

That said, I've implemented A/B rootfs redundancy without having to modify cboot by putting the rootfs partition selection logic into the init script in an initramfs and eliminating U-Boot from the boot sequence. That way, cboot directly loads the A or B kernel+initrd, then the init script looks at which slot was used and mounts the corresponding rootfs, ignoring the root= kernel command line parameter.

lfdmn commented 4 years ago

I just tried and patched the L4T 32.2 cboot sources and it doesn't work out on TX2. I was wondering the mismatch of 194 and 186. I'll try the R28.3 version

The initrd option sounds good though, at least easier to maintain. Do you accomplish this by setting

PREFERRED_PROVIDER_virtual/bootloader = "cboot-prebuilt"

and installing tegra186-redundant-boot_32.2.0.bb to tegra-minimal-initramfs to get nvbootctrl?

How are extra kernel parameters set then? Right now I set them in u-boot recipe and they end up into /boot/extlinux/extlinux.conf

madisongh commented 4 years ago

Right, the 32.2 cboot sources are Xavier-only.

And yes, I set the preferred provider for the bootloader and include nvbootctrl in the initramfs image so the script can use it. My test distro has a jetson-tx2-cboot machine that does this. In particular, look at the bbappend for tegra-minimal-init. (This is for zeus, but should work OK for warrior as well.)

For kernel parameters, I set them at build time in the KERNEL_ARGS variable; you can do that either in your machine config or in the tegra-minimal-initrafms recipe. A limitation of this approach is that you can't change them dynamically at runtime, since cboot just extracts them from the device tree.

Another caveat is that I found that the 32.2.x cboot can't handle arbitrarily large kernel+initrd images; in particular, the initrd image must be very small. Building more kernel modules into the kernel, or having an initrd that is more than a couple of MB led to boot failures where the kernel couldn't find the initrd. 32.3.1 is better in that it does handle larger kernels, but it still doesn't handle larger initrd images properly. So if you look at the test-distro master or zeus-32.3.1 branches, you'll see that I switched to building the initramfs into the kernel instead of having it be an initrd. (I didn't find that switching to that approach worked any better with 32.2.x.)

lfdmn commented 4 years ago

That said, I've implemented A/B rootfs redundancy without having to modify cboot by putting the rootfs partition selection logic into the init script in an initramfs and eliminating U-Boot from the boot sequence. That way, cboot directly loads the A or B kernel+initrd, then the init script looks at which slot was used and mounts the corresponding rootfs, ignoring the root= kernel command line parameter.

I'm now loading the correct roots partition from init script. Do I understand correctly that u-boot and the kernel are in the same image, and that NVidia's implementation of redundant A/B boot loads the correct kernel and u-boot slot?

Also, how do I make use of u-boot-bup-payload recipe to be able to create the payload as part of the image builds? I tried including it in my base image, but get an error

Task do_populate_sdk in .../test-image-minimal.bb rdepends upon non-existent task do_package_write_ipk in .../meta-tegra/recipes-bsp/u-boot/u-boot-bup-payload.bb

madisongh commented 4 years ago

NVIDIA's bootloader handles A/B for the kernel/kernel_b partition. If you're using U-Boot, those partitions contain the U-Boot image, and you have to implement your own A/B handling in U-Boot for the Linux kernel and the rootfs (and since the Linux kernel usually resides in the rootfs, it's handled automatically). If you don't use U-Boot, the Linux kernel is in the kernel/kernel_b partitions and yes, cboot loads the correct one automatically.

madisongh commented 4 years ago

Also, how do I make use of u-boot-bup-payload recipe to be able to create the payload as part of the image builds?

For including the BUP payload in a filesystem image, you have to have a separate recipe to package it. See here for an example.

madisongh commented 3 years ago

NVIDIA seems to be doing better with cboot source releases recently. You won't find them on the L4T page, but both the t18x and t19x sources are available from the Jetson Download Center for R32.4.3 and R32.4.4.

Closing this now, as I think the original question has been answered.