Skip to main content

Developing a simple Linux Distro from scratch using Busybox

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.

Bash
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:

Bash
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.

Bash
sudo git clone --depth 1 https://github.com/torvalds/linux

OR

Bash
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):

Bash
sudo tar -xvf linux-x.x.x.tar.xz

Now, cd to the extracted or cloned folder:

Bash
cd linux-x.x.x   # If used wget

OR

Bash
cd linux         # If used git

After entering the Linux directory, make the menu configuration:

Bash
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:

Bash
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:

Bash
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:

Bash
sudo cp arch/x86/boot/bzImage /distro/vmlinuz

Now, exit the Linux directory and clone the BusyBox repository:

Bash
cd ..
sudo git clone --depth 1 https://git.busybox.net/busybox

After cloning, cd to the BusyBox directory:

Bash
cd busybox

Now make the menu configuration:

Bash
sudo make menuconfig

There's a problem with the default configuration, so we need to edit the .config file:

Bash
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:

Bash
sudo make -j$(nproc)

After compilation, make a directory initramfs within the /distro directory, and make install the components to the initramfs folder:

Bash
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:

Bash
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:

Bash
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:

Bash
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:

Bash
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:

Bash
sudo mkfs -t fat OS

After formatting, mount the OS file to a temporary directory in /distro folder:

Bash
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:

Bash
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:

Bash
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:

Bash
cd /distro
sudo umount tmp
sudo syslinux OS

You've created a bootable image of your own OS. Boot it using QEMU:

Bash
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:

Bash
/vmlinuz -initrd=/initramfs.cpio

Congratulations! You've booted into your OS now!

Comments

Anonymous said…
Is it fine, if we don't rename bzImage to vmlinuz?
Gautham Nair said…
It is acceptable, but you must update the syslinux.cfg. If you did not use one, then while typing manually, enter `/bzImage -init=/initramfs.cpio`.

Popular posts from this blog

Windows Whistler: The Birth of Windows XP

 In the early 2000s, Microsoft embarked on a mission to unify its consumer and business operating systems into a single, versatile platform. This mission led to the creation of Windows Whistler , a project that would eventually evolve into the widely acclaimed Windows XP . Let's explore the journey of Windows Whistler and its significance in the world of computing. The Genesis of Whistler Windows Whistler was born out of the need to merge two separate projects: Windows Odyssey and Windows Neptune . Odyssey was aimed at business users, building on the stability and security of Windows 2000, while Neptune targeted home users with a more user-friendly interface. Recognizing the potential benefits of combining these efforts, Microsoft decided to merge the two projects into a single codebase, codenamed Whistler. Key Features and Innovations Whistler introduced several groundbreaking features that would later become hallmarks of Windows XP: Unified Codebase : By merging Odyssey and Nept...

Introducing new Python Modules

 Hello everyone, I have developed three Python modules and published them to pypi.org. The three modules are Donut-LLM-Tools, DonutLLMCore and GIUC. Donut-LLM-Tools, provides users an easy UI for creating, loading models as well as create datasets from Wikipedia wikis. DonutLLMCore is a library that is used by Donut-LLM-Tools to create a PyTorch model. GIUC (Gautham's Important Utility Collection), is a set of mathematical functions designed to help users solve complex math problems. LINKS :  Donut-LLM-Tools DonutLLMCore GIUC