How to Passing Boot Info to Kernel in Linux-Embedded Linux Course In Hyderabad

PREV_LEC | NEXT_LEC

Passing Boot Info to Kernel
What actually crosses the bootloader-to-kernel boundary — a free embedded systems course lecture

In this free embedded systems course, we’ve already covered how a bootloader loads a Linux kernel image into memory. But loading the kernel isn’t enough by itself — the bootloader also has to tell the kernel a handful of critical facts about the hardware it just booted on. This lecture walks through exactly what gets passed, how that mechanism evolved, and why almost every modern board now relies on the device tree to do it.

kernel command line
boot parameters
ATAGS
free embedded systems course
free linux device drivers course

What You Will Learn

  • Exactly what information a bootloader must hand to Linux
  • How the kernel command line controls early boot behavior
  • Why ARM boards moved away from “A tags” toward the device tree
  • A hands-on example reading passed boot parameters from kernel space
  • Common mistakes when setting up bootargs

Prerequisites

This lecture builds directly on the TPL and UEFI boot lecture earlier in this free embedded systems course. You should understand that a bootloader places a kernel image, and usually a device tree blob, into specific memory addresses before jumping to the kernel’s entry point.

The Handoff Contract

When a bootloader jumps into the Linux kernel, it isn’t just handing over the CPU — it’s honoring an informal contract about what information will be available at that jump. Depending on architecture, this typically includes:

Information Purpose Typical Carrier
SoC/board identifier Lets the kernel select the right early machine setup code Register value (legacy) or device tree compatible string
RAM size and location Tells the kernel how much usable memory exists and where Device tree memory node
Kernel command line Configures early kernel behavior, e.g. which device is root Device tree chosen node or ATAGS
Device tree blob location Describes the full hardware layout to the kernel CPU register pointing at DTB in RAM
Initial RAM disk location and size Lets the kernel mount a temporary root filesystem Device tree chosen node, initrd-start / initrd-end

The Kernel Command Line

The kernel command line is a plain text string, and it’s one of the most direct levers you have over early Linux behavior in any free embedded systems course exercise. It controls things like which device holds the root filesystem, which console to use for early messages, and dozens of subsystem-specific debug flags.

console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait rw earlyprintk

Each of these matters independently: console= decides where you’ll actually see kernel messages, root= decides which block device the kernel treats as its root filesystem, and rootwait tells the kernel to wait for that device to become available instead of panicking immediately — a very common requirement on boards where storage devices enumerate slightly after the kernel starts.

From Board Info Structures to A Tags to Device Trees

How this information physically gets passed has changed considerably over the years, and understanding that history is genuinely useful for anyone taking a free linux device drivers course, because you’ll still encounter both styles in the field.

  • PowerPC era: the bootloader passed a pointer to a fixed board information structure — simple, but rigid and platform-specific.
  • Early ARM era (“A tags”): the bootloader passed a pointer to a linked list of tagged entries describing memory, command line, and a few other basics. Flexible compared to a fixed structure, but still very limited in what it could express.
  • Modern era (device tree): the bootloader passes a pointer to a full device tree blob, which can describe an arbitrary hierarchy of hardware components, not just a handful of fixed fields.

The shift away from A tags began once it became clear that “platform data” — hardware facts hard-coded directly into kernel source for each board — didn’t scale. Every new board needed its own kernel build. The device tree solved this by moving hardware description out of kernel code and into a small, board-specific binary blob that the same generic kernel binary can parse at boot time.

Three Generations of the Same Handoff
PowerPC (legacy) ARM (early) Modern (all architectures)
+—————-+ +——————+ +—————————+
| board info | | list of A tags | | device tree blob (DTB) |
| structure | | (memory, cmdline,| | full hardware hierarchy: |
| (fixed fields, | -> | ramdisk, …) | -> | cpus, memory, buses, |
| hard to grow) | | (still limited) | | peripherals, chosen node |
+—————-+ +——————+ +—————————+

Hands-On: Reading Passed Boot Parameters From Kernel Space

