free linux device drivers course
free embedded systems course
kernel panic
root filesystem
Every embedded Linux developer eventually watches a fresh kernel boot cleanly for a few dozen lines and then stop dead with a wall of red text. This lecture, part of our free linux kernel development course, demystifies the kernel panic: what it actually is, why it happens most often on a brand-new board bring-up, and how to read the message to find the real cause instead of guessing.
What You Will Learn
- What a kernel panic actually is, mechanically, inside the kernel
- Why “unable to mount root filesystem” is the single most common panic on new boards
- How to use
rdinit=/bin/shas a diagnostic tool to isolate root-filesystem problems - How the
paniccommand-line parameter changes reboot behavior after a crash - A checklist for triaging any panic message you have not seen before
Prerequisites
- A kernel image and device tree you can boot, from the previous lecture in this series
- Basic comfort reading kernel log timestamps like
[ 1.886379]
What A Kernel Panic Actually Is
A panic is the kernel’s response to an error it has judged unrecoverable — a state where continuing to execute would risk corrupting data or behaving unpredictably, so it deliberately halts instead. Mechanically, this is a direct call into the kernel’s panic() function from wherever the fatal condition was detected. By default, panic() prints a diagnostic message to the console and then stops the system, waiting there indefinitely unless you have configured automatic reboot behavior.
│
▼
panic() is called
│
▼
Message printed to console
│
▼
panic_timeout set?
│ │
yes no
│ │
▼ ▼
reboot after N s halt forever
The Most Common First Panic: No Root Filesystem
On a board you are bringing up for the first time, the panic you will meet almost immediately looks something like this:
[ 1.886379] Kernel panic - not syncing: VFS: Unable to mount
root fs on unknown-block(0,0)
[ 1.895105] ---[ end Kernel panic - not syncing: VFS: Unable to
mount root fs on unknown-block(0, 0)
This is a genuinely good sign, even though it looks alarming. It means every earlier stage — bootloader handoff, decompression, CPU and memory initialization, driver probing — has already succeeded. The kernel has reached the very last step of booting, transitioning from kernel space into user space, and simply has nowhere to go: there is no root filesystem it can mount and no /init program it can run. A kernel with no user space to control is, by design, useless, so it panics rather than doing nothing productive forever in a half-initialized state.
Using rdinit As A Diagnostic Shell
The most useful debugging trick at this stage is to skip the real root filesystem question entirely and get a shell running from a minimal ramdisk, so you can start inspecting the system interactively. Assuming you have built (or downloaded) a small initramfs image containing a static shell, you can boot straight into it:
=> fatload mmc 0:1 0x80200000 zImage
=> fatload mmc 0:1 0x80f00000 board.dtb
=> fatload mmc 0:1 0x81000000 initramfs.cpio.gz
=> setenv bootargs console=ttyS2,115200 rdinit=/bin/sh
=> bootz 0x80200000 0x81000000 0x80f00000
The rdinit=/bin/sh override tells the kernel: instead of searching for a real init system, just execute /bin/sh directly from the ramdisk once it is mounted. With a working shell prompt in hand, you can inspect what devices the kernel actually found, confirm whether your storage driver probed correctly, and check partition layouts before worrying about a full root filesystem at all:
...
[ 1.964858] Freeing unused kernel memory: 408K
/ # uname -a
Linux (none) 6.9.0 #1 SMP PREEMPT armv7l GNU/Linux
/ # ls /dev/mmcblk*
/dev/mmcblk0 /dev/mmcblk0p1 /dev/mmcblk0p2
/ #
Seeing your expected block device nodes here immediately tells you the storage driver is fine, and the panic was purely about which device and partition you pointed root= at — not a deeper driver problem.
Two Ways To Supply User Space
Once you understand this failure mode, fixing it is a matter of choosing one of two paths and pointing the kernel at it correctly with the right command-line parameter.
| Approach | Command-Line Parameter | Typical Use Case |
|---|---|---|
| Ramdisk (initramfs) | rdinit=/path/to/program |
Early bring-up, recovery images, minimal diagnostic environments |
| Mounted block device | root=/dev/<device><partition> |
Production systems with a real filesystem on eMMC, SD, or NAND |
For a real block-device root, the parameter typically looks like root=/dev/mmcblk0p2 rootwait — the rootwait flag tells the kernel to wait for the storage device to finish probing (particularly important for SD/MMC, which can enumerate slightly after the rest of boot) before attempting the mount.
Controlling Reboot Behavior With panic=
By default, a panicked kernel halts forever, which is useful while you are actively reading the log but inconvenient for an unattended field device that should try to recover on its own. The panic command-line parameter sets a timeout, in seconds, after which the kernel automatically reboots instead of hanging:
=> setenv bootargs console=ttyS2,115200 root=/dev/mmcblk0p2 rootwait panic=5
With this set, a panic prints its message, waits five seconds so the message is still visible on a serial log, and then reboots automatically — a common pattern for production devices that need to self-recover from transient failures without a human present.
Common Mistakes And Troubleshooting
- Wrong partition number in root=: double-check with a diagnostic
rdinit=/bin/shshell which partition actually holds your root filesystem before assuming the kernel or driver is at fault. - Missing rootwait on slow storage: the mount can fail intermittently if the device has not finished probing yet; add
rootwaitfor MMC/SD roots. - Assuming every panic is a root filesystem problem: read the actual panic string — a different subsystem name in the message means a different root cause entirely, not a storage misconfiguration.
- No panic_timeout in production builds: a device that hangs forever after a rare panic requires a physical power cycle; set
panic=for anything deployed unattended.
Best Practices
- Keep a small, known-good initramfs with a static shell around specifically for diagnostic boots like this.
- Always read the exact subsystem name in a panic message before searching for a fix — “VFS” points at filesystem mounting, not at a driver or memory subsystem.
- Set a reasonable
panic=timeout on any board that will run unattended, so transient failures self-recover.
Summary And Key Takeaways
- A panic is the kernel’s deliberate, safe stop when it hits an error it cannot recover from.
- “Unable to mount root fs” on a new board almost always means the kernel booted correctly but has nowhere to hand off to user space.
rdinit=/bin/shis your fastest diagnostic tool for isolating root-filesystem and storage-driver issues.panic=<seconds>controls whether a panicked system halts forever or auto-reboots.
Conclusion
A kernel panic during bring-up looks like failure, but it is usually the kernel telling you, precisely, exactly how far it got. Learning to read that message — rather than reflashing blindly and hoping — is one of the highest-leverage debugging skills in this free linux device drivers course. In the next lecture, we follow the successful path: what actually happens once the kernel does find a working root filesystem and hands off to early user space.
Frequently Asked Questions
Is a kernel panic the same thing as a crash?
They are related but not identical. A panic is a deliberate, controlled stop triggered by the kernel itself when it detects an unrecoverable condition, as opposed to an uncontrolled crash or hang caused by, for example, corrupted memory with no detection at all.
Why does my board panic even though I set root= correctly?
Confirm the storage driver actually probed the device before the mount attempt — add rootwait, or check with a diagnostic rdinit=/bin/sh shell whether the expected device node even exists.
What is the difference between root= and rdinit=?
root= tells the kernel which block device and partition to mount as the real root filesystem. rdinit= overrides this entirely, telling the kernel to execute a specific program directly from an already-loaded ramdisk instead.
Can I recover from a panic without rebooting the board?
No. Once panic() is called, the kernel deliberately stops normal execution. The only recovery paths are an automatic reboot (if panic= is set) or a manual power cycle.
Does panic=0 mean the kernel will not panic?
No, panic=0 is actually the default behavior — it means halt forever with no automatic reboot. To disable panics entirely is not possible, since they represent conditions the kernel considers unsafe to continue past.
Master Embedded Linux Debugging
This lecture is part of EmbeddedPathashala’s free linux device drivers course, built for students who want real depth, not shortcuts.
