Monday , January 23 2017
Home / Linux / Custom RFS for Beaglebone Black using Busybox

Custom RFS for Beaglebone Black using Busybox

busybox

Hello folks,

In my previous post about Linux kernel compilation for Beaglebone black, I had used pre-built RFS for booting the kernel. Also, I mentioned that the RFS could be built from scratch using an utility called Busybox. In this post, we’ll see how to create one Custom RFS using Busybox and what are all the additional files required to boot the kernel. The RFS which we’re going to create contains only the bare minimum stuffs required to boot the kernel, so you can’t expect it to behave like your distribution’s rootfs.

Before getting our hands dirty by working with Busybox, let’s acquire some basic theory to get things organized!

What is RFS?
RFS is the Root File System¬† (/), the place where the kernel acts upon. All of the applications will reside inside this root file system. Usually RFS is created and placed in the Flash memory of the device, it could be either your Android phone or your Personal computer. There is also one filesystem called initramfs, which is used in the boot process of the Linux based desktops/servers. But, initramfs is a RAM based filesystem which contains the entire root file system directories often compressed and passed along with the kernel image. Embedded Linux devices doesn’t necessarily need initramfs for booting.

During the last stage of the Linux legacy booting process, the kernel executes the /sbin/init which in turn looks for the inittab file in /etc directory. It is based upon the SysV init process. But, most of the modern linux distros now switched from SysV init to Systemd, which is more flexible.

How do I create a RFS?

Now, we know that rootfs is mandatory inorder to boot the linux kernel. But how do I create one? Have you tried “ls /” in your linux machine… Yes, there are lot of directories under ‘/’. Usually not all of the directories were needed to get your linux system up and running. Only a fair amount of directories were needed by the kernel, but it entirely depends upon the end application your linux system is used. It could be either a server or an Embedded linux system for a dedicated application.

In our case we’ll consider the later one because our target platform is Beaglebone black, which is mostly used for an Embedded application. Let’s discuss the list of directories needed and their uses.

Mandatory directories:

1. /bin
/bin directory contains the commands used by the normal linux user for day to day activities like ls, cp, rm. It also contains the commands needed during boot process like systemd etc…

2. /sbin
/sbin directory contains the binaries used by the super user for system administration. Some of the commands are insmod, lsmod, ipconfig. Normal users can’t use the commands in this directory without administrative privileages.

3. /etc
/etc directory contains the files needed for system configuration like init scripts, network conf files, bootloader init scripts, application conf files etc…

4. /dev
/dev directory contains the special files which represent the devices present in the system like char, block and net devices. It also contains the files needed to interact with the device drivers for a particular hardware using generic read/write calls. For all types of devices attached to the target, appropriate device nodes will be created in this directory.

5. /lib
/lib directory contains the shared libraries used the applications in the system. Often it contains the glibc/klibc, ld-linux shared libraries. It also contains the loadable kernel modules under /lib/modules which could be inserted into the system dynamically using modprobe/insmod commands. List of modules should be built while building the kernel using ‘make modules’ command. Modules could also be loaded automatically when the devices were attached to the system using some utilities.

6. /usr

/usr directory contains the userspace programs and data. In old unix implementations, this is the place where the home directories of all users were placed. It contains the necessary data, headers, libraries and also some programs like telnet, git etc…

Nice to have:

1. /proc
/proc directory is based on procfs filesystem. It is a type of virtual file system which contains files based on the processes exist in the system. There is no need to create any files under this directory, all files will be created once you mount the procfs in this directory.

2. /sys
/sys directory is based on sysfs filesystem. Like procfs, this is also a type of virtual file system based on the Kernel objects and its attributes. It is most widely used to interact with the device drivers like /dev directory. Drivers need to create sysfs entry, then it may contain files to send/receive data from the driver. For instance Led’s in Beaglebone black could be configured using sysfs/class/leds.

3. /config
/config directory is based on configfs filesystem. Major use of the configfs is to manage the Kernel objects from userspace. Unlike sysfs, which just acts on the Kernel objects, this one can modify it in runtime.

Alright, we have seen the list of directories needed and their uses. So, are we going to create all these directories and its contents by hand? It would be an over kill, isn’t it?

For this scenario, we’re going to use an utility called Busybox, which will make our life easier ūüôā

Busybox Cross compilation

Definition from its site:

“BusyBox combines tiny versions of many common UNIX utilities into a single small executable. It provides replacements for most of the utilities you usually find in GNU fileutils, shellutils, etc. The utilities in BusyBox generally have fewer options than their full-featured GNU cousins; however, the options that are included provide the expected functionality and behave very much like their GNU counterparts. BusyBox provides a fairly complete environment for any small or embedded system.”

Busybox is focused mainly on Embedded platforms as the size optimization is vastly required. It could be built as the binary requiring shared libraries (default option) or a single static binary requiring no external shared libraries. We are going to use the later one.

Working with Busybox

Download the Busybox source from here:

Extract the tarball using following command

Then, cross compile the source for ARM platform using the following commands.

Note: This assumes that you have the arm cross compilation toolchain configured in your system. If not please go through my previous post to see how to get it done.

Select Busybox Settings -> Build Options -> Build Busybox as a static binary (no shared libs). Press y for selecting that option and save it. Then execute the following commands for building.

After the successful completion of the above commands, you can see 3 directories (bin, sbin, usr) and one file (linuxrc) created in your RFS directory. Path to RFS should be like /media/user/rfs which resides in SD card as ext3 file system. Apart from these, we need few more directories mentioned above to boot the kernel. So, move to the RFS location and create the following files and directories.

/dev:

Create some special files under this directory.

Console: The place where the kernel uses for interaction.

Null: This behaves like an empty file and is used to suppress the output from commands/programs.

Zero: Contains sequence of zeros used to fill up the memory regions.

/lib and /usr/lib:

For the static libraries, copy from the arm cross compiler toolchain path.

/proc, /sys, /root:

Create directories for mounting the virtual filesystems (procfs, sysfs) and root directory.

/etc:

Then, create additional files inside this directory.

Create another file called fstab and populate it. This file will mount the virtual file systems.

Also, create files hostname and passwd.

Busybox init will first look for /etc/init.d/rcS script, if it can’t find that then it will look for /etc/inittab. Inittab file will mount the virtual filesystem using fstab. Also, it will have the command for getting login prompt and shell.

/sbin/init -> /bin/cttyhack -> /bin/login -> /bin/sh.

Here, we don’t use password for login. So, after logging in, set the password by executing ‘passwd’ command.

Note: You may encounter ‘read only filesystem error’. This is due to the kernel parameters which Uboot has passed. You can change it by modifying the uEnv.txt file as:

This will mount the RFS as read/write file system.

That’s it…

Voila! You have successfully created one Custom RFS using Busybox for Beaglebone Black. Just insert the SD card into BBB’s slot and hold the Boot switch (SW2) while powering up. This will boot your linux kernel using Custom built RFS.

As we always say, if you get stuck at any point kindly post your questions in comments in somewhat detailed manner (No need to post the entire log…), we’ll help you out.

About Mani

Mani is an Embedded Linux hobbyist having perennial interest towards Electronics and Agriculture. You can reach him by the following social channels.

Check Also

gmail

How to use gmail form terminal (Linux)

Great news gmail our favorite mail service can be accessed form command line!! Now you …

  • Mansoor Haq

    Hi Mani,

    Thanks for the great post.
    I was wondering, if there is a way to compile a custom RFS in Ubuntu box.

Keep in touch with the current trends!
Did you like this article? Sign up and get our latest posts delivered to your inbox!
  We hate spam and never share your details.