Skip to content

A minimal, customizable Linux distribution built from scratch using the Linux kernel, BusyBox, and Syslinux bootloader. This project demonstrates how to build a bootable Linux system with full control over every component.

License

Notifications You must be signed in to change notification settings

ehsanghaffar/handbuilt-linux

Repository files navigation

Handbuilt Linux: Custom Linux Distribution from Scratch

A minimal, customizable Linux distribution built from scratch using the Linux kernel, BusyBox, and Syslinux bootloader. This project demonstrates how to build a bootable Linux system with full control over every component.

License Docker Linux

πŸ“‹ Table of Contents

✨ Features

  • Minimal footprint: Only essential components included
  • From scratch: Built directly from kernel and BusyBox sources
  • Multi-stage Docker build: Optimized build process with caching
  • Bootable ISO: Creates a bootable ISO image
  • Custom init system: Simple, transparent init process
  • QEMU ready: Easy testing with QEMU emulator
  • Configurable: Customize kernel and BusyBox configurations
  • Fast builds: Parallel compilation with caching

πŸ”§ Prerequisites

For Docker Build (Recommended)

  • Docker 20.10 or later
  • Docker Compose (optional)
  • 4GB free disk space
  • 2GB RAM minimum

For Manual Build

  • Linux system (Debian/Ubuntu recommended)

  • Build tools: gcc, make, bison, flex

  • Additional packages:

    sudo apt-get install build-essential libncurses-dev bison flex \
      libssl-dev libelf-dev bc cpio git wget curl syslinux \
      dosfstools genisoimage qemu-system-x86

πŸš€ Quick Start

Using Docker (Recommended)

  1. Clone the repository

    git clone https://github.com/ehsanghaffar/handbuilt-linux.git
    cd handbuilt-linux
  2. Build the distribution

    docker build -t handbuilt-linux .
  3. Extract the ISO

    docker run --rm handbuilt-linux cat /distro/output.iso > output.iso
  4. Test with QEMU

    qemu-system-x86_64 -cdrom output.iso -m 512M

Using Docker Compose

docker-compose up --build

πŸ—οΈ Building from Source

Step 1: Build with Docker

The multi-stage Dockerfile handles all build steps:

# Build the complete image
docker build -t handbuilt-linux .

# Or build specific stages
docker build --target kernel-builder -t linux-kernel .
docker build --target busybox-builder -t busybox-build .
docker build --target iso-builder -t linux-iso .

Step 2: Extract Build Artifacts

# Extract ISO
docker run --rm handbuilt-linux cat /distro/output.iso > output.iso

# Extract kernel
docker run --rm handbuilt-linux cat /distro/bzImage > bzImage

# Extract initramfs
docker run --rm handbuilt-linux cat /distro/initramfs > initramfs

Step 3: Create Bootable USB (Optional)

# Replace /dev/sdX with your USB device (BE CAREFUL!)
sudo dd if=output.iso of=/dev/sdX bs=4M status=progress
sudo sync

πŸ“– Usage

Running with QEMU

Boot from ISO:

qemu-system-x86_64 -cdrom output.iso -m 512M

Boot from kernel and initramfs directly:

qemu-system-x86_64 \
  -kernel bzImage \
  -initrd initramfs \
  -append "console=ttyS0" \
  -nographic \
  -m 512M

With networking:

qemu-system-x86_64 \
  -cdrom output.iso \
  -m 512M \
  -netdev user,id=net0 \
  -device e1000,netdev=net0

Building Boot Image

Use the enhanced build.sh script to create a bootable disk image:

# Basic usage
./build.sh

# Custom size
./build.sh --size 100

# Custom output name
./build.sh --output my-boot.img

# Verbose output
./build.sh --verbose

# Show help
./build.sh --help

Interactive Shell Commands

Once booted, you have access to BusyBox utilities:

# List all available commands
busybox --list

# File operations
ls, cat, cp, mv, rm, mkdir, rmdir, touch

# System utilities
ps, top, free, df, mount, umount, hostname

# Network utilities
ifconfig, ping, wget, nc

# Text processing
grep, sed, awk, sort, uniq, head, tail

πŸ“ Project Structure

