Never Ending Security

It starts all here

How To Build a Linux Barebones


There are so many people out there interested in Linux and how it all comes together, but so few resources to explain just that. Sure there is Linux From Scratch but that is an entire distribution with all kinds of extra programs added in. There is also the Fedora and Debian tools to make smaller and lighter versions of those distributions.

But those tools keep so much hidden and automate so much.

A basic Linux system need be no more than a boot loader and a kernel. That is what we would like to explore here today. How to make your own barebones Linux Build installation ?

Barebones Linux Build Barebones Linux Build barebone Barebones Linux Build Barebones Linux Build Barebones Linux BuildBarebones Linux Build Goal

At the end of this article we will have a working build that can be written onto a USB stick that is capable of booting into a barebones Linux Build environment. The environment should have these things:

  • Linux Kernel
  • Bootloader (grub)
  • Basic Utilities (busybox)

Here are some things that are needed:

  • Computer/virtual machine running Centos 6.5 32bit
  • 512M+ USB Stick

All of these commands will be issued as root !

These are similar examples of what we are about to build but this one will be much smaller and have much less flotsam in the build.

Building the Environment

You need to make sure that you have some special utilities and programs available to build the sources. Additionally you will nee to make a working directory for your work.

Make sure all needed packages are installed

yum -y update
yum -y groupinstall 'Development tools'
yum -y install wget bc

Create the initial working directory structure and environment

export SRC=/barebones/source
export BLD=/barebones/build
mkdir -p $BLD
mkdir -p $BLD/lib $BLD/proc $BLD/sys $BLD/dev $BLD/etc/init.d $BLD/tmp
mkdir -p $SRC
chmod 1777 $BLD/tmp
cd $SRC

Download all of the required packages into /barebones/source


Then Proceed to uncompress the archives we have downloaded.


tar xf busybox-1.22.1.tar.bz2
tar xf linux-3.19.tar.gz

Building the Sources

You can spend a lot of time reading up on how to tweak a kernel config. But, luckily, you do not absolutely have to do that anymore. You can build the kernel with a ‘default’ configuration that works fine in most instances.

Configure and compile the kernel

cd $SRC/linux-3.19
make defconfig && make 

This process has made a kernel image for you called ‘arch/x86/boot/bzImage’ which you can copy to your build directory. This is the kernel you will be booting from when you are done building.

Copy kernel to build directory

cp arch/x86/boot/bzImage $BLD/boot/vmlinuz

Now for busybox. It requires us to compile it as well.

Configure and compile busybox

cd $SRC/busybox-1.22.1
make defconfig && make
make install

This process here compiled busybox and made a binary in the _install directory, along with symlinks that point back to the busybox binary. We need to chmod the busybox binary so it is executable, and copy all of the symlinks to our build directory. It also creates ‘linuxrc’ which isn’t needed, so it should be removed. Finally, set up a symlink to point /init to busybox.

Make busybox executable, copy symlinks to build directory

chmod 4755 _install/bin/busybox
cp -a _install/* $BLD/

Remove linuxrc and create an /init symlink

rm $BLD/linuxrc
cd $BLD
ln -s bin/busybox init

Initialization Configuration

When the new kernel boots up, it mounts the initrd image, then it looks for an ‘init’ to fire off. ‘init’ then runs configuration files located in /etc/init.d/ such as this one that we are going to make here. This ‘rcS’ file is executable and will:

  • mount everything in the fstab
  • populate the /dev directory
  • set the hostname from /etc/hostname
  • bring up the loopback interface

Finally, we will make sure that the file is exectuable by init.

Create /etc/init.d/rcS

cd $BLD
cat << EOF > $BLD/etc/init.d/rcS
mount -a
/sbin/mdev -s
/bin/hostname -F /etc/hostname
/sbin/ifconfig lo up

chmod +x $BLD/etc/init.d/rcS

‘mount -a’ will require an /etc/fstab file for it to work. It should contain names and types of the default mount points – proc, sysfs, devpts and tmpfs.

Create /etc/fstab

cat << EOF > $BLD/etc/fstab
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
devpts /dev/pts devpts defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0

This is the file that is polled for the machine’s hostname.

Create /etc/hostname

echo 'localhost' > $BLD/etc/hostname

You can get away without having a user, but some utilities might have a hard time running. It is best to have a root user created which requires 3 files:

  • /etc/passwd
  • /etc/group
  • /etc/shadow

/etc/shadow is the file that passwords are stored in, so its permissions should be modified to be less permissive.

echo "root:x:0:0:root:/root:/bin/sh" > $BLD/etc/passwd
echo "root::10:0:0:0:::" > $BLD/etc/shadow
echo "root:x:0:" > $BLD/etc/group
chmod 640 $BLD/etc/shadow

Library requirements

Grab the libraries that you need from your host OS. In a typical build, we would have made a toolchain and built our own libraries, but for a barebones linux Build there is no need.

Copy libraries to build

cp /lib/{,,} $BLD/lib/
cp /lib/ $BLD/lib/

Create your initrd

The final step, and the one that causes the most problems, is building your own initrd.img file. This file will be uncompressed by Linux and used as it’s operating environment.

Compress initrd.img file

cd $BLD
find . -print | cpio -o -H newc | gzip -9 > $BLD/boot/initrd.img

Putting it onto a flash drive

We have to partition and format a flash drive, put all of these files onto it, and finally, configure grub the bootloader. You will have to partition the drive by hand!

Partition and format your flash drive

## We will assume your flashdrive is /dev/sdb, if not, 
## substitute sdb with whatever yours is configured as.

#remove all partitions, make new partition, bootable, write
cfdisk /dev/sdb 
mkfs.ext2 /dev/sdb1

Mount flashdrive and copy build files to it

mkdir /barebones/flashdrive
mount /dev/sdb1 /barebones/flashdrive
rsync -varh /barebones/build/ /barebones/flashdrive/

Install grub bootloader onto flash drive

grub-install --root-directory=/barebones/flashdrive /dev/sdb

Configure grub further

cat << EOF > /barebones/flashdrive/boot/grub/grub.cfg
menuentry "Standard boot" {
set root=(hd0,msdos1)
linux /boot/vmlinuz
initrd /boot/initrd.img
menuentry "Debug boot" {
set root=(hd0,msdos1)
linux /boot/vmlinuz debug
initrd /boot/initrd.img
menuentry "Pre-mount break boot" {
set root=(hd0,msdos1)
linux /boot/vmlinuz debug break=y name=sz
initrd /boot/initrd.img

Unmount your flash drive

umount /barebones/flashdrive

CONGRATS You now have a bootable Linux flash drive.

More information can be found at:

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s