The Complete Magazine on Open Source

Develop a GNU/Linux-like OS for a Single Board Computer

SHARE
/ 315 0

Single Board Computer

Single board computers (SBCs) have a variety of applications such as monitoring and observation devices, kiosk terminals, etc. In this column, the author shares his experience of developing a monolithic-kernel GNU/Linux-like OS on the ARM platform for a SBC.

Single board computers (SBCs) have become pretty popular in a wide variety of fields. As the core component of computer systems as well as of embedded systems, the operating system plays a very important role in these systems.

For the purpose of technical research and teaching a curriculum, I have developed a monolithic-kernel SBC GNU/Linux-like OS on the ARM platform. The article covers a boot loader design called U-boot, building the kernel – uImage, the design of the root file system and the Init process. The single board computer OS (SBC OS) is developed on the Linux platform with the GNU tool chain. The system mainly focuses on helping students to learn about and design tiny operating systems on the ARM platform from scratch when the source code is provided.

Figure 1

Figure 1: Architecture of SBC OS

Figure 2

Figure 2: Storage of the boot loader, kernel and root file system in the ROM memory (flash)

Architecture of the SBC OS
At the top of the SBC OS is the user or application space where user applications are executed. Below the user space is the kernel space, where the SBC OS kernel resides.

The SBC OS also contains a GNU C library (glibc), which provides the system call interface that connects to the SBC OS kernel and provides the mechanism for the transition between the user or application space and the SBC OS kernel. This is important because the kernel and the user application occupy different protected address spaces. While each user or application space process occupies its own virtual address space, the SBC OS kernel occupies a single address space.

The SBC OS kernel can be further divided into three levels. At the top is the system call interface, which implements the basic functions such as read and write. Below the system call interface is the SBC OS kernel code, which can be more accurately defined as the architecture-independent kernel code. This code is common to all of the processor architectures supported by the SBC OS. Below this is the architecture-dependent code, which forms what is more commonly called a BSP (board support package). This code serves as the processor and platform-specific code for the given architecture.

Design and implementation
The U-boot boot loader design
U-boot is an open source, cross-platform boot loader that provides out-of-the-box support for hundreds of SBCs and many CPUs, including PowerPC, ARM, XScale, MIPS, Coldfire, NIOS, Microblaze and x86.

The SBC OS normally resides in large-capacity devices such as hard disks, CD-ROMs, USB disks, network servers and other permanent storage media. When the processor is powered on, the memory does not hold an operating system, so special software is needed to bring the SBC OS into the memory from the media on which it resides. This software is normally a small piece of code called the boot loader. On a desktop PC, the boot loader resides on the master boot record (MBR) of the hard drive and is executed after the PC’s basic input output system (BIOS) performs system initialisation tasks. In a SBC, the boot loader’s role is more complicated because these systems rarely have a BIOS to perform initial system configuration.

At the very minimum, a boot loader for the SBC OS performs these functions:

  • Initialises the hardware, especially the memory controller
  • Provides boot parameters for the SBC OS
  • Starts the SBC OS

Compiling the boot loader
Boot loader compilation for the SBC OS can be done using the following command:

$ make clean && make cubietruck CROSS_COMPILE-arm-linux-gnueabihf-

Building the kernel – uImage
The kernel is the most fundamental software component of the SBC OS. It is responsible for managing the bare hardware within the chosen target system and bringing order to what would otherwise be a chaotic struggle between each of the many different software components on a typical system.

Figure-3

Figure 3: Snapshot of Menuconfig

Configuring the kernel
The options that we need in the kernel have to be configured before building it. The target is to have an appropriate .config file in our Kernel source distribution. Depending on our target, the option menus available will change, as will their content. Some options, however, will be available no matter which embedded architecture we choose. After the environmental set-up, make menuconfig runs a text-based menu interface as shown in Figure 3.

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig

<*> indicates that the feature is on
<M> indicates that the feature is configured as mobile
< > indicates that the feature is off
Figure-4

Figure 4: Snapshot of SBC OS kernel compilation – ulmage

Compiling the kernel and modules
After saving the kernel configuration in the kernel root directory, our main goals are to compile the uImage compressed kernel and uImage kernel modules for the SBC OS using the following commands:

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage –j4
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules –j4

Installing modules
Before we install and boot from our new SBC OS kernel, we should put the new kernel modules in /lib/modules with the following command:

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules_install

Our new modules should appear in /lib/modules/version, where the version is the new kernel version of the SBC OS.

Figure 5 The Cubietruck SBC

Figure 5: The cubietruck SBC

Designing the root file system
One of the last operations conducted by the Linux kernel during system start-up is mounting the root file system. The Linux kernel itself doesn’t dictate any file system structure, but user space applications do expect to find files with specific names in specific directory structures. Therefore, it is useful to follow the de facto standards that have emerged in Linux systems.

$ debootstrap --no-check-gpg --arch=armhf --foreign wheezy

The Init process and runlevels
In conventional Linux systems, Init is the first process started when a Linux kernel boots and it’s the ancestor of all processes. Its primary role is to start appropriate service processes for the ‘state’ the system is to run in at boot and to shut down or start appropriate services if the system state changes (such as changing to the halt/shut down state). It can also create consoles and respond to certain types of events.
Init’s behaviour is determined by its configuration file /etc/inittab. Lines in /etc/inittab have the following syntax:

id:runlevels:action:process
where:
id — 1–4 (usually 2) character name for the line, totally arbitrary;
runlevels — a list of runlevels the line applies to;
action — what init is to do and/or under what conditions;
process — program/command to be run.

Here are the typical runlevels and what they mean for Red Hat family distros:

0 — halt system
1 — single user mode (no GUI)
2 — multiuser mode, no networking (no GUI)
3 — multiuser mode, networking (no GUI)
4 — unused
5 — multiuser mode (GUI/X11) //FUTURE WORK
6 — reboot system

A demo of the SBC OS and the single board computer called Cubietruck

FOSSOF 1.0 (Free and Open Source SOFtware) is a SBC OS that can be obtained from http://github.com/gselvapravin/FossoF. Developed by yours truly, it can be cloned by using the following commands:

$ sudo apt-get –y install git
$ cd ~
$ git clone https://github.com/gselvapravin/FossoF
$ chmod +x ./FossoF/fossof.sh
$ cd ./FossoF
$ ./fossof.sh

The compiled image will be located in /tmp/FossoF/output/debian_rootfs.raw.gz. To write it to an SD card, decompress it and use Image Writer (Windows) or DD-it in Linux by using the following command:

$ dd bs=1M if FossoF_x.x_vga.raw of=/dev/sdx

Cubietruck is an SBC and is the third board of Cubieteam; so it is also called Cubieboard3. It’s a new PCB model adopted with the Allwinner A20 main chip, just like Cubieboard2. But it is enhanced with some features, such as 2GB memory, an on-board VGA display interface, 1000M network interface, Wi-Fi+BT on board, support for Li batteries and RTC, and the SPDIF audio interface.