Minimal Linux

Friday, October 31, 2008 by Nasir

It is been a awhile since I wrote something technical. At some point I wanted to build Linux distribution from scratch. After a short research I found Linux From Scratch project. I learned a lot from it.

I’m now more involved with embedded development and I wanted to do the same, but for embedded environment. My idea is to use just Linux Kernel, BusyBox and initramfs. Turns out I’m not the only one who wanted to do that. There is tons of information about that. The one I found where a bit outdated, as this one will be too, in fairly short time. I want to use the latest stable Linux Kernel and BusyBox. I spend almost five hours, spread on couple days to get it to work. Linux Kernel 2.6.27.4 and BusyBox 1.12.1 is what I used.

The way I do things is to start with minimalistic configuration and enable just what I need. Download, extract and run make with allnoconfig option:

mkdir download ; cd download/
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.4.tar.bz2
wget http://busybox.net/downloads/busybox-1.12.1.tar.bz2
cd ..
tar xjvf download/linux-2.6.27.4.tar.bz2
tar xjvf download/busybox-1.12.1.tar.bz2 
cd linux-2.6.27.4/
make allnoconfig
cd ../busybox-1.12.1/
make allnoconfig
cd ../linux-2.6.27.4/

That’s what I did. Now I need to enable two options in Linux kernel, the ELF support and Initial RAM file system support.

make menuconfig

Enable these two option by selecting:

General setup —>
    Initial RAM filesystem and RAM disk (initramfs/initrd) support
Executable file formats / Emulations —>
    Kernel support for ELF binaries

Build and get the kernel.

make
cp arch/x86/boot/bzImage ..

BusyBox also need one option, which is static binary build.

cd ../busybox-1.12.1
make menuconfig

You can find it at:

Busybox Settings —>
    Build Options —>
        Build BusyBox as a static binary (no shared libs)

Also you need to select which applets you want to be supported. You will need a shell, mount at to be able to do something. When you are done choosing the applets, build BusyBox and install it.

make
make install

After compiling with install option you will find _install directory. I use that directory as a base for root file system. In there create dev, proc, sys and tmp directory’s. We need at least one device, which is console and we need init script as well. I also remove linuxrc.

mv _install/ ../rootfs
cd ../rootfs/
mkdir dev proc sys tmp
rm linuxrc
mknod dev/console c 5 1
cat >> init << EOF
#!/bin/sh
	
mount -t proc none /proc
mount -t sysfs none /sys
	
/bin/sh
EOF
chmod +x init 

Archive the initramfs with cpio and compress it with gzip.

find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
cd ..

Done. That is all to it.

We can run what we just builded in Qemu

Windows will something like this:

qemu.exe -L . -m 8 -M pc -kernel bzImage -initrd rootfs.cpio.gz -hda linux.img

Linux will something like:

qemu /dev/null -m 8 -kernel bzImage -initrd rootfs.cpio.gz

Either way you can find which options you need to use just read the Qemu documentation.
I used SYSLinux to boot using a USB pen drive. Read SYSLinux documentation to know how you can do that too. I included the configuration for linux-2.6.27.4 and busybox-1.12.1 to this entry.

Note:
hristo hint the following: “Also it is good to state in more clean way that at least mount and shell (ash) applets should be selected”.