Embedded Freaks..

December 18, 2008

Creating Simple Root Filesystem for Embedded Linux

Filed under: embedded-linux — Tags: — kunilkuda @ 11:28 am

During the last few posts, I’ve been using Debian-ARM from TS-Logic site as the root filesystem. Debian is a nice distro, but it’s too much for learning embedded linux development. Therefore, I’m creating a new simpler root filesystem to make it faster to boot, and reduce the complexity.

The new root filesystem is very simple, so it only have single user (root), a shell, and no-login. It cannot mount any media, send/receive TCP/IP connection, etc. But, we’ll learn how to do it (mounting media, detecting media, detecting ethernet card, etc) step-by-step later.

My root filesystem will be installed in /nfs/simple, since I use it under NFS scheme. You can install it anywhere that you like. But, for sake of this guide, let’s call it the $ROOTFS directory.

Installing Drivers/Modules into Root Filesystem

On the few last posts (here and here), I showed some guide to compile, install, and test the kernel. Now it is the time to install the modules.Installing the modules is easy, if you have compiled the kernel. Issue this command once you have compiled the kernel.

# make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- INSTALL_MOD_PATH=$ROOTFS modules_install

Remember that you can only do this after the kernel compilation stage, since the modules are compiled during the kernel compilation stage.

Note: You might want to delete the $ROOTFS/lib/modules/$KERNEL_VERSION/{build source}..since it’s not needed.

Installing Busybox

Busybox is a single binary that can do almost any UNIX utility (bash, perl, dhcp-client, mount, vi, cat, etc. You might want to view their explanation here). So, we’re going to install it into our simple root filesystem.

Download busybox from its site (here). I’m using Busybox v1.10.1. Untar, then configure it.

# tar xvjf busybox-1.10.1.tar.bz2
# cd busybox-1.10.1/
# CFLAGS=-march=armv4t make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig

Note: You need ncurse-devel package to run menuconfig. For Ubuntu users: “sudo apt-get install libncurses5-dev“.

In busybox configuration, you can select anything that you want. But for me, to make it as simple as possible, I only enable the ash shell. If you have finished with your busybox configuration, compile and install it.

# CFLAGS=-march=armv4t make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
# CFLAGS=-march=armv4t make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- CONFIG_PREFIX=$ROOTFS install

Now, by default most of linux application is built on shared library. Therefore, the shared library needs to be copied into the root filesystem. But that’s not all. The application will also need the shared library loader.

The concept is when the application needs certain function from shared library, it will call the library loader, and pass it the library name, and function that the application needs. The library loader will check whether the shared library has been loaded or not. If not, it will load the shared library into memory. Then, it will return the address of the requested function to the application. Check out the wikipedia for more info.

To check which library loader that busybox is using:

#  arm-none-linux-gnueabi-strings $ROOTFS/bin/busybox | more
/lib/ld-linux.so.3
libc.so.6
setuid
chroot
socket
fflush
strcpy
...a lot more...

The first line of the strings result is the name of the library loader (in this case “/lib/ld-linux.so.3“). We need to copy this loader into our rootfs. Check our toolchain directory for it.

# find $CODESOURCERY -iname ld-linux.so.3
/home/kunil/CodeSourcery/arm-none-linux-gnueabi/libc/armv4t/lib/ld-linux.so.3
/home/kunil/CodeSourcery/arm-none-linux-gnueabi/libc/lib/ld-linux.so.3
/home/kunil/CodeSourcery/arm-none-linux-gnueabi/libc/thumb2/lib/ld-linux.so.3

Note: Change $CODESOURCERY with the directory of your toolchain.

Since we’re using ARM920T (ARMv4T type..as specified in our CFLAGS), our loader is $CODESOURCERY/arm-none-linux-gnueabi/libc/armv4t/lib/ld-linux.so.3. Copy it into $ROOTFS/lib

# cp $CODESOURCERY/arm-none-linux-gnueabi/libc/armv4t/lib/ld-linux.so.3 $ROOTFS/lib

Note, just in case you’re not sure you’ve copied the correct binary (executable or library) into your root filesystem, you can always use ‘readelf’ to check the target architecture of the binary

# arm-none-linux-gnueabi-readelf -A $ROOTFS/lib/ld-linux.so.3

To check shared library that busybox is using:

# arm-none-linux-gnueabi-readelf -d $ROOTFS/bin/busybox

Dynamic section at offset 0x144b4 contains 24 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
...a lot more...

So, we need libc.so.6 in the ld-linux default search path (which is /lib and /usr/lib or any directories inside LD_LIBRARY_PATH environement variable). Copy it into our $ROOTFS.

# cp $CODESOURCERY/arm-none-linux-gnueabi/libc/armv4t/lib/libc.so.6 $ROOTFS/lib

Installing Device Files
Device files are point of contact between the kernel (its device drivers) and the user application. Without it, user application cannot do their work (such as receiving keyboard’s input or sending message to the terminal).

One of the needed device file in our root filesystem is ttyAM0 (ARM “AMBA” serial port 0), the serial console when our board is booting. Create it in with

# mkdir $ROOTFS/dev
# sudo mknod $ROOTFS/dev/ttyAM0 c 205 16

What is “c 205 16″ ? How do you get it ? Read this.

Other than that, we need to create the default console. This is the default console that the kernel will use, before it redirect it into /dev/ttyAM0.

# sudo mknod $ROOTFS/dev/console c 5 1

Testing The Root Filesystem

Boot the board, press CTRL+C to cancel the default booting. Then

RedBoot> load -r -b 0x218000 -h
RedBoot> exec -c "console=/dev/ttyAM0,115200 ip=dhcp nfsroot=:"

That’s it. Your board should display simple prompt, but cannot do anything (actually it depends on what you’ve compiled and installed in Busybox).

About these ads

3 Comments »

  1. [...] by nigifabio on 20 December 2008 Creating Simple Root Filesystem for Embedded Linux « Embedded Freaks.. During the last few posts, I’ve been using Debian-ARM from TS-Logic site as the root filesystem. [...]

    Pingback by Creating Simple Root Filesystem for Embedded Linux « Embedded Freaks.. « Nigi Fabio Blog — December 21, 2008 @ 5:01 am

  2. Hi. I tried this and it worked well. I had to add libm.so.6 as well to $ROOTFS/lib. And to run a program I needed libgcc_s.so.1. To rmmod a module I needed to have the proc filesystem mounted.

    Comment by LRF — November 15, 2009 @ 8:14 am

  3. [...] it’s the same steps as in previous post, but there’s some additional steps that’re needed to be added. First, download, [...]

    Pingback by Testing ‘Disko-Demos’ in LPC3250 « Embedded Freaks.. — November 26, 2010 @ 4:49 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com 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

The Silver is the New Black Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: