Fundamentals 17 min read

How to Build a Minimal Root Filesystem for Embedded Linux with BusyBox

This guide explains how to create a minimal root filesystem for an embedded Linux board using BusyBox, covering flash file system options, required directory structure, cross‑compilation setup, building and installing BusyBox, adding init scripts, creating a ramdisk image, and configuring U‑Boot to boot from NFS or ramdisk.

Liangxu Linux
Liangxu Linux
Liangxu Linux
How to Build a Minimal Root Filesystem for Embedded Linux with BusyBox

1. Overview of Root Filesystem

In an embedded device, the kernel can run without a user‑space process, but a root filesystem is still needed to provide the directory hierarchy and interfaces that the kernel expects. The root filesystem contains essential directories (e.g., /bin, /etc, /proc) and files required for booting.

2. Flash‑Based Filesystems

Linux supports many filesystems (ext2, ext3, vfat, ntfs, iso9660, jffs, yaffs, romfs, nfs). To manage them uniformly, the Virtual File System (VFS) layer provides a common API. Common flash filesystems for embedded devices include:

Cramfs : read‑only, fast, but cannot be expanded.

JFFS2 : journalling flash FS, supports compression and wear‑leveling; performance degrades when the FS is near full.

YAFFS/YAFFS2 : designed for NAND flash, lightweight, fast mount, supports large pages in YAFFS2.

NFS : network file system useful during development to mount a host‑side rootfs.

Tools such as mkfs.cramfs, mkfs.jffs2, and mkfs.yaffs are used to create images.

3. Root Filesystem Composition

The rootfs must contain at least the following top‑level directories: bin – basic executables opt – optional packages boot – kernel and bootloader files proc – virtual procfs dev – device nodes root – root user home etc – configuration files sbin – system administration binaries home – regular user homes tmp – temporary files lib – shared libraries usr – additional applications mnt – mount points for other filesystems var – variable data such as logs

Only the directories required for the target board need to be created.

4. Required Directories for Embedded Builds

/bin /sbin /etc /proc /tmp /var /dev /mnt

Typical rootfs must also include:

Basic filesystem hierarchy.

Essential libraries (e.g., glibc).

System init scripts (e.g., rc.sysinit, inittab).

Device node support ( /dev/hd*, /dev/tty*, /dev/fd0).

Basic utilities ( sh, ls, cp, mv).

5. Build Steps Using BusyBox

5.1 Download Source

http://busybox.net/downloads/busybox-1.22.1.tar.bz2

5.2 Extract

tar xvf busybox-1.22.1.tar.bz2

5.3 Enter Directory

cd busybox-1.22.1

5.4 Configure

Run make menuconfig and enable a static build:

Busybox Settings → Build Options → [*] Build BusyBox as a static binary (no shared libs)
(arm-none-linux-gnueabi-) Cross Compiler prefix

5.5 Compile

make

5.6 Install

make install

The installation creates an _install directory containing bin, sbin, usr, and linuxrc.

5.7 Create Additional Directories

mkdir dev etc mnt proc var tmp sys root

5.8 Copy Required Libraries

cp /home/linux/toolchain/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/* . -a

Adjust permissions, strip symbols, and ensure the total size stays below 8 MiB:

chmod +w lib
rm lib/*.a
arm-none-linux-gnueabi-strip lib/*
du -mh lib/

5.9 Add Init Scripts

Create etc/inittab:

#this is run first except when booting in single‑user mode.
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot

Create etc/fstab:

#device     mount-point   type    options   dump fsck order
proc        /proc         proc    defaults   0    0
tmpfs       /tmp          tmpfs   defaults   0    0
sysfs       /sys          sysfs   defaults   0    0
tmpfs       /dev          tmpfs   defaults   0    0

Ensure the kernel has tmpfs support enabled (via

make menuconfig → Pseudo filesystems → [*] Tmpfs POSIX Access Control Lists

).

5.10 Create rcS Script

#!/bin/sh
/bin/mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s

Make it executable:

chmod +x init.d/rcS

5.11 Add profile

#!/bin/sh
export HOSTNAME=farsight
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
mknod dev/console c 5 1   # required console node

6. Create a RAM Disk Image

6.1 Create Empty Image (8 MiB)

dd if=/dev/zero of=ramdisk bs=1k count=8192

6.2 Format as ext2

mkfs.ext2 -F ramdisk

6.3 Mount and Populate

mkdir -p /mnt/initrd
mount -t ext2 ramdisk /mnt/initrd
cp -a /source/rootfs/* /mnt/initrd/
umount /mnt/initrd

6.4 Compress

gzip --best -c ramdisk > ramdisk.gz

6.5 Convert for U‑Boot

mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img
cp ramdisk.img /tftpboot

7. Kernel Configuration for RAM Disk

Enable the following options:

File systems → [*] Second extended fs support
Device Drivers → SCSI disk support → [*] SCSI disk support
Block devices → [*] RAM block device support (default 16 disks, 8192 kB size – adjust to 8 MiB)
General setup → [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

Re‑compile the kernel and copy the resulting uImage to /tftpboot.

8. U‑Boot Boot Commands

# Example boot from NFS rootfs
setenv bootcmd 'tftp 41000000 uImage; tftp 42000000 exynos4412-fs4412.dtb; bootm 41000000 - 42000000'
setenv bootargs 'root=/dev/nfs nfsroot=192.168.9.120:/source/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=192.168.9.233'
saveenv

# Example boot from RAM disk
setenv bootcmd 'tftp 41000000 uImage; tftp 42000000 exynos4412-fs4412.dtb; tftp 43000000 ramdisk.img; bootm 41000000 43000000 42000000'
saveenv

After setting the environment, reset the board and verify that it boots correctly.

Image
Image
Filesystemcross-compilationrootfsbusyboxramdiskubootembedded-linux
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.