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.
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 /mntTypical 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.bz25.2 Extract
tar xvf busybox-1.22.1.tar.bz25.3 Enter Directory
cd busybox-1.22.15.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 prefix5.5 Compile
make5.6 Install
make installThe installation creates an _install directory containing bin, sbin, usr, and linuxrc.
5.7 Create Additional Directories
mkdir dev etc mnt proc var tmp sys root5.8 Copy Required Libraries
cp /home/linux/toolchain/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/* . -aAdjust 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/rebootCreate 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 0Ensure 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 -sMake it executable:
chmod +x init.d/rcS5.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 node6. Create a RAM Disk Image
6.1 Create Empty Image (8 MiB)
dd if=/dev/zero of=ramdisk bs=1k count=81926.2 Format as ext2
mkfs.ext2 -F ramdisk6.3 Mount and Populate
mkdir -p /mnt/initrd
mount -t ext2 ramdisk /mnt/initrd
cp -a /source/rootfs/* /mnt/initrd/
umount /mnt/initrd6.4 Compress
gzip --best -c ramdisk > ramdisk.gz6.5 Convert for U‑Boot
mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img
cp ramdisk.img /tftpboot7. 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) supportRe‑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'
saveenvAfter setting the environment, reset the board and verify that it boots correctly.
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.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
