Booting Linux With bootm in Linux-Best Embedded Linux Training In Hyderabad

Booting Linux With bootm
The final handoff from U-Boot to a running Linux kernel
Free Embedded Linux Course
Chapter 3: Bootloaders
Lecture 18
free embedded systems course
free linux development course
free linux device drivers course
free linux kernel development course
u-boot bootm command

Everything in this chapter of our free embedded Linux course has been building toward one
moment: the command that actually hands control from U-Boot to the Linux kernel. That command is bootm
(and its architecture-specific sibling booti for ARM64), and this lecture covers exactly what happens
when you run it, and how to pass a device tree and ramdisk alongside the kernel.

What You Will Learn

  • The bootm/booti command syntax and its three addresses
  • What happens internally during the handoff to Linux
  • Booting with a kernel, device tree, and ramdisk together
  • Booting a FIT image with a single command
  • Diagnosing a hang between bootm and the first kernel message

Prerequisites

You should have a kernel image already loaded into RAM (from SD card, TFTP, or NAND, as covered in the previous
lectures of this free linux kernel development course), along with a matching device tree if your
board requires one.

bootm and booti Syntax

The classic 32-bit command is bootm; ARM64 boards typically use booti, which expects
an uncompressed Image rather than a compressed zImage. Both share the same three-address argument pattern:

bootm [kernel_addr] [ramdisk_addr] [fdt_addr]
booti [kernel_addr] [ramdisk_addr] [fdt_addr]

The kernel address is mandatory; the other two are optional depending on your board’s configuration. If there’s a
device tree but no ramdisk, the ramdisk position is replaced with a dash rather than omitted, since argument
position determines meaning:

U-Boot# booti ${ep_kernel_addr} - ${ep_fdt_addr}

What Happens During the Handoff

Running bootm/booti is not a simple jump instruction — U-Boot performs several checks and setup steps first:

  1. Validates the image header(s) at each given address, the same check iminfo performs manually.
  2. Decompresses the kernel into its runtime location, if compression was used.
  3. If a device tree was given, fixes it up with runtime information U-Boot has gathered — things like detected memory size and the kernel command line from bootargs — before Linux ever sees it.
  4. Sets up CPU state as the Linux boot protocol for the architecture requires (e.g. disabling the MMU and caches on ARM before entry, in the state Linux expects to find them).
  5. Jumps to the kernel’s entry point. From this instant, U-Boot has handed off control entirely — it does not run again until the next power cycle.
bootm/booti Handoff Sequence
U-Boot# booti $ep_kernel_addr – $ep_fdt_addr
|
v
Validate image header(s) at given addresses
|
v
Decompress kernel if needed
|
v
Fix up device tree
(memory size, bootargs -> /chosen)
|
v
Set CPU state per Linux boot protocol
|
v
Jump to kernel entry point
|
v
Linux takes over — U-Boot does not run again
until next power cycle

Booting With Kernel, Ramdisk, and Device Tree

A complete boot with all three components loaded at separate addresses looks like this:

U-Boot# fatload mmc 0:1 ${ep_kernel_addr} Image
U-Boot# fatload mmc 0:1 ${ep_fdt_addr} board.dtb
U-Boot# fatload mmc 0:1 ${ep_ramdisk_addr} initramfs.cpio.gz
U-Boot# booti ${ep_kernel_addr} ${ep_ramdisk_addr} ${ep_fdt_addr}

Note the argument order: kernel first, ramdisk second, device tree third — swapping ramdisk and fdt addresses is
a common copy-paste mistake that produces a kernel panic very early in boot, since Linux tries to parse the ramdisk
data as a device tree or vice versa.

Booting a FIT Image in One Command

If you built a FIT image (covered in the mkimage lecture) that bundles the kernel, device tree, and ramdisk
together with a named configuration, booting collapses to a single address and an optional configuration selector:

