编译x86 Linux内核后QEMU启动触发Kernel Panic:无法找到可用init
Let's break down why you're hitting this kernel panic and walk through the fixes step by step:
The Root Cause
Error code -2 translates to ENOENT (No such file or directory), meaning the kernel can't locate the /init executable in your initramfs. This typically stems from one of three issues: incorrect initramfs packaging, wrong file paths in your QEMU command, or missing critical kernel configuration options.
Step 1: Verify Your Static init Executable
First, confirm your init binary is properly compiled as a static x86_64 executable. Run this check:
file init
You should see output like this:
init: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=..., not stripped
If you don't get this result, recompile with explicit 64-bit flags (install gcc-multilib if needed):
gcc -static -m64 init.c -o init
Step 2: Repackage Your Initramfs Correctly
Your current echo init | cpio... command can be unreliable due to path or permission edge cases. Use this method to guarantee init is placed at the root of the initramfs:
# Create a temporary directory to build the initramfs structure mkdir -p initramfs_root cp init initramfs_root/ # Change to the root directory and package all contents cd initramfs_root find . | cpio -o --format=newc > ../initramfs_new cd .. # Clean up the temporary directory rm -rf initramfs_root
This ensures the init file lives at the root (./init), so when the kernel unpacks the initramfs, it will immediately find /init.
Step 3: Fix Paths and Parameters in Your QEMU Command
Double-check that paths to your bzImage and new initramfs are correct. In your original command, you pointed to ~/data/linux/arch/x86/boot/initramfs—if you built the initramfs in a different directory, this path is invalid.
Use the new initramfs we created and explicitly tell the kernel where to find init with the init=/init append parameter:
qemu-system-x86_64 -kernel ~/data/linux/arch/x86/boot/bzImage \ -append 'console=ttyS0 init=/init' \ -serial stdio \ -initrd ./initramfs_new \ -nographic
Step 4: Validate Kernel Configuration
Ensure your kernel has the necessary options to handle initramfs:
- Run
make menuconfigfrom your kernel source directory - Enable these options (use the
/key to search):CONFIG_BLK_DEV_RAM=y(RAM Disk support)CONFIG_DEVTMPFS=y(Optional but helps with device node setup)CONFIG_INITRAMFS_SOURCE=""(Leave empty since we're providing our own initrd)
- Save the config and recompile the kernel:
make -j8
Bonus: Ignore Unrelated Warnings
The NX protection cannot be enabled message in your log is unrelated to the init panic—it just means your kernel isn't compiled with PAE support, which won't block your init from running.
After following these steps, QEMU should boot successfully and display your "Tiny init - Hello World..." message.
内容的提问来源于stack exchange,提问作者InsaneCoder

