// Booting a bare minimum linux using QEMU
$ sudo apt-get install qemu-system-x86
$ sudo apt-get install build-essential
$ sudo apt-get install lzop flex bison libncurses-dev
$ mkdir ~/workspace_kernel_mini && cd ~/workspace_kernel_mini ( && or ;; for running both the commands)
The official Linux Kernel Archives lists the current stable release as 6.15.5, published on July 6, 2025. You can download the tarball from: linux-6.15.5.tar.gz (stable release) $ wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.15.5.tar.gz
Downloading latest Busybox -- the latest official BusyBox release is version 1.37.0, which was released on September 27, 2024
$ wget https://busybox.net/downloads/busybox-1.37.0.tar.bz2
$ cd ~/workspace_kernel_mini
$ tar -xvf /linux-6.15.5.tar.gz
$ cd linux-6.15.5/
$ make allnoconfig
"This will create .config file setting values to 'n' as much as possible. For more refer Documentation/admin-guide/README.rst at kernel.org"
$ make menuconfig
This will open configuration options. Now set following options … Option 1: Host name General setup > Default hostname “bare-mini-linux-kernel"
Option 3: Enable support for RAM disk General Setup > Initial RAM filesystem and RAM disk (initramfs/initrd) support
Option 4: Enable printk support General Setup > Configure standard kernel features (expert users) > Enable support for printk
Option 5: Ensure Gzip Kernel compression General Setup >kernel compression mode (Gzip)
Option 6: ELF binary and script Executable file formats > Kernel support for ELF binaries Executable file formats > Kernel support for scripts starting with #!
Option 7: Enable devtmpfs Device Driver > Generic Driver Options > Maintain a devtmpfs filesystem to mount at /dev Device Driver > Generic Driver Options > Automount devtmpfs at /dev, after the kernel mounted the rootfs
Option 8: Enable TTY Device Driver > Character devices > Enable TTY
Option 9: Enable Serial Drivers Device Driver > Character devices > Serial Drivers > 8250/16550 and compatible serial support Device Driver > Character devices > Serial Drivers > Console on 8250/16550 and compatible serial port
Option 10: Pseudo filesystems File systems > Pseudo filesystems > /proc file system support File systems > Pseudo filesystems > /sysfs file system support
Now, save and close configuration window. This will save .config file.
$ gedit bare-mini-linux-kernel.config
$ make -j4 ( -j4 runs 4 threads in 4 cores of the processor to speed up the process of compilation)
To check cores in your PC $ nproc
$ /home/lokesh/workspace_kernel_mini/linux-6.15.5/arch/x86/boot (will take a while)
Depending on the internet speed and PC configuration, this will take some time. Once build is complete, you can verify presence of kernel.
example : ~/workspace_kernel_mini/linux-6.15.5/arch/x86/boot $ ls -sh bzImage 1.6M bzImage
Now we have Linux kernel available. Next is creating initram disk.
Creating Initramfs
$ cd ~/workspace_kernel_mini
$ tar -xvf busybox-1.37.0.tar.bz2
$ cd busybox-1.37.0/
$ make menuconfig
This will start configuration menu for BusyBox. We need only one setting.
Settings > Build static binary (no shared libs)

Now, exit and save. It is time to build busybox.
$ make -j4
$ make install This will install binaries in “./_install” directory
$ cd ~/workspace_kernel_mini
$ mkdir mini_linux && cd mini_linux
$ mkdir -p etc proc sys dev
$ cp -a ~/workspace_kernel_mini/busybox-1.37.0/_install/* .
Create init script in “mini_linux” directory. This is the content of init script. /** #!/bin/sh mount -t proc none /proc mount -t sysfs none /sys cat <<! boot took $(cut -d' ' -f1 /proc/uptime) seconds exec /bin/sh **/
$ cat init
$ chmod +x init
$ find . -print0 | cpio --null -ov --format=newc | gzip -9 > initramfs.cpio.gz
Note : Description of “find . -print0 | cpio --null -ov --format=newc | gzip -9 > initramfs.cpio.gz”
find . -print 0 : this will create a list of all files. print the full file name on the standard output, followed by a null character cpio --null -ov --format=newc: copy file to archive, use newc (SVR4) archive format , -o = create , -v verbosly list all files processed gzip -9 > initramfs.cpio.gz : creating gzip file, with compression speed 9. initramfs.cpio.gz should be created.
Booting Mini Linux in QEMU
Now we have, Linux kernel ~/workspace_kernel_mini/linux-6.15.5/arch/x86/boot/bzImage
And ramfs .. ~/workspace_kernel_mini/mini_linux/initramfs.cpio.gz
$ qemu-system-x86_64
-kernel ~/workspace_kernel_mini/linux-6.15.5/arch/x86/boot/bzImage
-initrd ~/workspace_kernel_mini/mini_linux/initramfs.cpio.gz
-append "init=/bin/sh console=ttyS0" -nographic
Command
Description
qemu-system-x86_64
Command to start QEMU for system.
-kernel ~/workspace_kernel_mini/Linux -6.15.5/arch/x8664/boot/bzImage \
“-kernel” option to provide path of bzImage.
-initrd ~/workspace_kernel_mini/mini_linux/initramfs.cpio.gz \
“-initrd” option to provide initramfs file.
-append "init=/bin/sh console=ttyS0"
“-append” provide command line argument for Linux kernel.
-nographic
We don’t want to use graphics.
Now we can try multiple commands to review our bare minimum Linux. $ uname -a
$ top
top command display all the process running in Linux. You can see we have /bin/sh which is bourne shell . Process ID (PID) of bourne shell is 1. and second process is kthreadd, process Id is 2. kthreadd is the kernel thread started after init and all kernel threads are descendant of kthreadd.
$ cat /proc/cmdline
This command shows command line argument give to the kernel.
$ cat /proc/cpuinfo
you can review parameter related to CPU. Model name is QEMU Virtual CPU
$ dmesg
This command shows all kernel messages which were routed to ttyS0. You should able to find following information in kernel messages.









