Greetings, and welcome to my blog. Today, I will discuss how to create a simple Linux distribution using BusyBox. This can be done on any system, whether it is Windows, macOS, or Linux. For Windows, you need WSL, a Docker (Ubuntu) container, or a VM with a Linux distribution installed (Ubuntu or its derivatives are recommended). First, install the prerequisites:
Note: If you are using a container, ensure you run it in privileged mode.
sudo apt install bc cpio bison libssl-dev libncurses-dev libelf-dev bzip2 make
sudo apt install automake autoconf git
syslinux dosfstools xz-utils build-essential gcc wget
Once you have these dependencies installed, start by creating a directory named distro
:
sudo mkdir /distro
cd /distro
After creating and changing the directory, obtain the Linux Kernel, either from git or wget:
Note: If you use git, you might clone the beta or release candidate version of the kernel.
sudo git clone --depth 1 https://github.com/torvalds/linux
OR
sudo wget https://cdn.kernel.org/pub/linux/kernel/vx.x/linux-x.x.x.tar.xz
After obtaining the kernel, extract it (if used wget to obtain archive):
sudo tar -xvf linux-x.x.x.tar.xz
Now, cd to the extracted or cloned folder:
cd linux-x.x.x # If used wget
OR
cd linux # If used git
After entering the Linux directory, make the menu configuration:
sudo make menuconfig
It's not necessary to change the configuration in the TUI menu, however, if you want, you may change it. Then save the configuration and start compiling:
sudo make -j <number_of_jobs_to_run_in_parallel>
If you're unsure of how many threads your CPU has, you may instead type:
sudo make -j $(nproc)
This fetches the number of threads in CPU through the nproc
variable set by your host system. Now, you will get a success message saying, bzImage successfully generated or created. After you get this message, copy the bzImage as vmlinuz file to your /distro
folder:
sudo cp arch/x86/boot/bzImage /distro/vmlinuz
Now, exit the Linux directory and clone the BusyBox repository:
cd ..
sudo git clone --depth 1 https://git.busybox.net/busybox
After cloning, cd to the BusyBox directory:
cd busybox
Now make the menu configuration:
sudo make menuconfig
There's a problem with the default configuration, so we need to edit the .config
file:
sudo vim .config
In the .config
file, change the line with CONFIG_TC = y
to CONFIG_TC = n
.
After changing, you may start the compilation:
sudo make -j$(nproc)
After compilation, make a directory initramfs
within the /distro
directory, and make install the components to the initramfs folder:
sudo mkdir /distro/initramfs
sudo make CONFIG_PREFIX=/distro/initramfs install
This will install all the components to the initramfs directory. Then, cd to the initramfs directory and delete the linuxrc
file:
sudo rm linuxrc
After removing linuxrc
, we need to create an init
script that will initialize our system, on what to start after booting up:
sudo vim init
Vim > Bash
#!/bin/sh
/bin/sh
This script starts the shell, which we can use to type in our commands and execute stuff. Then, staying in the initramfs folder, create a cpio image of the initramfs folder:
sudo find . | cpio -o -H newc > ../initramfs.cpio
This creates a cpio initramfs image. Now, cd to the root of the distro directory, and type the following commands:
cd ..
sudo dd if=/dev/zero of=OS bs=1M count=50
The above dd command creates a file named OS
, filled with zeros, written via /dev/zero
, of size 50 * 1 = 50 MB (approx). Now format the created OS file with FAT filesystem using:
sudo mkfs -t fat OS
After formatting, mount the OS file to a temporary directory in /distro
folder:
sudo mkdir tmp
sudo mount OS tmp
This mounts the OS file to the tmp directory. Now we can start copying the vmlinuz (bzImage) and initramfs.cpio files to the OS file:
sudo cp /distro/vmlinuz /distro/tmp/vmlinuz
sudo cp /distro/initramfs.cpio /distro/tmp/initramfs.cpio
After this, finally we install the SYSLINUX bootloader to this OS file and make it bootable. Before starting, you need to create a syslinux.cfg
file to automatically load vmlinuz and initramfs.cpio, or else you need to manually type the command in the boot prompt of SYSLINUX:
sudo vim /distro/tmp/syslinux.cfg
Vim > CFG
PROMPT 0
TIMEOUT 50
DEFAULT MyOS
LABEL MyOS
MENU LABEL MyOS
KERNEL /vmlinuz
INITRD /initramfs.cpio
This is the syslinux.cfg
file. After saving it, you may now install the SYSLINUX bootloader to it:
cd /distro
sudo umount tmp
sudo syslinux OS
You've created a bootable image of your own OS. Boot it using QEMU:
qemu-system-x86_64 OS
Your system will now boot; however, if you decided not to create the cfg file, you have to manually load the vmlinuz and initrd by typing in the boot prompt:
/vmlinuz -initrd=/initramfs.cpio
Congratulations! You've booted into your OS now!
Comments