Let’s write a small, original demo — not reused from any reference book — that reads back the command line the bootloader handed us and prints it during kernel init. This is a useful first exercise in any free linux device drivers course, because it shows the handoff data actually landing inside kernel code you control.

// ep_bootinfo.c — minimal module printing the passed kernel command line
#include <linux/module.h>
#include <linux/init.h>
#include <linux/printk.h>

static int __init ep_bootinfo_init(void)
{
    pr_info("ep_bootinfo: kernel was started with cmdline: \"%s\"\n",
            saved_command_line);
    return 0;
}

static void __exit ep_bootinfo_exit(void)
{
    pr_info("ep_bootinfo: unloaded\n");
}

module_init(ep_bootinfo_init);
module_exit(ep_bootinfo_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("EP course demo: print bootloader-passed command line");
# Build and load against your running kernel headers
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
sudo insmod ep_bootinfo.ko
dmesg | tail -n 3
sudo rmmod ep_bootinfo

Expected output:

[  12.184201] ep_bootinfo: kernel was started with cmdline: "console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait rw earlyprintk"

saved_command_line is exactly the string the bootloader placed in the device tree’s chosen node (or ATAGS on very old ARM kernels) — this one line of code makes the abstract handoff concept from earlier in this lecture completely concrete.

Real-World Use Cases

  • Selecting an alternate root filesystem for a recovery or factory-reset boot
  • Passing a serial number or MAC address into the kernel via bootargs
  • Switching console targets between a UART and a display for headless debugging
  • Reserving memory regions for firmware or secure-world use before Linux starts

Common Mistakes and Troubleshooting

Kernel panics with “unable to mount root fs”

Usually a wrong or missing root= value, or a missing rootwait on a device that isn’t ready the instant the kernel probes it.

No console output at all

The console= parameter doesn’t match the UART actually wired to your debug port, or the baud rate is wrong.

Command line silently ignored

On device-tree-based boots, bootargs must be set inside the chosen node — a command line set only in an old-style environment variable with no device tree wiring will not reach the kernel.

Best Practices

  • Keep production bootargs minimal and documented — every extra flag is a debugging surface
  • Avoid embedding secrets or sensitive identifiers directly in the command line, since it’s often readable at runtime
  • Prefer rootwait over fixed boot delays for storage that enumerates asynchronously

Summary and Key Takeaways

The bootloader-to-kernel handoff carries a small but critical set of facts: SoC identity, memory layout, the command line, and pointers to the device tree and initramfs. That mechanism has evolved from rigid, architecture-specific structures toward the flexible, general-purpose device tree — a theme that runs throughout this free embedded systems course and sets up everything we cover next.

Conclusion

Now that you’ve seen what crosses the boundary and how, our next lecture goes deeper into the device tree itself — its syntax, its node hierarchy, and how to read one confidently, which is foundational for the rest of this free linux device drivers course.

FAQ

What is the kernel command line?

A plain text string passed from the bootloader that configures early kernel behavior, such as which device holds the root filesystem and where console output should go.

What were “A tags”?

A linked list of tagged data structures used on early ARM Linux systems to pass memory size, command line, and a few other basics from the bootloader to the kernel, before the device tree became standard.

Why did platform data stop scaling?

Because it required each board to have its own dedicated kernel build with hardware facts hard-coded into source, which didn’t scale as the number of supported boards grew.

Where does the device tree pointer come from?

The bootloader places the device tree blob in memory and passes its address to the kernel, typically in a fixed CPU register at the kernel entry point.

Can I read the boot command line from a running kernel module?

Yes — the kernel exposes it through the saved_command_line symbol, as shown in this lecture’s hands-on example.

Is the initial RAM disk always required?

No — it’s optional. Many embedded systems boot directly to a real root filesystem without an initramfs stage.

Continue This Free Embedded Systems Course

Next up: a full walkthrough of device tree syntax and structure.

PREV_LEC | NEXT_LEC

Leave a Reply

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