johny
Posts: 58
Joined: Tue Apr 24, 2012 10:00 am
Location: Australia

How to U-Boot with FDT on a Pi 2?

Thu Apr 23, 2015 8:33 am

Hi all,

I'm currently trying to add support for Pi 2 hardware to some of our existing projects here at $work, which all rely on U-Boot as the primary loader (post-GPU, that is). As such I'm been banging my head on my desk* all day trying to get this to work on a Pi 2. My issue, as far as I can tell, is that the plain bcm2709-rpi-2-b.dtb on disk is not usable, but relies on the GPU to have patched its contents in RAM before handing the result to the kernel.

If, in U-Boot I simply fatload the DTB and hand it through to the kernel via bootz ${kernel_addr_r} - ${fdt_addr_r} then I get a kernel which spins up a single core and then hangs about 5sec into the boot. The same kernel booted straight by the GPU without U-Boot fires up all four cores and gets all the way to complaining about mounting root (which is what I expect with the current setup).

On the other hand, if I simply ask the GPU to put the processed DTB at a particular location via device_tree_addr= in config.txt, and then point the bootz command at that address, I'm told there is no FDT there, and the boot fails. I believe I've made sure that said location does not get clobbered by other fatloads, btw. Attempting to just bootz without an FDT address provided results in "Starting kernel ..." followed by nothing. I tried building a Pi 2 kernel without FDT support, but that failed to load altogether, with or without U-Boot. Various combinations of bootm vs bootz have also been tried, without any additional luck.

So, my question is, does anyone actually have a U-Boot working with a Pi 2, and if so, how the blazes did you do it? Which version of U-Boot, what bootcmd, which FDT & address(es)?

Many thanks in advance,
/Johny

*) Yes, literally.

johny
Posts: 58
Joined: Tue Apr 24, 2012 10:00 am
Location: Australia

Re: How to U-Boot with FDT on a Pi 2?

Fri Apr 24, 2015 7:34 am

Okay, I've finally gotten this to work the way I need it to. I can now boot a Raspberry Pi 2 B through U-Boot, where U-Boot decides which kernel and root partition to use. U-Boot uses the GPU-provided DTB and only updates the /chosen/bootargs entry.

To get this to work I had to patch U-Boot's default addresses to stop it from blowing away the GPU-provided DTB when U-Boot loads the boot.scr script, and also tell U-Boot about the default DTB address (0x100). I then hand the built u-boot.bin to the mkknlimg tool (using --dtok to force it) to get it to appear like an FDT-enabled kernel, and save that as kernel7.img. This step is needed to avoid needing to have a device_tree= entry in config.txt. If you have neither you only get ATAGS from the GPU and life is not good.

With all that done it's possible to:

Code: Select all

  fdt addr ${fdt_addr_r} && fdt get value bootargs /chosen bootargs || setenv fdt_addr_r;
  ...
  setenv bootargs "${bootargs} ro root=${my_root_part} rootfstype=ext2 rootwait";
  fatload mmc ${devnum} ${kernel_addr_r} "${my_kernel}" && bootm ${kernel_addr_r} - ${fdt_addr_r};
and hey presto you're finally booting your Pi 2, and getting the benefit of all the DTB fiddling performed by the GPU.

U-Boot patch, applies cleanly on top of 1733259d25015c28c47990ec11af99b3f62f811c (you can leave out the BOOTDELAY and BOOTZ parts if you want):

Code: Select all

diff --git c/include/configs/rpi-common.h i/include/configs/rpi-common.h
index 3121ac9..01a2053 100644
--- c/include/configs/rpi-common.h
+++ i/include/configs/rpi-common.h
@@ -163,10 +163,10 @@
  *   for the FDT/DTB to be up to 1M, which is hopefully plenty.
  */
 #define ENV_MEM_LAYOUT_SETTINGS \
-       "scriptaddr=0x00000000\0" \
+       "fdt_addr_r=0x00000100\0" \
        "pxefile_addr_r=0x00100000\0" \
        "kernel_addr_r=0x01000000\0" \
-       "fdt_addr_r=0x02000000\0" \
+       "scriptaddr=0x02000000\0" \
        "ramdisk_addr_r=0x02100000\0" \
 
 #define BOOT_TARGET_DEVICES(func) \
@@ -181,6 +181,8 @@
        ENV_MEM_LAYOUT_SETTINGS \
        BOOTENV
 
-#define CONFIG_BOOTDELAY 2
+#undef CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY -2
+#define CONFIG_CMD_BOOTZ
Incidentally, having a legacy boot.scr file which uses 0x8000 for scratch is not very helpful. Why? Because 0x8000 is where the GPU loaded U-Boot...

User avatar
Hvergelmir
Posts: 2
Joined: Mon Dec 17, 2012 10:19 pm

Re: How to U-Boot with FDT on a Pi 2?

Wed Nov 01, 2017 11:05 pm

Hi johny,

shouldn't it be possible to throw your new default addresses into u-boot.env? Just wondering. Came across your question and answer because I am looking into the same issue now, but with a newer U-Boot version.

Thanks for posting your findings here. Much appreciated!
... just because you aren't paranoid doesn't mean they aren't after you

johny
Posts: 58
Joined: Tue Apr 24, 2012 10:00 am
Location: Australia

Re: How to U-Boot with FDT on a Pi 2?

Thu Nov 02, 2017 12:58 am

Hi Hvergelmir,

Bit of a blast from the past here! :)

Yes, you should certainly be able to put the address into u-boot.env and have that work. The reason I don't like doing so is because the environment is at higher risk of being corrupted/erased. I sleep much better if I know that the compiled-in values can get the job done.

I also ended up writing a blog post for $work on this topic which expands slightly on what I've already posted here, if that's any use.

Return to “Advanced users”