Custom Linux Kernel Development
The ability to easily customize and expand any portion of the kernel is a feature of Linux that makes it very well suited for embedded systems development. In the embedded environment, specialized hardware, protocols, and systems may require a look into the kernel internals, custom configuration, feature additions, or driver development. This article aims to provide information on the most common kernel development tasks for EMAC OE Linux systems. In addition, the reader is pointed to sources for kernel development resources.
Contents
Prerequisites
This article assumes some basic familiarity with Linux and C programming competency. Before continuing, make sure that git is installed on your development machine, and review the Building the Linux Kernel document.
Background
Maybe some more here about the technical design of the kernel and very brief history... monolithic kernel, loadable modules, etc. For now just see wikipedia http://en.wikipedia.org/wiki/Linux_kernel
The Kernel Source
Source code for EMAC kernels is provided through our Git server. Refer to the documentation for your system to determine the correct source to use.
For this guide, the 2.6.30-at91 kernel tree will be used, which currently covers many of EMAC's SoM-based ARM products. |
Clone the Git Repository
To clone the git repository over anonymous HTTP, run the following commands:
developer@ldc:~$ git clone http://git.emacinc.com/public/source/linux-2.6.30-at91.git
Once the command has completed, the entire source should be contained in the linux-2.6.30-at91
directory. The master branch will be checked out automatically. Because EMAC uses the master branch for all releases, this is the correct branch to use, but other branches or tags may be checked out if directed or required.
Kernel Source Structure
Within the kernel source tree that was downloaded, you will see several directories. Table 1 gives a brief description of each of these directories.
Directory name | Description |
---|---|
arch |
Architecture-specific kernel code with subdirectories for each architecture |
block |
Block device driver code |
crypto |
Encryption support algorithms |
Documentation |
Text documentation files on the kernel and APIs |
drivers |
Device driver code, with a subdirectory structure for each device type |
firmware |
Code for building firmware required to communicate with devices |
fs |
File systems code |
include |
Include (header) files required to build the kernel code |
init |
Kernel initialization code |
ipc |
Interprocess communications code |
kernel |
Main internal kernel code |
lib |
Library code |
mm |
Memory management code |
net |
Kernel networking code |
samples |
Code examples and drivers that have not been fully developed |
scripts |
Various scripts used for the configuration and build process as well as standalone utility scripts |
security |
Kernel security support |
sound |
Sound and audio driver code |
usr |
Code used during kernel image creation |
virt |
Virtualization support code |
These directories will be referred to as needed in this document.
Configuration
The kernel uses a configuration system that specifies how every aspect of the kernel is built.
Configuration Structure
The kernel configuration is generated based on selections by the user combined with dependency information built into the Kconfig structure. You will find a file named Kconfig
in most source directories within the kernel. These files follow the language described in Documentation/kbuild/kconfig-language.txt
and control the structure and operation of the kernel configuration utility.
The current kernel configuration is stored in a file named .config
in the top level of the kernel source tree. This file is read and updated by the configuration utility and is used by the make system during the build process. The first step in configuring the kernel often involves initializing this file with a default configuration set up with sane values for the target platform. These default configuration files are stored under the arch
directory. For example, arch/arm/configs/
.
Note that the .config file is a hidden file since its filename begins with a '.' . The ls utility will not show this file by default unless the -a option is passed to show hidden files. |
In this example, copy the arch/arm/configs/som9g45-som210_defconfig
file to the top level of the kernel source as .config
:
developer@ldc:~$ cp arch/arm/configs/som9g45-som210_defconfig .config
This is the default configuration file for the EMAC SoM-9G45 module using an SoM-210ES carrier board.
The configuration file defines all CONFIG
values that are set, either y (yes), m (module), a numeric value, or a string value. Options not configured are entered into the file as a comment with the option followed by the words "is not set." An example of each of these formats is shown below:
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.30
# Tue Jan 10 17:42:58 2012
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
# CONFIG_NO_IOPORT is not set
...
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
...
CONFIG_INIT_ENV_ARG_LIMIT=32
...
CONFIG_SDIO_UART=m
While editing the configuration file by hand is not recommended because it is easy to break dependencies that the configuration utility will catch, viewing the configuration file as text can be helpful in quickly viewing the current configuration selections. |
Configuring the Kernel
The kernel supports several methods of generating configuration values including command line utilities, a menu-based utility, a Qt-based utility, and a GTK+-based utility. These utilities are instantiated as make
targets. The menu-based utility, invoked by the menuconfig command is the only option supported by the EMAC Linux kernel build script. See here for more information on how to initiate the configuration process using the EMAC Linux kernel build script.
Menuconfig
The top-level interface to the kernel menuconfig utility is shown in Figure 1. Note that the navigation keys and legend are shown at the top of the page.
Any menu item with a ---> will lead to a submenu with further options. For example, to set the EMAC carrier board used with this SoM, you would use the arrow keys to highlight System Type and press Enter to select. From this menu, select Atmel AT91 System-on-Chip followed by EMAC Carrier Board Selection. This will initiate a menu allowing a single selection with all of the carrier boards supported by the currently selected SoM module. If, for example, you wanted to target the SoM-200ES carrier board, you could highlight SOM-200ES Carrier Support and press the space bar or Enter to select.
Once all desired changes have been made, select Exit and press enter from the main menu. You will be prompted to save the kernel configuration as shown in Figure 2.
If configuration options are the only customization required for your project, you may continue by building the kernel. If only loadable module options were changed from the original configuration that your running kernel was built with, you will only need to load the modules onto the target system as described here. If other built-in options were modified, you will need to reload the kernel image as well, which requires a different procedure depending on the bootloader. More here links for different bootloaders
Adding Support for a new Carrier Board
Show how to add a carrier board in the 2.6.30 "emac-carrier" structure.
Driver Development
Basic info on driver structure here.
Licensing
It is important to note that all code built-in to the kernel automatically fall under the the GPLv2 license and must use an Open Source license compatible with the terms of the GPL. For loadable kernel modules, there is controversy over whether modules are derived works of the kernel. While proprietary and other non-GPL-compatible modules are generally permitted, several restrictions apply: The "taint" flag will be set on the kernel as soon as the module is loaded, and certain symbols are only available to modules marked with a GPL-compatible license.
EMAC recommends that you seek legal advice if you are unsure of the license requirements for your software.
See the following resources for more information:
Where to go for Additional Information
There is an abundance of information available both online and in-print on the topic of Linux kernel development. Some of these resources are discussed below.
- Kernel.org
- Kernel.org is the site hosting the Linux kernel. Source code, news, links, and other helpful information related to the Linux kernel can be found on this site.
- Linux Device Drivers, Third Edition (LDD3)
- This book is available online in free PDF form through the LWN.net site. It is also available in-print through O'Reilly. LDD3 covers most of the topics required for Linux kernel development and includes examples. Note that some of the APIs covered have changed since 2.6.10 when the book was written so adaptation may be required to use the example code.
- Mailing Lists
- There are many very active mailing lists (see http://vger.kernel.org/vger-lists.html) that can be used to ask questions or search through archives for solutions. The archive of the Linux Kernel mailing list is available at LKML.org and archives to other lists can be found through a web search as well as links noted in the list here.
- Linux Kernel in a Nutshell
- This book is written by Greg Kroah-Hartman, one of the primary developers and maintainers of the kernel and covers the process and tools for building, configuration, and installation of the Linux kernel. It is available for free through the authors site in electronic format or in-print through O'Reilly.
- EMAC Support
- EMAC provides custom Linux kernel development and kernel development support for EMAC customers on a contractual basis. Contact EMAC Support for more information.
LDD3, mailing list, EMAC support.