Skip to content

mvebu: bootscript load address calculation a.o. #8272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

djurny
Copy link
Contributor

@djurny djurny commented Jun 4, 2025

Description

Attempt to work towards one U-Boot bootscript for (at least) mvebu, sunxi and rockchip64.
This adds:

  • (Aligned) load address calculations
    This will remove the need to update any kernel_load_addr_r or ramdisk_addr_r in case kernel image increases.
    Calculation is based on either
    • Flat kernel image image_size + text_offset as specified in the vmlinux(/Image) header info
    • Compressed kernel image filesize (vmlinuz/zImage)
  • Clear warnings to user in case files are not found, not able to load or application failed.
  • Merge of armbianEnv.txt kernel options was attempted for sunxi, mvebu and rockchip64.
  • DT folder determination based on sunxi approach.
  • DT file determination based on sunxi approach.
  • Compat with /boot/dtb/fdtfile.dtb and /boot/dtb/vendor/fdtfile.dtb.
  • Simplified some constructs by assuming U-Boot has successfully sourced us with a set of pre-set variables, like ${prefix} ${devtype} etc.
  • Actively set the ${kernel_comp_*} parameters based on calculations of load addresses.
  • Ability to select different kernel/initrd by setting kver in armbianEnv.txt

Also:

  • Any warning or error includes a 10 second delay to make sure the user is able to see and read them.
  • Any "informative" message added by the bootscript can be silenced by setting verbosity to 0
  • Attempted to make the bootscript 'reentrant' in away: all variables required for proper (re)execution are set, which should allow for the entire bootscript to be re-run on a next boot_target.
  • All variables used in for-loops are actively cleared from the environment to ensure for loops work as expected.
  • Any pre-set variable that might be used in next boot_target will be reset whenever necessary.

Documentation summary for feature / change

  • short description (copy / paste of PR title)
  • summary (description relevant for end users)
    Load address calculation can be disabled by adding load_addr_calc=off to armbianEnv.txt
    Load address calculation OBOE avoidance can be disabled by adding align_overlap_oboe_avoidance=off to armbianEnv.txt
    User can set custom fdtdir and fdtfile in armbianEnv.txt, but make sure to only specify DT filename in fdtfile. fdtdir will be used to both load DT, DT overlays and fixup scripts
  • example of usage (how to see this in function)

