Embedded Linux device drivers

Kernel device drivers expose the underlying hardware to the rest of the system. Devices running embedded Linux or Android almost always need to interface with novel configurations of hardware, and so it is often necessary for engineers working in the embedded and Android space to be familiar with the device driver infrastructure within the Linux kernel.

This four day course contains the background information necessary to be able to write, configure and debug device driver code. Throughout, there is an emphasis on the techniques that are applicable to embedded systems such as platform independence, cross development and efficient use of resources. Approximately 50% of the course is dedicated to practical exercises, which are cross-compiled and tested on a BeagleBone Black ARM-based development board

Download course details as a PDF
Click here for information about booking a course

Duration

4 days

Upcoming courses

None scheduled: contact us to request a quote

Prerequisites

Essential

  • good understanding of the C language
  • familiarity with Linux development and command-line tools such as make

Recommended

  • a good background in embedded devices

Course materials

All students will receive:

  • A printed copy of the presentations and lab notes
  • A USB flash drive containing worked solutions to the problems, plus electronic copies of the course materials
  • A free copy of the trainer's book, “Mastering Embedded Linux Programming”

Hands-on labs

An essential part of the training are the lab sessions, which take approximately 50% of the time. We normally work in pairs using a modern development board such as the BeagleBone. Each group will also need a laptop or desktop to run the system development tools. We will provide a bootable USB memory stick with an appropriate version of Linux and cross tool-chain so there is no need to install Linux beforehand.

Outline

Linux kernel programming

  • User space vs kernel space
  • Kernel coding guidelines

The Linux kernel

  • Getting get the source code for mainline and vendor kernels
  • Kernel configuration options
  • Building and booting a kernel

Kernel modules

  • Writing a module and compiling "out of tree"
  • Passing parameters
  • Modules and the GPL license

Device driver basics

  • Different ways that applications interact with a driver
  • Device nodes: major and minor numbers
  • Building and testing a simple character device driver

Kernel debugging

  • Review of printk and the magic sysrq key
  • Decoding a kernel panic
  • Interactive debugging using kgdb

The Linux driver model

  • Understanding the elements of the driver model: device; bus; driver; class
  • Using a device manager to populate /dev

Device Trees

  • Describing hardware using device trees
  • Using overlays to extend a device tree

Platform Drivers

  • Binding devices to drivers
  • The platform bus
  • Platform data

Wait queues

  • Waiting for things to happen
  • Sleeping and waking

Kernel locking

  • The challenges of concurrent programming
  • Mutual exclusion using kernel mutexes and spinlocks
  • Atomic operations

Interrupts

  • Installing an interrupt handler
  • Interrupt context and synchronisation issues
  • Deferred processing using work queues

Time and timers

  • Getting the system time
  • Delays and sleeps
  • Kernel timers and high resolution timers

Memory management

  • Memory regions
  • Allocating and freeing memory
  • Understanding paged memory
  • Using mmap to map memory into user space

Accessing hardware

  • Extracting information from a device tree
  • Mapping in device memory using ioremap
  • DMA buffers: coherent and stream mappings
  • Memory barriers

Hardware buses

  • The role of the bus in the device model
  • Examples: I2C bus and USB