What is BusyBox Init and inittab Explained-Embedded Linux Course In Hyderabad

Free embedded Linux course: how PID

BusyBox Init and inittab Explained

 1 boots your root filesystem

PID 1 process
inittab actions
rcS boot script

If you have ever booted a minimal embedded Linux system straight into a shell prompt, you already know how fragile that setup is: nothing restarts a crashed shell, nothing mounts /proc for you, and nothing supervises background services. This lecture is part of our free embedded Linux course and explains how BusyBox init solves this by acting as PID 1 — the very first userspace process the kernel starts, and the ancestor of every other process on the system.

busybox init
inittab
free embedded linux course
free linux kernel development course
rootfs boot sequence

What You Will Learn

  • Why every Linux system — desktop, server, or embedded — needs an init process at PID 1
  • The exact syntax of /etc/inittab and what each field means
  • The difference between sysinit, askfirst, and respawn actions
  • How to write a boot script (rcS) that prepares the system for use
  • How to test your init setup on QEMU and on real embedded hardware

Prerequisites

You should already have a working root filesystem staging directory (with BusyBox built and installed) and basic familiarity with shell scripting. If you haven’t built a rootfs yet, work through the earlier lectures in this free embedded systems course before continuing.

Why init Exists

The Linux kernel’s job ends the moment it hands control to the first userspace program. That program — traditionally called init — is responsible for everything that happens next: mounting filesystems, starting a console, launching background daemons, and restarting anything that crashes. Without init, a kernel panic isn’t the only way your board becomes unresponsive; a single shell exiting would leave you with nothing at all.

BusyBox ships its own compact init implementation, which is more than adequate for embedded targets that don’t need the complexity of systemd. It reads a single configuration file, /etc/inittab, and acts on each line in order.

Boot Sequence: Kernel to Shell
Bootloader
|
v
Kernel decompresses, mounts rootfs, execs /sbin/init (PID 1)
|
v
BusyBox init reads /etc/inittab
|
+–> sysinit action -> runs /etc/init.d/rcS (mounts, setup)
|
+–> respawn actions -> starts syslogd, getty, etc. (restarted if they exit)
|
+–> askfirst action -> waits for Enter, then starts a login shell

inittab Syntax

Each line in /etc/inittab follows a fixed four-field format:

<id>:<runlevels>:<action>:<process>

BusyBox ignores the id and runlevels fields (they exist for compatibility with SysV init), so in practice most embedded inittabs leave them blank. The action field is what matters:

Action Meaning
sysinit Run once, first, before anything else — typically your boot script
respawn Start the process, and restart it automatically if it ever exits
askfirst Print a prompt and wait for Enter before starting the process (usually a shell)
wait Run once and block further inittab processing until it finishes
once Run once, don’t wait, don’t restart
ctrlaltdel Process to run when Ctrl+Alt+Del is received
shutdown Process to run at system shutdown

A Minimal, Working inittab

Here is an original example — not copied from any book — suitable for a small embedded target:

::sysinit:/etc/init.d/rcS
::askfirst:-/bin/ash
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r

The leading - before /bin/ash marks it as a login shell, which sources /etc/profile and $HOME/.profile before dropping you at a prompt. A login shell also enables job control, which is why Ctrl+C works to interrupt a foreground program — without it, a runaway ping would be unkillable from that console.

Writing the rcS Boot Script

/etc/init.d/rcS is where one-time boot setup belongs. A practical, modern version mounts the pseudo filesystems the rest of the system depends on:

#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
echo "ep_demo: rootfs initialised" > /dev/kmsg

Make it executable before building the rootfs image:

$ cd ~/staging
$ chmod +x etc/init.d/rcS

Testing on QEMU and Real Hardware

On QEMU, point the kernel command line at your init binary:

qemu-system-arm -M virt -kernel zImage -initrd rootfs.cpio.gz \
  -append "console=ttyAMA0 rdinit=/sbin/init" -nographic

On a real board using U-Boot, the equivalent is setting bootargs before booting:

=> setenv bootargs console=ttyS0,115200 rdinit=/sbin/init
=> boot

Common Mistakes and Troubleshooting

  • Kernel panics with “no init found”: check that rdinit= (initramfs) or init= (disk-based rootfs) points to a path that actually exists and is executable inside the image.
  • rcS never runs: almost always a missing execute bit. Re-check with chmod +x before repackaging.
  • Shell exits and nothing happens: you used once or wait instead of askfirst/respawn for your console entry.
  • Ctrl+C doesn’t stop foreground programs: the shell wasn’t launched as a login shell (missing leading -).

Best Practices

  • Keep rcS idempotent and fast — every extra second here delays boot on every single power-up.
  • Always add a respawn entry for your console shell/getty so a crashed shell doesn’t brick the board until reboot.
  • Log rcS failures to /dev/kmsg or a serial console rather than silently swallowing errors.

Summary and Key Takeaways

  • BusyBox init is PID 1 and reads /etc/inittab to decide what to start and how to supervise it.
  • sysinit runs your boot script once; respawn keeps critical processes alive; askfirst gates shell startup on user input.
  • rcS is the right place for one-time mounts and setup, not long-running services.

Conclusion

Getting inittab and rcS right is the foundation every other rootfs feature builds on — user accounts, logging daemons, and device management all assume a working init has already brought the system to a stable state. In the next lecture we’ll configure user accounts on top of this foundation.

FAQ

What happens if /etc/inittab is missing?

BusyBox init falls back to a built-in default inittab, which is more permissive than a hand-written minimal one — fine for development, not recommended for production images.

Can I run systemd instead of BusyBox init?

Yes, on higher-end boards with enough storage and RAM, but for constrained embedded targets BusyBox init’s simplicity is usually preferable.

Why does my getty keep restarting in a loop?

That’s expected with a respawn action — it should restart every time the login shell exits, which is the intended supervised behavior.

Where do rcS errors get logged before syslogd starts?

Nowhere by default — redirect critical rcS output to /dev/kmsg or the console so you can see failures during early boot.

Is inittab syntax the same across all init systems?

No — this is BusyBox’s specific format. SysV init and systemd use different configuration mechanisms entirely.

Continue Your Free Embedded Linux Course

Next up: configuring user accounts in your root filesystem.

 

1 Comment

Leave a Reply

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