DEV Community

Can Gulmez
Can Gulmez

Posted on

Embedded Linux Development - Part 4

In this tutorial, I will go with the fourth stage of embedded Linux development which is the rootfs.

Every Linux-based system have a filesystem. If you are on GNU/Linux, you already probably know it and how it structured.

Apart from that embedded Linux needs a few special applications to start up the system. The init is the first program that runs on user-space so that its process ID always is 1. This init program is responsible for start the other user-space applications and services like shell. It generally resides at /sbin/init, /etc/init, /bin/init or so on. The kernel try to find it and then run.

The organization of a Linux rootfs in terms of directories is well-defined by the Filesystem Hierarchy Standard. The general hierarchy:

  • /bin: Basic programs

  • /boot: Kernel images, configurations and booting tools

  • /dev: Device files

  • /etc: System-wide configuration

  • /home: Directory for the users home utilities

  • /lib: Basic libraries

  • /media: Mount points for removable media

  • /mnt: Mount point for a temporarily mounted filesystem

  • /proc: Mount point for the proc virtual filesystem

  • /root: How directory of the root user

  • /run: Run-time variable data

  • /sbin: Basic system programs

  • /sys: Mount point of the sysfs virtual filesystem

  • /tmp: Temporary files

  • /usr: User-specific utilities

  • /var: Variable data files, for system services

So in summary, I need to create a Linux rootfs and then put the required applications in there. I also want to build a development environment. For example, I want to run python 3 scripts, compiling C/C++ programs, or so on. But how?

There are three options here:

  • Building everything from scratch

  • A minimal BusyBox rootfs

  • A Debian rootfs with debootstap

Which option is for me?

Building everything from scratch means that creating the directories and then fetch the every program, package, library by hand. It means the hell of package dependency! It's not for me.

A minimal rootfs can be created with BusyBox easily. It can create the classic Linux directories and put the core utilities in there like cp, mkdir, ls or so on. If you're making embedded Linux system first time and just focusing on a "running" system, BusyBox is for you. But I need more. I wanna create a development environment!

The right tool is debootstrap program. It creates a base Debian rootfs including the utilities that we're using everyday like apt, systemctl, vi, or so on. This Debian rootfs is around ~200MB, while BusyBox rootfs is ~1MB.

By the way, if you want to go with BusyBox rootfs (while I'm not), below is the required commands:

$ git clone https://git.busybox.net/busybox
$ cd busybox
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc)
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig # optional
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- CONFIG_PREFIX=path/to/linux/rootfs install
Enter fullscreen mode Exit fullscreen mode

Let's focus on debootstrap. Firstly download it.

$ sudo apt install qemu-user-static debootstrap
Enter fullscreen mode Exit fullscreen mode

In here, I also installed qemu-user-static which lets me to run the ARM binaries onto x86_64.

Let's create the base Debian rootfs:

$ sudo debootstrap --arch=armhf --foreign bookworm path/to/linux/rootfs http://deb.debian.org/debian
$ sudo chroot path/to/linux/rootfs /debootstrap/debootstrap --second-stage
Enter fullscreen mode Exit fullscreen mode

In here, bookworm is the nickname of Debian 12 which is the last stable version.

These two commands download the rootfs and then unpack it. So it takes some time (~30 minutes in my case). Don't forget, these just fetch the required and important packages from the Debian database, not fully OS.

The rootfs is ready to be used. But there are some tricks that you always must do:

$ sudo cp /usr/bin/qemu-arm-static <path/to/linux/rootfs>/usr/bin/
Enter fullscreen mode Exit fullscreen mode

I also want to install the additional packages and make some settings. For example, you always must set the password. That means I need to run this rootfs on my Ubuntu host:

$ sudo chroot path/to/linux/rootfs
Enter fullscreen mode Exit fullscreen mode

First thing you must is to update the password:

root@can:/# passwd
New password: 
Retype new password: 
passwd: password updated successfully
Enter fullscreen mode Exit fullscreen mode

Install the additional packages if you want:

root@can:/# apt install gcc python3 vim openssh-server # and what you need
Enter fullscreen mode Exit fullscreen mode

In here, make sure that you install the openssh-server. It's required for ssh command.

Lastly, I need to install the kernel modules in this rootfs. Go back to the kernel source and run:

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=path/to/linux/rootfs modules_install
Enter fullscreen mode Exit fullscreen mode

That's it. I created the proper Debian rootfs that I can make software development. In the next tutorial, I will use the all artifacts coming from u-boot, the kernel and the rootfs to make SD card image.

Resources:

Simmonds C., Mastering Embedded Linux Programming, Packt Publishing, 2015
Embedded Linux system development training, Bootlin, 2024

Top comments (0)