armbian / armbian/build

[Bug]: U-Boot load address calculation bug and DT overlap oobe

Open
#8,178 2 comments 0 reactions 0 assignees View on GitHub
Bug
Dominant language
Shell
Stars
5.4k
Forks
3.1k
Avg merge
1d 9h
Merged PRs (30d)
204

Description

### What happened?

Found two dormant issues after applying same solution for https://github.com/armbian/build/issues/8165 to the sunxi bootscript:
1. An oboe in `bootm_find_images()` of **U-Boot:v2021.04** causes false trip of overlap detection.
Flattened device tree data starts at `fdt_addr` and ends at `fdt_addr+fdt_len-1`. If something else starts at `fdt_addr+fdt_len` it is not an overlap, it is an oobe.

```
/* check if FDT overlaps OS image */
if (images.ft_addr &&
(((ulong)images.ft_addr >= start &&
(ulong)images.ft_addr <= start + size) ||
((ulong)images.ft_addr + images.ft_len >= start &&
(ulong)images.ft_addr + images.ft_len <= start + size))) {
printf("ERROR: FDT image overlaps OS image (OS=0x%lx..0x%lx)\n",
start, start + size);
return 1;
}
```
1. The `align_addr_next` env command variable fails due to `test ${modulo} -gt 0` not expecting (hex) l-value. Use `itest` instead to compare hex values.

### How to reproduce?

Apply the same load address calculation method for `boot-sunxi.cmd` and test it on U-Boot v2021.04.

1. When DT aligns exactly to the next image to load, `bootm_find_images()` incorrectly trips an overlap situation:
```
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot/boot.scr
7246 bytes read in 4 ms (1.7 MiB/s)
## Executing script at 43100000
U-boot loaded from SD
Loading environment from mmc to 0x45000000 ...
511 bytes read in 3 ms (166 KiB/s)
sun8i-h2-plus-orangepi-zero.dtb: No match
Load fdt: /boot/dtb/sun8i-h2-plus-orangepi-zero.dtb
Found mainline kernel configuration
Loading DT from mmc to 0x43000000 ...
35384 bytes read in 10 ms (3.4 MiB/s)
Loading kernel provided DT overlay sun8i-h3-usbhost2.dtbo from mmc to 0x45000000 ...
504 bytes read in 11 ms (43.9 KiB/s)
Loading kernel provided DT overlay sun8i-h3-usbhost3.dtbo from mmc to 0x45000000 ...
504 bytes read in 11 ms (43.9 KiB/s)
Loading kernel provided DT overlay sun8i-h3-i2c0.dtbo from mmc to 0x45000000 ...
374 bytes read in 10 ms (36.1 KiB/s)
Loading user provided DT overlay rtc0-i2c-ds3231-rtc1-soc.dtbo from mmc to 0x45000000 ...
835 bytes read in 4 ms (203.1 KiB/s)
Loading kernel provided DT fixup script (sun8i-h3-fixup.scr) from mmc to 0x45000000
4185 bytes read in 11 ms (371.1 KiB/s)
## Executing script at 45000000
Loading kernel from mmc to 43009000 ...
11013984 bytes read in 838 ms (12.5 MiB/s)
Loading ramdisk from mmc to 43a89f60 ...
11827093 bytes read in 898 ms (12.6 MiB/s)
Booting kernel ...
## Loading init Ramdisk from Legacy Image at 43a89f60 ...
Image Name: uInitrd
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 11827029 Bytes = 11.3 MiB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 43000000
Booting using the fdt blob at 0x43000000
ERROR: FDT image overlaps OS image (OS=0x43009000..0x43a89f60)
SCRIPT FAILED: continuing...
```
DT was loaded to `43000000` and size was `0x9000` which makes DT end at `0x43008fff`. Kernel was loaded to `43009000` which is **not** overlapping.

1. The command variable `align_next_addr` fails sometimes.
The `test` used does not handle hex values without prefix properly. `test` uses a `simple_strtol()` on both l- and r-value which borks for hexadecimal values without the `0x` prefix.
```
setenv align_addr_next '
setexpr modulo ${addr_next} % ${align_to} ;
if test ${modulo} -gt 0 ; then
setexpr addr_next ${addr_next} / ${align_to} ;
setexpr addr_next ${addr_next} + 1 ;
setexpr addr_next ${addr_next} * ${align_to} ;
fi'
```
(Unfolded the one-liner for easier interpretation.)
```
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot/boot.scr
7281 bytes read in 4 ms (1.7 MiB/s)
## Executing script at 43100000
U-boot loaded from SD
Loading environment from mmc to 0x45000000 ...
511 bytes read in 3 ms (166 KiB/s)
sun8i-h2-plus-orangepi-zero.dtb: No match
Load fdt: /boot/dtb/sun8i-h2-plus-orangepi-zero.dtb
Found mainline kernel configuration
Loading kernel from mmc to 0x42000000 ...
11013984 bytes read in 837 ms (12.5 MiB/s)
Loading DT from mmc to 42a80f60 ...
35384 bytes read in 10 ms (3.4 MiB/s)
```
Kernel was loaded to `0x42000000` and after alignment `addr_next` became `42a80f60` which was not aligned to `align_to` at all.

### Branch

main (main development branch)

### On which host OS are you running the build script and observing this problem?

Ubuntu 24.04 Noble

### Are you building on Windows WSL2?

- [ ] Yes, my Ubuntu/Debian/OtherOS is running on WSL2

### Relevant log URL

_No response_

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.