How Has This Been Tested?

  • Helios4: OK
    [16:10:38] U-Boot SPL 2019.04-armbian-2019.04-S3c99-Pcd6a-H9530-V0854-Bb703-R448a (May 10 2025 - 09:39:24 +0000)
    [16:10:38] High speed PHY - Version: 2.0
    [16:10:38] Detected Device ID 6828
    [16:10:38] board SerDes lanes topology details:
    [16:10:38]  | Lane #  | Speed |  Type       |
    [16:10:38]  --------------------------------
    [16:10:38]  |   0    |  6   |  SATA0    |
    [16:10:38]  |   1    |  5   |  USB3 HOST0       |
    [16:10:38]  |   2    |  6   |  SATA1    |
    [16:10:38]  |   3    |  6   |  SATA3    |
    [16:10:38]  |   4    |  6   |  SATA2    |
    [16:10:38]  |   5    |  5   |  USB3 HOST1       |
    [16:10:38]  --------------------------------
    [16:10:39] High speed PHY - Ended Successfully
    [16:10:39] mv_ddr: mv_ddr-armada-18.09.2 
    [16:10:39] DDR3 Training Sequence - Switching XBAR Window to FastPath Window
    [16:10:39] DDR Training Sequence - Start scrubbing
    [16:10:40] DDR3 Training Sequence - End scrubbing
    [16:10:40] mv_ddr: completed successfully
    [16:10:40] Trying to boot from MMC1
    
    
    [16:10:40] U-Boot 2019.04-armbian-2019.04-S3c99-Pcd6a-H9530-V0854-Bb703-R448a (May 10 2025 - 09:39:24 +0000)
    
    [16:10:40] SoC:   MV88F6828-A0 at 1600 MHz
    [16:10:40] DRAM:  2 GiB (800 MHz, 32-bit, ECC enabled)
    [16:10:40] MMC:   mv_sdh: 0
    [16:10:41] Loading Environment from EXT4... ** File not found /boot/boot.env **
    
    [16:10:41] ** Unable to read "/boot/boot.env" from mmc0:1 **
    [16:10:41] Model: Helios4
    [16:10:41] Board: Helios4
    [16:10:41] SCSI:  MVEBU SATA INIT
    [16:10:41] Target spinup took 0 ms.
    [16:10:41] Target spinup took 0 ms.
    [16:10:41] AHCI 0001.0000 32 slots 2 ports 6 Gbps 0x3 impl SATA mode
    [16:10:41] flags: 64bit ncq led only pmp fbss pio slum part sxs 
    
    [16:10:41] Net:   
    [16:10:41] Warning: ethernet@70000 (eth1) using random MAC address - 42:21:01:47:98:72
    [16:10:41] eth1: ethernet@70000
    [16:10:41] Hit any key to stop autoboot:  0 
    [16:10:44] switch to partitions #0, OK
    [16:10:44] mmc0 is current device
    [16:10:44] Scanning mmc 0:1...
    [16:10:45] Found U-Boot script /boot/boot.scr
    [16:10:46] 18398 bytes read in 359 ms (49.8 KiB/s)
    [16:10:46] ## Executing script at 03000000
    [16:10:46] Boot script loaded from mmc 0:1.
    [16:10:46] 241 bytes read in 371 ms (0 Bytes/s)
    [16:10:46] Loaded/imported environment /boot/armbianEnv.txt to/from 0x00300000.
    [16:10:46] armada-388-helios4.dtb: No match
    [16:10:48] 28834 bytes read in 704 ms (39.1 KiB/s)
    [16:10:48] Loaded DT /boot/dtb/armada-388-helios4.dtb to 0x02040000.
    [16:10:48] Loading kernel provided DT overlay(s) from /boot/dtb/overlay to 0x00300000 ..
    [16:10:49] ** WARNING: Could NOT find DT overlay notfound!
    [16:10:49] Loading user provided DT overlay(s) from /boot/overlay-user to 0x00300000 ..
    [16:10:50] ** WARNING: Could NOT find user DT overlay notfoud (/boot/overlay-user/notfoud.dtbo)!
    [16:10:53] 8856168 bytes read in 1903 ms (4.4 MiB/s)
    [16:10:53] Loaded compressed kernel image /boot/zImage to 2049000.
    [16:10:53] Using compressed kernel image filesize 0x872268 bytes to calculate initial ramdisk load address.
    [16:10:55] 10998232 bytes read in 2295 ms (4.6 MiB/s)
    [16:10:55] Loaded initial ramdisk /boot/uInitrd to 28bc000.
    [16:10:55] Unknown command 'kaslrseed' - try 'help'
    [16:10:55] Not able to prepare for KASLR.
    [16:10:55] Kernel commandline arguments:
    [16:10:55]   root=UUID=a36c9a2d-e1ed-469d-b1bb-2a1bc453df43
    [16:10:55]   rootfstype=ext4
    [16:10:55]   rootwait
    [16:10:55]   splash=verbose
    [16:10:55]   console=ttyS0,115200
    [16:10:55]   console=tty1
    [16:10:55]   consoleblank=0
    [16:10:55]   loglevel=8
    [16:10:55]   ubootpart=cb16300f-01
    [16:10:55]   usb-storage.quirks=
    [16:10:55]   rw
    [16:10:55]   net.ifnames=0
    [16:10:55]   ipv6.disable=1
    [16:10:55]   cgroup_enable=cpuset
    [16:10:55]   cgroup_memory=1
    [16:10:55]   cgroup_enable=memory
    [16:10:55] ## Loading init Ramdisk from Legacy Image at 028bc000 ...
    [16:10:55]    Image Name:   uInitrd
    [16:10:55]    Created:      2025-05-29   3:04:11 UTC
    [16:10:55]    Image Type:   ARM Linux RAMDisk Image (gzip compressed)
    [16:10:55]    Data Size:    10998168 Bytes = 10.5 MiB
    [16:10:55]    Load Address: 00000000
    [16:10:55]    Entry Point:  00000000
    [16:10:55]    Verifying Checksum ... OK
    [16:10:55] ## Flattened Device Tree blob at 02040000
    [16:10:55]    Booting using the fdt blob at 0x2040000
    [16:10:55]    Loading Ramdisk to 0f582000, end 0ffff198 ... OK
    [16:10:55]    Loading Device Tree to 0f577000, end 0f581fff ... OK
    
    [16:10:55] Starting kernel ...
    
    [16:10:57] [    0.000000] Booting Linux on physical CPU 0x0
    
    Note: Added a non-existent DT and non-existant user DT overlay to test the warnings.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
    New warnings introduced:
    • Environment load failed
    • Environment import failed
    • DT load/application failed
    • DT (user) overlay load/application failed
    • Initial ramdisk load failed
    • Kernel image load failed
    • Boot failed
  • Any dependent changes have been merged and published in downstream modules
    Prequisite U-Boot setexpr command already merged via rockchip64/rk3328: U-Boot v2022.04/07 add setexpr #8260.

