fdt_high default value causes unbootable kernel due to misalignment

Hello,
When I was using U-Boot with a dart_6ul board I occasionally had fitimages that U-Boot would attempt to boot just fine, but the kernel wouldn't actually boot. Debugging found that this was correlated with the header length of the fitImage. Then I noticed this remark in doc/usage/environment.rst about fdt_high:
If this is set to the special value 0xffffffff (32-bit machines) or 0xffffffffffffffff (64-bit machines) then the fdt will not be copied at all on boot. For this to work it must reside in writable memory, have sufficient padding on the end of it for u-boot to add the information it needs into it, and the memory must be accessible by the kernel. This usage is strongly discouraged however as it also stops U-Boot from ensuring the device tree starting address is properly aligned and a misaligned tree will cause OS failures.
And indeed, fdt_high is set to 0xffffffff in the include/configs/dart_6ul.h that I was using. Since mkimage only guarantees 32-bit alignment of the device tree blob within the fitimage, and not the 64-bit alignment that Linux requires, this is basically a 50/50 coin flip. Something simple like adding a few characters to the description string in the fitimage header can make or break the alignment.
Personally I fixed this by removing the fdt_high altogether, which makes U-Boot copy the device tree to an appropriate location. I assume this only works in my situation because I only have half a GiB of RAM and therefore do not have any high memory. I can imagine my fix would be problematic for board variants with more RAM, the setting doesn't exist without a reason of course.
It looks like this issue is not limited to my board; the same usage of fdt_high can be found in many other board configs. I'm not going to suggest what the best fix is because I lack detailed knowledge, but I will pitch that perhaps omitting fdt_high by default is at least preferable to a value that is "strongly discouraged" and causes Linux boot failures somewhat arbitrarily.
Kind regards,
Tim

Hi Tim,
On Tue, 18 Jul 2023 at 09:59, Tim van der Staaij | Zign Tim.vanderstaaij@zigngroup.com wrote:
Hello,
When I was using U-Boot with a dart_6ul board I occasionally had fitimages that U-Boot would attempt to boot just fine, but the kernel wouldn't actually boot. Debugging found that this was correlated with the header length of the fitImage. Then I noticed this remark in doc/usage/environment.rst about fdt_high:
If this is set to the special value 0xffffffff (32-bit machines) or 0xffffffffffffffff (64-bit machines) then the fdt will not be copied at all on boot. For this to work it must reside in writable memory, have sufficient padding on the end of it for u-boot to add the information it needs into it, and the memory must be accessible by the kernel. This usage is strongly discouraged however as it also stops U-Boot from ensuring the device tree starting address is properly aligned and a misaligned tree will cause OS failures.
And indeed, fdt_high is set to 0xffffffff in the include/configs/dart_6ul.h that I was using. Since mkimage only guarantees 32-bit alignment of the device tree blob within the fitimage, and not the 64-bit alignment that Linux requires, this is basically a 50/50 coin flip. Something simple like adding a few characters to the description string in the fitimage header can make or break the alignment.
Personally I fixed this by removing the fdt_high altogether, which makes U-Boot copy the device tree to an appropriate location. I assume this only works in my situation because I only have half a GiB of RAM and therefore do not have any high memory. I can imagine my fix would be problematic for board variants with more RAM, the setting doesn't exist without a reason of course.
It looks like this issue is not limited to my board; the same usage of fdt_high can be found in many other board configs. I'm not going to suggest what the best fix is because I lack detailed knowledge, but I will pitch that perhaps omitting fdt_high by default is at least preferable to a value that is "strongly discouraged" and causes Linux boot failures somewhat arbitrarily.
I wonder if we should adjust mkimage to use -B 8 as the default?
Regards, Simon

I wonder if we should adjust mkimage to use -B 8 as the default?
Ah, overlooked this option. I ran a test with -B 8 and by itself it doesn't fix the issue. However, as the manpage notes, -B is only effective when -E is also used. And indeed, using -E -B 8 does avoid misalignment when the device tree is used in-place.
Sounds like a good fix to me, but I don't know if there would be broader consequences of defaulting to -E? It sounds like this changes the structure of the fitimage rather dramatically.
Kind regards, Tim

Hi Tim,
On Thu, 20 Jul 2023 at 08:40, Tim van der Staaij | Zign Tim.vanderstaaij@zigngroup.com wrote:
I wonder if we should adjust mkimage to use -B 8 as the default?
Ah, overlooked this option. I ran a test with -B 8 and by itself it doesn't fix the issue. However, as the manpage notes, -B is only effective when -E is also used. And indeed, using -E -B 8 does avoid misalignment when the device tree is used in-place.
Sounds like a good fix to me, but I don't know if there would be broader consequences of defaulting to -E? It sounds like this changes the structure of the fitimage rather dramatically.
Yes it does, see [1]. But there are some advantages to having all the nodes/properties at the start of the file.
Regards, Simon
[1] https://u-boot.readthedocs.io/en/latest/usage/fit/source_file_format.html#ex...
participants (2)
-
Simon Glass
-
Tim van der Staaij | Zign