DEV Community

Can Gulmez
Can Gulmez

Posted on

Embedded Linux Development - Part 3

In this tutorial, I'll go with the third stage of embedded Linux development. That's the Linux kernel.

It's the responsible for:

  • Manage all the hardware resources: CPU, memory, I/O.

  • Provide a set of portable, architecture and hardware independent APIs to allow user space applications and libraries to use the hardware resources.

  • Handle concurrent accesses and usage of hardware resources set of system calls.

The kernel provides about 400 system calls that provide the services like opening the disk file, forking the new process, managing the memory or so on. These system calls are defined in /usr/include/x86_64-linux-gnu/asm/unistd.h like:

#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4
#define __NR_fstat 5
#define __NR_lstat 6
#define __NR_poll 7
#define __NR_lseek 8
#define __NR_mmap 9
#define __NR_mprotect 10
#define __NR_munmap 11
#define __NR_brk 12

(...)
Enter fullscreen mode Exit fullscreen mode

In user-space applications, we generally don't use these system calls directly. These system calls are wrapped by the standard POSIX C library. If you're a programmer, you already know it.

Let's start with downloading Linux kernel:

$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Enter fullscreen mode Exit fullscreen mode

I have the 6.14 kernel (slightly older, but doesn't matter). As you see that the kernel contains thousands of device drivers, filesystem drivers, network protocols and other configurable items.

As I did previously at u-boot stage, the first thing is to configure the kernel according to BeagleBone Black over configuration files (ends with _defconfig).

Which configuration file should be used for BeagleBone Black? It's omap2plus_defconfig under linux/arch/arm/configs (OMAP is the processor family including the AM335x Sitara processor by TI).

So let's configure the kernel:

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- omap2plus_defconfig
Enter fullscreen mode Exit fullscreen mode

It will create the .config and write the associated configs in it.

As I said, this configuration file includes the generic AM335x Sitara processor configs. To customize and tailor the kernel further:

$ make menuconfig # or xconfig (for Qt-based)
Enter fullscreen mode Exit fullscreen mode

It will open the terminal-based GUI window to select/unselect the configurable items like:

If you're unfamiliar or newer, I DON'T recommend it. But I need to make an important configuration in here about the USB gadget support. As I will explain in the next tutorail, I wanna use the ssh command to make connection with BeagleBone Black. If you don't make it, you're totally free.

Navigate to Device Drivers --> USB Support --> USB Gadget Support --> USB Gadget precomposed configurations --> Ethernet Gadget (with CDC Ethernet support), type "M" and then exit by saving. It will create the virtual USB link so that I can use the ssh command to connect to BeagleBone Black. I will explain it in the last tutorial in detail.

By the way, you will see the "*" and "M" marks as you navigate the configs. "*" means that the configs will be embedded into the kernel image, while "M" means that the configs is built as modules. These are plugins that can be loaded/unloaded dynamically at runtime to the kernel.

After configured the kernel, for now, you're ready to build the required outputs.

Which outputs exactly should be built from the kernel source? Three things:

  • zImage

  • am335x-boneblack.dtb

  • kernel modules

zImage is the compressed the Linux kernel image. am335x-boneblack.dtb is the device tree blob that describes the hardware connected to the kernel. The kernel modules also are being compiled externally, not embedded into the kernel image.

In here, I have to explain the device tree concept. It's the description of the hardware that the kernel manages at runtime. As you expect, the kernel must know the hardware that it will manage. It's written generally by the processor vendor or development board engineers. The device tree corresponding to BeagleBone Black is the am335x-boneblack.dts under linux/arch/arm/boot/dts/ti/omap.

To produces these outputs:

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc) zImage dtbs modules
Enter fullscreen mode Exit fullscreen mode

It will take for a while (~1 hours in my case). After that you will see the zImage under linux/arch/arm/boot and am335x-boneblack.dtb under linux/arch/arm/boot/dts/ti/omap.

The kernel modules are compiled ending with .ko suffix. After the rootfs is being created, I will install these kernel modules in it:

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

But DON'T do it for now. I need to create a rootfs firstly and then install the kernel modules in there. I will show it in the next tutorial.

That's it. I've produced the three essential components from the kernel source: zImage, am335x-boneblack.dtb, and kernel modules. In the next tutorial, I will interest with the rootfs.

Resources:

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

Top comments (0)