@djurny djurny requested a review from igorpecovnik as a code owner June 4, 2025 23:33
Copy link
Contributor

coderabbitai bot commented Jun 4, 2025

"""

Walkthrough

The boot script boot-mvebu.cmd was extensively refactored to enhance handling of environment variables, device tree loading, overlay application, kernel and ramdisk loading, and boot command execution. The update introduces explicit preservation of preset variables, new default environment variables, dynamic loading and merging of environment files, and conditional kernel command line construction. It implements robust logic for device tree file resolution, overlay application, and fixup script processing, along with mechanisms for dynamic load address calculation and kernel image type detection. Error handling and informative messaging were improved throughout the script, with changes to boot command execution and variable restoration on failure.

Possibly related PRs

  • mvebu: bootscript fixes & enhancements #8189: The main PR and this PR both modify the mvebu bootscript, focusing on address alignment logic and enhancing error handling during device tree, overlay, kernel, and ramdisk loading, showing a direct and strong code-level connection.
  • Update boot-mvebu.cmd #8166: This PR builds upon and extends the load address alignment, dynamic device tree resizing, overlay fallback, and kernel/ramdisk loading improvements introduced in PR Update boot-mvebu.cmd #8166, indicating a clear continuation and expansion of the same core boot script functionality.

Suggested labels

ready to merge

Suggested reviewers

  • igorpecovnik
  • clee
  • amazingfate
    """

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df1fd2c and d56d1c3.