handbuilt-linux/
β”œβ”€β”€ Dockerfile              # Multi-stage Docker build
β”œβ”€β”€ docker-compose.yml      # Docker Compose configuration
β”œβ”€β”€ Makefile               # Build automation
β”œβ”€β”€ README.md              # This file
β”œβ”€β”€ LICENSE                # Project license
β”œβ”€β”€ .gitignore             # Git ignore rules
β”‚
β”œβ”€β”€ build.sh               # Boot image builder script
β”œβ”€β”€ init.sh                # Init system script (PID 1)
β”œβ”€β”€ syslinux.cfg           # Bootloader configuration
β”‚
β”œβ”€β”€ linux.config           # Linux kernel configuration
β”œβ”€β”€ busybox.config         # BusyBox configuration
β”‚
β”œβ”€β”€ scripts/               # Helper scripts
β”‚   β”œβ”€β”€ test.sh           # Testing script
β”‚   β”œβ”€β”€ extract.sh        # Extract artifacts from Docker
β”‚   └── clean.sh          # Cleanup build artifacts
β”‚
β”œβ”€β”€ docs/                  # Additional documentation
β”‚   β”œβ”€β”€ BUILDING.md       # Detailed build instructions
β”‚   β”œβ”€β”€ CUSTOMIZING.md    # Customization guide
β”‚   └── TROUBLESHOOTING.md # Common issues and solutions
β”‚
└── .github/
    └── workflows/
        └── build.yml      # CI/CD pipeline

βš™οΈ Configuration

Kernel Configuration

To customize the kernel:

# Start configuration menu
docker run -it --rm -v $(pwd):/work handbuilt-linux bash
cd /opt/mydistro/linux
make menuconfig
# Save configuration
cp .config /work/linux.config

BusyBox Configuration

To customize BusyBox:

# Start configuration menu
docker run -it --rm -v $(pwd):/work handbuilt-linux bash
cd /opt/mydistro/busybox
make menuconfig
# Save configuration
cp .config /work/busybox.config

Init System

Modify init.sh to customize:

  • Hostname
  • Mounted filesystems
  • Network configuration
  • Startup services
  • Environment variables

Bootloader

Modify syslinux.cfg to customize:

  • Boot timeout
  • Kernel parameters
  • Boot menu options
  • Default boot entry

πŸ”₯ Advanced Usage

Custom Packages

Add custom software to the initramfs:

# In Dockerfile, add after BusyBox installation:
RUN cd /build/initramfs && \
    wget https://example.com/package.tar.gz && \
    tar xzf package.tar.gz && \
    rm package.tar.gz

Multi-Architecture Support

Build for different architectures:

# ARM64
docker build --build-arg ARCH=arm64 -t handbuilt-linux-arm64 .

# ARM
docker build --build-arg ARCH=arm -t handbuilt-linux-arm .

Persistent Storage

Mount a persistent volume:

qemu-system-x86_64 \
  -cdrom output.iso \
  -m 512M \
  -drive file=data.img,format=raw

Network Boot (PXE)

Extract kernel and initramfs for network booting:

# Extract files
docker run --rm handbuilt-linux cat /distro/bzImage > /tftpboot/bzImage
docker run --rm handbuilt-linux cat /distro/initramfs > /tftpboot/initramfs

# Configure PXE
cat > /tftpboot/pxelinux.cfg/default << EOF
DEFAULT linux
LABEL linux
    KERNEL bzImage
    APPEND initrd=initramfs
EOF

πŸ› Troubleshooting

Common Issues

Build fails with "out of space" error:

# Increase Docker disk space or clean up
docker system prune -a

QEMU shows black screen:

# Use serial console
qemu-system-x86_64 -cdrom output.iso -nographic

Kernel panic on boot:

# Check initramfs was created correctly
file initramfs
# Should show: "gzip compressed data"

Permission denied when mounting:

# Run build.sh with sudo
sudo ./build.sh

Debug Mode

Enable verbose logging:

# Build script
./build.sh --verbose

# QEMU with debug output
qemu-system-x86_64 -cdrom output.iso -d guest_errors,cpu_reset

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Linux Kernel - The core of the operating system
  • BusyBox - The Swiss Army Knife of Embedded Linux
  • Syslinux - Lightweight bootloader
  • QEMU - Emulator for testing

πŸ“š Resources

πŸ“ž Support

  • Create an issue for bug reports
  • Start a discussion for questions
  • Check existing issues before creating new ones

About

A minimal, customizable Linux distribution built from scratch using the Linux kernel, BusyBox, and Syslinux bootloader. This project demonstrates how to build a bootable Linux system with full control over every component.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published