Linux Kernel Boot Failed to execute /init error -2
Linux Kernel Boot: Failed to Execute /init (Error -2) - Comprehensive Troubleshooting Guide
Encountering the cryptic “Failed to execute /init (error -2)” message during your Linux kernel boot sequence, followed by a “Kernel panic - not syncing: No working init found”, can be a perplexing and frustrating experience, especially when meticulously building a minimal Linux distribution or working through detailed tutorials like “Build a minimal Linux with only Busybox in 1 Hour” from “Write your own Operating System.” At revWhiteShadow, we understand the intricacies of operating system development and the critical role of the initial process, /init
, in bringing your system to life. This guide delves deep into the root causes of this common boot failure and provides a comprehensive, actionable strategy to resolve it, ensuring your custom Linux environment boots successfully.
Understanding the Boot Process and the Crucial Role of /init
Before we dissect the error, it’s essential to grasp the fundamental steps the Linux kernel undertakes upon startup. When the kernel image is loaded and begins execution, its primary directive is to locate and execute the init process. This process, traditionally found at /sbin/init
or /etc/init
, is the first user-space process launched by the kernel. It assumes the crucial responsibility of bringing the system to a usable state by initializing all necessary services, mounting file systems, and ultimately presenting a login prompt or graphical environment.
The kernel searches for the init program in a specific order, as indicated by your error message: first /init
, then /sbin/init
, /etc/init
, /bin/init
, and finally /bin/sh
as a last resort. When it fails to find a valid, executable init program in these locations, or if the found program cannot be executed, the kernel cannot proceed with the user-space initialization. This leads directly to the “No working init found” panic, signaling a critical failure in the boot chain.
The “error -2” specifically indicates ENOENT, which translates to “No such file or directory.” This is a potent clue, suggesting that the kernel, despite being instructed to look for /init
, cannot find this file at the expected location within the root filesystem.
Common Causes of “Failed to Execute /init (Error -2)”
The failure to execute /init
stems from a few primary categories of misconfiguration or oversight during the custom distribution build process. Each of these needs to be meticulously examined to pinpoint the exact cause.
1. Incorrect Root Filesystem Assembly
This is arguably the most frequent culprit. The kernel, when it starts searching for /init
, operates within the context of the root filesystem that has been made available to it. If the root filesystem is not properly constructed, mounted, or made accessible to the kernel at the correct time, the /init
binary will simply not be present within the kernel’s view of the filesystem hierarchy.
1.1 Missing or Corrupted /init
Binary
The most direct reason for “No such file or directory” is precisely that: the /init
file is not present in the root filesystem’s /
directory. This can happen due to:
- Incomplete Busybox Compilation: If Busybox was not compiled with the necessary applets enabled, particularly the
sh
(shell) and potentiallymount
,sysfs
,proc
, anddevtmpfs
utilities that your/init
script relies on, the resulting Busybox binary might not be sufficient. When Busybox is statically linked, it becomes a single executable that handles multiple commands based on symbolic links or internal dispatching. If thesh
functionality within Busybox isn’t correctly configured or included, the/init
script itself cannot be executed. - Incorrect File Copying: During the process of creating your root filesystem, you might have overlooked copying the
init
binary (which is often a symlink to the Busybox binary in minimal systems) into the root directory of your target filesystem. - Filesystem Corruption: While less common, the root filesystem image itself could be corrupted, leading to missing files or an inability to access them.
1.2 Incorrect Root Filesystem Mounting
Even if /init
exists, the kernel needs to know where to find the root filesystem. This is typically handled by the bootloader and kernel command-line arguments.
- Missing
root=
Kernel Parameter: The kernel needs to be told which device contains the root filesystem. If theroot=
parameter is omitted or incorrect, the kernel will not be able to mount the root filesystem, and thus will not find/init
. - Incorrect Device Specification: If your
root=
parameter points to a device that doesn’t exist, is not accessible, or is not the correct one containing your root filesystem (e.g.,/dev/sda1
when your rootfs is on/dev/vda1
in a virtual machine), the kernel won’t be able to mount it. - Uninitialized or Incorrectly Formatted Root Device: The storage device intended to host your root filesystem must be properly formatted with a filesystem (like ext2, ext4, or even a simple tar archive mounted via an initramfs) that the kernel can understand.
2. Issues with the /init
Script Itself
The provided /init
script contains a sequence of commands to set up the environment before handing off control. Errors within this script can prevent it from executing successfully.
Syntax Errors in the Shell Script: Even a minor syntax error in your
#!/bin/sh
script can cause the shell to fail when trying to interpret it. This could be an unclosed quote, a missing semicolon, an incorrect variable assignment, or any other deviation from standard POSIX shell syntax.Missing Dependencies for Commands: Your
/init
script relies on several commands:mount
,sysctl
, and/bin/sh
.mount
: Essential for mounting/sys
,/proc
, and/devtmpfs
. Ifmount
is not available (i.e., not part of Busybox or not correctly linked), these crucial virtual filesystems won’t be mounted, potentially leading to issues later, though not directly the “error -2” on/init
itself.sysfs
: The kernel needs to access/sys
for system information.proc
: Theproc
filesystem is vital for process management and kernel information.devtmpfs
/udev
: Used for dynamically creating device nodes in/dev
. If these are not available or the mount fails, your system might not be able to access essential hardware devices.sysctl
: Used to tune kernel parameters, like controlling kernel message verbosity. Ifsysctl
is missing, this specific line will fail, but it’s unlikely to be the cause of the initial/init
execution failure./bin/sh
: The script is explicitly#!/bin/sh
. If the/bin/sh
binary (often a symlink to the Busybox shell) is not present or executable, the script cannot run.
Permissions Issues: While less common for the initial
/init
on a freshly built filesystem, if the/init
file itself does not have execute permissions set for the user the kernel is running as (typically root during boot), it will fail to execute.
3. Kernel Configuration Issues
Although less directly related to “error -2,” certain kernel configurations can indirectly lead to this problem.
- Missing Filesystem Support: If the kernel is not compiled with support for the filesystem type used for your root filesystem (e.g., ext4 support is missing), it won’t be able to mount the root device, even if the
root=
parameter is correct. - Incorrect Initramfs/Initrd Usage: If you are using an initramfs (Initial RAM File System), problems with its creation or content can prevent the kernel from correctly loading the real root filesystem. The initramfs typically contains scripts and utilities to set up the environment and then mount the actual root partition. If the initramfs itself lacks a working
/init
or the mechanism to mount the rootfs, the process stalls.
Troubleshooting Steps: A Methodical Approach
To effectively diagnose and resolve the “Failed to execute /init (error -2)” issue, we will adopt a systematic approach, examining each potential point of failure.
Step 1: Verify the Root Filesystem Contents
This is the most crucial step. You need to ensure that your root filesystem is correctly assembled and contains all necessary components.
1.1 Mount and Inspect Your Root Filesystem
Locate Your Root Filesystem Image: This could be a
.tar.gz
archive, a raw disk image file (like.img
), or a partition on a storage device.Mount the Filesystem:
- For
.tar.gz
files: Extract it into a directory:tar -xzf your_rootfs.tar.gz -C /path/to/your/mountpoint
- For
.img
files (assuming it’s a partitionable image like MBR): Uselosetup
to find the partition offsets and then mount the relevant partition. A simpler approach for many modern images is:mount -o loop,ro your_rootfs.img /path/to/your/mountpoint
(adjustro
torw
if you need to make changes). - For a physical partition:
mount /dev/your_root_partition /path/to/your/mountpoint
- For
Navigate to the Mountpoint:
cd /path/to/your/mountpoint
Check for
/init
: Executels -l /init
. You should see an entry indicating it’s a file or a symbolic link.- If
/init
is missing: This is your primary problem. You need to go back to your Busybox build process and ensure thatCONFIG_INIT
or relevant shell applets are enabled, and then ensure theinit
binary (or its symlink) is correctly placed in the root of your filesystem. In a minimal Busybox setup,/init
is often a symbolic link to/bin/busybox
, and/bin/sh
is also a symlink to/bin/busybox
. Verify these symlinks are correct:ls -l bin/busybox
,ls -l bin/sh
. - If
/init
is present: Check its permissions withls -l /init
. It should have execute permissions for the owner (root). For example,-rwxr-xr-x
. If not, you may need to adjust permissions usingchmod
on the source filesystem before creating the image or archive.
- If
1.2 Verify Critical Binaries and Scripts
While inside your mounted root filesystem:
- Check
/bin/sh
:ls -l bin/sh
. This should also point to your Busybox binary. - Check
init
script: If/init
is a script (as yours seems to be), ensure it’s present at the root:ls -l /init
. - Verify script contents: Examine the script file (
cat /init
) for any obvious syntax errors. Make sure themount
command is present (it’s usually part of Busybox). - Check Busybox:
ls -l bin/busybox
. Ensure this binary exists and has execute permissions.
Step 2: Examine Kernel Boot Parameters
The way you instruct the kernel to boot is crucial. This is typically done via your bootloader (like GRUB, U-Boot, or QEMU’s command line).
2.1 The root=
Parameter
Ensure your kernel command line includes a root=
parameter that correctly identifies your root filesystem device.
- Example for a Virtio block device in QEMU:
root=/dev/vda1
orroot=/dev/vda
if it’s the entire device. - Example for a SATA device:
root=/dev/sda1
- Example for a RAM disk (initramfs): This is more complex and depends on how the initramfs is configured to mount the actual root.
2.2 The init=
Parameter (Optional but Recommended for Debugging)
While your error message mentions trying init=
, explicitly specifying it can help if the kernel’s default search order is problematic or if you’re using a non-standard init location.
- If
/init
is your script:init=/init
- If using a standard
/sbin/init
:init=/sbin/init
- If
/bin/sh
is your fallback:init=/bin/sh
Combining these, a typical kernel command line might look like:
console=ttyS0 root=/dev/vda rw init=/init
Explanation:
console=ttyS0
: Directs kernel messages to a serial console (common in VMs).root=/dev/vda
: Specifies the root filesystem device.rw
: Mounts the root filesystem in read-write mode.init=/init
: Explicitly tells the kernel to execute/init
.
Step 3: Rebuild Busybox and Your Root Filesystem
If verification reveals missing files or incorrect links, you’ll need to rebuild.
Busybox Configuration:
- Navigate to your Busybox source directory.
- Run
make menuconfig
(ormake xconfig
, etc.). - Crucially, ensure:
- Under
Settings
->Build Options
,Build BusyBox as a static binary (no shared libs)
is selected if you are aiming for a truly minimal system without libc dependencies. - Under
Applets Core
->Coreutils
, ensuresh
is enabled. - Under
Applets Core
->Init
, ensureinit
is enabled if you intend to use Busybox’sinit
functionality directly, otherwise ensuresh
is sufficient for your script. - Under
Applets Core
->Mount
, ensuremount
is enabled. - Under
Applets Core
->Sysctl
, ensuresysctl
is enabled. - Under
Applets Core
->devtmpfs
, ensuredevtmpfs
is enabled.
- Under
- Save your configuration and run
make
andmake install DESTDIR=/path/to/your/staging/directory
. This will install Busybox into a directory structure that you can then copy into your root filesystem.
Root Filesystem Creation:
- Create your base directory structure (e.g.,
bin
,sbin
,etc
,dev
,proc
,sys
,usr
,lib
,tmp
,mnt
,root
). - Copy the built Busybox binary (usually found in
staging/bin/busybox
) to/bin/busybox
within your root filesystem. - Create necessary symlinks:
ln -s /bin/busybox /bin/sh
ln -s /bin/busybox /sbin/mount
ln -s /bin/busybox /sbin/sysctl
ln -s /bin/busybox /sbin/init
(If you are using Busybox’s direct init functionality, though your script implies/init
is a separate shell script).- If
/init
is a script, ensure it’s placed at the root of your filesystem (your_rootfs_dir/init
).
- Create the
dev
,proc
, andsys
directories. These will be mounted at runtime. - Archive or create an image of this directory structure.
- Create your base directory structure (e.g.,
Step 4: Analyze the init
Script in Detail
Your provided init
script is:
#!/bin/sh
mount -t sysfs sysfs /sys
mount -t proc proc /proc
mount -t devtmpfs udev /dev
sysctl -w kernel.printk="2 4 1 7"
/bin/sh
Let’s break down each command and potential failure point:
#!/bin/sh
: Assumes/bin/sh
exists and is executable. Verified in Step 1.mount -t sysfs sysfs /sys
:- Requires the
mount
binary. - Requires the
sysfs
kernel module or built-in support. - Requires the
/sys
directory to exist in the root filesystem. - If
/sys
is not present in your rootfs, this mount will fail. Ifmount
binary is missing, it will fail earlier.
- Requires the
mount -t proc proc /proc
:- Requires the
mount
binary. - Requires the
proc
kernel module or built-in support. - Requires the
/proc
directory to exist in the root filesystem.
- Requires the
mount -t devtmpfs udev /dev
:- Requires the
mount
binary. - Requires
devtmpfs
support in the kernel. - Requires the
/dev
directory to exist in the root filesystem.
- Requires the
sysctl -w kernel.printk="2 4 1 7"
:- Requires the
sysctl
binary. - Requires the kernel to be running and able to process
sysctl
commands. - Sets the kernel’s console log level. This is unlikely to cause the initial “error -2” but is good practice.
- Requires the
/bin/sh
: This is the final command, intended to launch an interactive shell. If all previous steps were successful, you should drop into a shell.
Potential issues with your script:
- Missing
mount
orsysctl
: Ensure these are correctly symlinked from your Busybox binary. - Missing
/sys
,/proc
, or/dev
directories: These MUST be created within your root filesystem structure before you package it. - Order of Operations: The
mount
commands are critical. If the kernel panics after trying to execute/init
but before reaching/bin/sh
, it’s often because one of the earlymount
commands failed silently or due to missing kernel support/binaries.
Step 5: Consider Initramfs/Initrd
If you are using an initramfs, the init
script logic is often contained within it, responsible for finding and mounting the real root filesystem.
- Check Initramfs Contents: Mount the initramfs image (often a
cpio
archive) and inspect its/init
script and included binaries. The principles discussed above apply directly to the initramfs’s environment as well. - Kernel Command Line for Initramfs: Ensure your bootloader is correctly passing the initramfs image to the kernel and that the kernel is configured to handle it.
Advanced Debugging Techniques
When the initial checks don’t reveal the problem, more advanced techniques can shed light on the boot process.
1. Serial Console Logging
Always ensure you have a serial console configured (especially in virtualized environments). Kernel messages, including panics and errors, are often directed here, providing invaluable debugging information. Your console=ttyS0
parameter is a good start for this.
2. Verbose Kernel Boot Messages
Modify your kernel command line to include loglevel=7
or debug
. This will print more detailed kernel messages, which might reveal earlier issues with device detection or root filesystem probing.
3. Customizing the init
Script for Debugging
Modify your /init
script to be more verbose and check the exit status of each command:
#!/bin/sh
echo "Starting custom init script..."
echo "Mounting sysfs..."
mount -t sysfs sysfs /sys
if [ $? -ne 0 ]; then
echo "ERROR: Failed to mount sysfs!"
# Optionally, try to drop to a shell here for debugging
exec /bin/sh
fi
echo "Mounting proc..."
mount -t proc proc /proc
if [ $? -ne 0 ]; then
echo "ERROR: Failed to mount proc!"
exec /bin/sh
fi
echo "Mounting devtmpfs..."
mount -t devtmpfs udev /dev
if [ $? -ne 0 ]; then
echo "ERROR: Failed to mount devtmpfs!"
exec /bin/sh
fi
echo "Setting kernel.printk..."
sysctl -w kernel.printk="2 4 1 7"
if [ $? -ne 0 ]; then
echo "WARNING: sysctl command failed."
fi
echo "Executing /bin/sh..."
exec /bin/sh
This enhanced script will tell you exactly which mount
command failed, if any. If the script fails at the exec /bin/sh
line, it means the previous commands likely succeeded, and the issue might be with /bin/sh
itself or the state of the system at that point.
4. Examining the Kernel Configuration (.config
)
If you compiled your own kernel, meticulously review your .config
file to ensure that support for your root filesystem type (e.g., CONFIG_EXT4_FS
) and essential drivers (e.g., Virtio block drivers for QEMU) are enabled, either built-in (=y
) or as modules (=m
). If they are modules, ensure they are available within your initramfs or can be loaded by the kernel.
Conclusion: Towards a Successful Boot
The “Failed to execute /init (error -2)” error is a clear indication that the kernel cannot locate or successfully run the initial user-space program. By systematically verifying the integrity of your root filesystem, the correctness of your kernel boot parameters, and the robustness of your /init
script and its dependencies, you can effectively diagnose and resolve this common hurdle. At revWhiteShadow, we advocate for meticulous attention to detail in every step of the OS building process. Rebuilding Busybox with the correct applets enabled, ensuring proper symlinking, and carefully constructing your root filesystem are paramount. With these comprehensive steps, you will be well-equipped to conquer this boot failure and bring your custom Linux distribution to life. Remember, patience and a methodical approach are your greatest allies in the fascinating world of operating system development.