📒 Files selected for processing (1)
  • config/bootscripts/boot-mvebu.cmd (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
config/bootscripts/boot-mvebu.cmd (4)
Learnt from: djurny
PR: armbian/build#8272
File: config/bootscripts/boot-mvebu.cmd:182-186
Timestamp: 2025-06-04T23:45:38.825Z
Learning: In config/bootscripts/boot-mvebu.cmd, the `fdtfile` variable is mandatory for booting and is pre-set by U-Boot, but can be overridden via armbianEnv.txt. If `fdtfile` is empty, the subsequent device tree file search logic will eventually fail and trigger the critical error "Cannot find DT!" with proper error handling.
Learnt from: djurny
PR: armbian/build#8272
File: config/bootscripts/boot-mvebu.cmd:61-63
Timestamp: 2025-06-04T23:52:39.476Z
Learning: In U-Boot shell scripting, the `else ;` construct followed by commands on subsequent lines is valid syntax, as demonstrated by empirical testing. Both `else command` and `else ; command` forms are acceptable in U-Boot's shell implementation.
Learnt from: djurny
PR: armbian/build#8272
File: config/bootscripts/boot-mvebu.cmd:61-63
Timestamp: 2025-06-04T23:52:39.476Z
Learning: U-Boot's Hush shell accepts the `else ;` construct followed by commands on subsequent lines as valid syntax, even though the standard documentation examples typically show else clauses without the trailing semicolon. This was confirmed through empirical testing on actual U-Boot.
Learnt from: djurny
PR: armbian/build#8272
File: config/bootscripts/boot-mvebu.cmd:182-186
Timestamp: 2025-06-04T23:45:38.825Z
Learning: In U-Boot bootscripts, the `setexpr` command will not fail if a variable is empty - it simply won't perform any substitution operations and leaves the target variable unchanged.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Shell script analysis
🔇 Additional comments (11)
config/bootscripts/boot-mvebu.cmd (11)

6-38: Excellent variable scoping strategy and documentation.

The comprehensive comments explaining the variable preservation approach and the systematic use of preset_* variables to avoid conflicts with U-Boot's global variables demonstrates thoughtful design. The default environment variables are well-chosen and provide good coverage for common use cases.


39-63: Well-designed load address layout and sophisticated utility functions.

The load address definitions with clear size annotations provide excellent documentation. The func_align_addr_next implements proper boundary alignment with overlap avoidance, and the messaging functions (func_inform, func_warn, func_critical_error) provide good user feedback control with appropriate verbosity handling.


64-89: Robust environment file loading with proper error handling.

The environment loading logic correctly handles both user-specified and default environment files with comprehensive error handling for both file loading and import operations. The informative messages help users understand what's happening during the boot process.


90-126: Flexible and comprehensive kernel command line construction.

The dynamic construction of console arguments supporting both serial and display outputs, along with vendor-specific optimizations and configurable Docker support, provides excellent flexibility for different use cases. The organized approach to vendor-specific tweaks makes the code maintainable and extensible.


127-152: Intelligent capability detection and graceful fallback for load address calculation.

The automatic detection of setexpr capability using a test operation and graceful fallback to fixed addresses when dynamic calculation isn't supported shows excellent defensive programming. The informative messages clearly communicate which addressing mode is active, which aids in troubleshooting.


153-170: Correct architecture-based kernel image type determination.

The logic correctly defaults to flat kernel images (Image) for AArch64 and compressed images (zImage) for AArch32, which aligns with standard practices for these architectures. The support for kernel version overrides via the kver variable adds useful flexibility for testing.


172-221: Sophisticated and comprehensive device tree file resolution.

The multi-stage fallback logic for device tree file discovery is well-designed, trying user-specified paths first, then vendor-specific directories, then generic locations, and finally U-Boot presets. The basename extraction handles path components in fdtfile correctly, and the critical error handling ensures boot fails safely when no DT file can be found, which is appropriate since the device tree is mandatory for booting.


222-368: Comprehensive device tree and overlay processing with excellent error recovery.

The sophisticated overlay processing logic that tries multiple prefixes (overlay_prefix, vendor, vendor-soc) to accommodate different naming conventions across vendors is well-designed. The fallback mechanism that reloads the original DT when overlay application fails provides robust error recovery. The fixup script processing from multiple locations adds valuable flexibility for vendor-specific customizations.


369-387: Necessary platform-specific workarounds with proper DT finalization.

The eMMC and SPI-SATA compatibility fixes address specific hardware issues on mvebu platforms. The targeted device tree modifications are appropriate for these workarounds, and the final fdt resize operation correctly finalizes the device tree after all overlays and modifications have been applied.


388-507: Sophisticated dynamic load address calculation with proper kernel image detection.

The dynamic address calculation that prevents memory overlaps between device tree, kernel, and ramdisk components is excellent engineering. The kernel image type detection using magic bytes (ARMd signature at offset 0x38) is correctly implemented, and the different handling for flat vs compressed images properly accounts for image size vs file size differences. The error handling that restores preset values ensures clean environment state for retry attempts.


508-539: Well-structured boot sequence with comprehensive failure handling.

The boot execution flow is excellently organized with KASLR preparation, detailed bootargs logging for debugging, and correct boot command selection (booti for flat images, bootz for compressed). The environment restoration on boot failure ensures clean state for subsequent boot target attempts, which is crucial for U-Boot's distro boot implementation.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added size/large PR with 250 lines or more 08 Milestone: Third quarter release Needs review Seeking for review Hardware Hardware related like kernel, U-Boot, ... labels Jun 4, 2025
@coderabbitai coderabbitai bot added the Ready to merge Reviewed, tested and ready for merge label Jun 4, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
config/bootscripts/boot-mvebu.cmd (2)

438-448: Document endianness assumption for magic number check.

The code assumes little-endian byte order when reading and comparing the 'ARMd' magic number. While ARM systems are typically little-endian, this assumption should be documented.

Add a comment explaining the endianness assumption:

 # determine the load address for the initial ramdisk
 if test "${load_addr_calc}" = "on" ; then
+	# Note: The following magic number check assumes little-endian byte order
 	# vmlinux image + 0x38 contain magic (le-double) 'ARMd'
 	setexpr l_ptr ${l_kernel_addr_r} + 0x00000038

519-528: Simplify redundant boot command logic.

The compressed kernel type case and the default case both use bootz, making the nested conditions redundant.

 if test "${l_kernel_image_type}" = "flat" ; then
 	booti ${l_kernel_addr_r} ${l_ramdisk_addr_r} ${fdt_addr_r}
 else
-	if test "${l_kernel_image_type}" = "compressed" ; then
-		bootz ${l_kernel_addr_r} ${l_ramdisk_addr_r} ${fdt_addr_r}
-	else
-		# default booting command
-		bootz ${l_kernel_addr_r} ${l_ramdisk_addr_r} ${fdt_addr_r}
-	fi
+	# default booting command for compressed and other types
+	bootz ${l_kernel_addr_r} ${l_ramdisk_addr_r} ${fdt_addr_r}
 fi
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28ae76b and 4d6436a.

📒 Files selected for processing (1)
  • config/bootscripts/boot-mvebu.cmd (1 hunks)
🔇 Additional comments (2)
config/bootscripts/boot-mvebu.cmd (2)

1-543: Well-structured boot script with excellent error handling.

The refactoring introduces valuable features including:

  • Dynamic load address calculation with proper alignment
  • Comprehensive DT overlay support with multiple prefix fallbacks
  • Robust error handling with informative user messages
  • Good variable scoping using local (l_) and preset_ prefixes
  • Flexible configuration through armbianEnv.txt

The implementation is thorough and follows U-Boot scripting best practices.


47-47: ⚠️ Potential issue

Fix syntax error in conditional statement.

The semicolon is incorrectly placed after the conditional. In U-Boot shell scripting, it should come before the command to be executed.

-	test "${align_overlap_oboe_avoidance}" = "on" && setexpr l_addr_next ${l_addr_next} + 1 ;
+	test "${align_overlap_oboe_avoidance}" = "on" && setexpr l_addr_next ${l_addr_next} + 1

Likely an incorrect or invalid review comment.

Follow conventional `if-then-else-fi` constructions by not having `else` followed by semicolon. Hush is accepting, but other commonly used shells do not accept this.
@github-actions github-actions bot removed the Ready to merge Reviewed, tested and ready for merge label Jun 5, 2025
@coderabbitai coderabbitai bot added the Ready to merge Reviewed, tested and ready for merge label Jun 5, 2025
@EvilOlaf
Copy link
Member

EvilOlaf commented Jun 5, 2025

Any warning or error includes a 10 second delay to make sure the user is able to see and read them.

Does mvebu have hdmi or video out support in general? If not I think adding such large delays don't make sense, just annoys users why stuff takes so long. Users connected to debug serial are usually a bit more mindful and the overall output of boot loader stage isn't that big so errors should be spotted easily without extensive search.
If you insist I suggest to drop to two or three seconds.

@djurny
Copy link
Contributor Author

djurny commented Jun 5, 2025

Hi @EvilOlaf,
mvebu (clearfog/helios4) does not have any video output AFAIK.

I'm fine with removing the delay :-) The idea for the delay was to have some way of indicating to end users that their overlays= did not load or something else is wrong with their configuration or armbianEnv.txt.

Please do keep the comments coming!
Groetjes,

Remove the 10 sec delay in case "critical error" raised.
@github-actions github-actions bot removed the Ready to merge Reviewed, tested and ready for merge label Jun 5, 2025
@coderabbitai coderabbitai bot added the Ready to merge Reviewed, tested and ready for merge label Jun 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
08 Milestone: Third quarter release Hardware Hardware related like kernel, U-Boot, ... Needs review Seeking for review Ready to merge Reviewed, tested and ready for merge size/large PR with 250 lines or more
Development

Successfully merging this pull request may close these issues.

2 participants