U-Boot# tftp ${ep_fit_addr} ep-demo.itb
U-Boot# bootm ${ep_fit_addr}#conf-1

The #conf-1 suffix selects a specific named configuration from the FIT image, useful when a single
image bundles configurations for more than one board variant or boot mode.

Real-World Use Cases

  • Development boards commonly boot kernel + separate dtb + rootfs over NFS via bootargs, skipping a ramdisk entirely.
  • Production devices increasingly boot a single signed FIT image, since it keeps the kernel and its matching device tree cryptographically bound together.
  • Recovery/rescue boot flows often use a ramdisk-based initramfs so the device can run diagnostics without depending on the (potentially corrupted) main root filesystem.

Common Mistakes and Troubleshooting

Symptom Likely Cause Fix
Board hangs immediately after bootm/booti, no kernel output Wrong or missing device tree, or bootargs console setting wrong Confirm bootargs matches your actual serial console device and baud rate
“Bad Data CRC” during bootm Image corrupted since last iminfo check Reload and re-verify with iminfo before retrying bootm
Kernel panics parsing device tree Ramdisk and fdt addresses swapped in the command Double check argument order: kernel, ramdisk, fdt
booti refuses the image Compressed zImage passed to booti instead of bootm Use bootm for compressed 32-bit images, booti expects uncompressed ARM64 Image

Best Practices

  • Run iminfo on every loaded component immediately before calling bootm/booti, not just the kernel.
  • Keep bootargs, device tree, and kernel version changes tested together — a mismatch between any two is a common source of early boot failures.
  • Prefer a single signed FIT image on production hardware over separately-loaded components.
  • Log the exact bootm/booti command used for a working configuration in your board’s bring-up notes — it’s easy to forget argument order months later.

Security Considerations

bootm/booti is the exact point where U-Boot’s verified boot chain either enforces or fails to enforce trust —
when booting a signed FIT image with verification enabled, U-Boot refuses to execute a kernel or device tree that
doesn’t match a trusted signature. Skipping FIT verification on production hardware means anyone who can write to
boot storage can substitute an arbitrary kernel.

Summary and Key Takeaways

  • bootm and booti hand off control from U-Boot to Linux, with kernel, ramdisk, and fdt addresses as arguments.
  • U-Boot fixes up the device tree with runtime information before Linux ever reads it.
  • Argument order matters — kernel, ramdisk, fdt — and getting it wrong produces confusing kernel-side failures.
  • A FIT image collapses multi-component boots into a single, optionally signed and verified command.

Conclusion

This closes out the boot-image chapter of our free embedded systems course: from understanding
what a bootloader does, through device trees, choosing and building U-Boot, environment variables, image wrapping,
loading, NAND programming, and finally the handoff itself. From here, control belongs to the Linux kernel — which
is exactly where the next chapter of this free linux development course picks up.

FAQ

What’s the difference between bootm and booti?

bootm is the general-purpose command supporting compressed and legacy image formats across architectures, while
booti is used specifically for ARM64 and expects an uncompressed Image rather than a compressed zImage.

Why does the device tree need “fixing up” before Linux boots?

U-Boot inserts runtime information it has already detected, such as memory size and the kernel command line,
into the device tree’s /chosen node so Linux doesn’t need to rediscover that information itself.

Can I boot without a ramdisk?

Yes, many systems boot straight into a root filesystem on eMMC, NAND, or NFS with no initramfs at all, in which
case the ramdisk argument position is simply replaced with a dash.

What happens if I use the wrong configuration name with a FIT image?

bootm reports that the requested configuration doesn’t exist in the FIT image, and no boot is attempted — check
the image’s configuration names with iminfo or the its source file.

Does U-Boot run again after Linux boots?

No, once bootm/booti jumps to the kernel entry point, U-Boot’s code does not execute again until the next power
cycle or reset.

Continue the Free Embedded Linux Development Course

 

Leave a Reply

Your email address will not be published. Required fields are marked *