Linux Device Drivers Development

Book description

Learn to develop customized device drivers for your embedded Linux system

About This Book

  • Learn to develop customized Linux device drivers
  • Learn the core concepts of device drivers such as memory management, kernel caching, advanced IRQ management, and so on.
  • Practical experience on the embedded side of Linux

Who This Book Is For

This book will help anyone who wants to get started with developing their own Linux device drivers for embedded systems. Embedded Linux users will benefit highly from this book.

This book covers all about device driver development, from char drivers to network device drivers to memory management.

What You Will Learn

  • Use kernel facilities to develop powerful drivers
  • Develop drivers for widely used I2C and SPI devices and use the regmap API
  • Write and support devicetree from within your drivers
  • Program advanced drivers for network and frame buffer devices
  • Delve into the Linux irqdomain API and write interrupt controller drivers
  • Enhance your skills with regulator and PWM frameworks
  • Develop measurement system drivers with IIO framework
  • Get the best from memory management and the DMA subsystem
  • Access and manage GPIO subsystems and develop GPIO controller drivers

In Detail

Linux kernel is a complex, portable, modular and widely used piece of software, running on around 80% of servers and embedded systems in more than half of devices throughout the World. Device drivers play a critical role in how well a Linux system performs. As Linux has turned out to be one of the most popular operating systems used, the interest in developing proprietary device drivers is also increasing steadily.

This book will initially help you understand the basics of drivers as well as prepare for the long journey through the Linux Kernel. This book then covers drivers development based on various Linux subsystems such as memory management, PWM, RTC, IIO, IRQ management, and so on. The book also offers a practical approach on direct memory access and network device drivers.

By the end of this book, you will be comfortable with the concept of device driver development and will be in a position to write any device driver from scratch using the latest kernel version (v4.13 at the time of writing this book).

Style and approach

A set of engaging examples to develop Linux device drivers

Table of contents

  1. Title Page
  2. Copyright
    1. Linux Device Drivers Development
  3. Credits
  4. About the Author
  5. About the Reviewer
  6. www.PacktPub.com
    1. Why subscribe?
  7. Customer Feedback
  8. Dedication
  9. Preface
    1. What this book covers
    2. What you need for this book
    3. Who this book is for
    4. Conventions
    5. Reader feedback
    6. Customer support
      1. Downloading the example code
      2. Downloading the color images of this book
      3. Errata
      4. Piracy
      5. Questions
  10. Introduction to Kernel Development
    1. Environment setup
      1. Getting the sources
        1. Source organization
      2. Kernel configuration
      3. Building your kernel
    2. Kernel habits
      1. Coding style
      2. Kernel structure allocation/initialization
      3. Classes, objects, and OOP
    3. Summary
  11. Device Driver Basis
    1. User space and kernel space
      1. The concept of modules
      2. Module dependencies
        1. depmod utility
      3. Module loading and unloading
        1. Manual loading
          1. modprobe and insmod
          2. /etc/modules-load.d/<filename>.conf
        2. Auto-loading
        3. Module unload
    2. Driver skeletons
      1. Module entry and exit point
        1. __init and __exit attributes
      2. Module information
        1. Licensing
        2. Module author(s)
        3. Module description
    3. Errors and message printing
      1. Error handling
      2. Handling null pointer errors
      3. Message printing – printk()
    4. Module parameters
    5. Building your first module
      1. The module's makefile
      2. In the kernel tree
      3. Out of the tree
      4. Building the module
    6. Summary
  12. Kernel Facilities and Helper Functions
    1. Understanding the container_of macro
    2. Linked lists
      1. Creating and initializing a list
        1. Dynamic method
        2. Static method
      2. Creating a list node
      3. Adding a list node
      4. Deleting a node from the list
      5. Linked list traversal
    3. The kernel sleeping mechanism
      1. Wait queue
    4. Delay and timer management
      1. Standard timers
        1. Jiffies and HZ
        2. The timer API
          1. Timer setup initialization
          2. Standard timer example
      2. High-resolution timers (HRTs)
        1. HRT API
          1. HRT setup initialization
      3. Dynamic tick/tickless kernel
      4. Delays and sleep in the kernel
        1. Atomic context
        2. Nonatomic context
    5. Kernel locking mechanism
      1. Mutex
        1. Mutex API
          1. Declare
          2. Acquire and release
      2. Spinlock
        1. Spinlock versus mutexes
    6. Work deferring mechanism
      1. Softirqs and ksoftirqd
        1. ksoftirqd
      2. Tasklets
        1. Declaring a tasklet
        2. Enabling and disabling a tasklet
      3. Tasklet scheduling
      4. Work queues
        1. Kernel-global work queue – the shared queue
        2. Dedicated work queue
          1. Programming syntax
        3. Predefined (shared) workqueue and standard workqueue functions
      5. Kernel threads
    7. Kernel interruption mechanism
      1. Registering an interrupt handler
        1. Interrupt handler and lock
      2. Concept of bottom halves
        1. The problem – interrupt handler design limitations
        2. The solution – bottom halves
        3. Tasklets as bottom halves
        4. Workqueue as bottom halves
        5. Softirqs as bottom half
    8. Threaded IRQs
      1. Threaded bottom half
    9. Invoking user space applications from the kernel
    10. Summary
  13. Character Device Drivers
    1. The concept behind major and minor
      1. Device number allocation and freeing
    2. Introduction to device file operations
      1. File representation in the kernel
    3. Allocating and registering a character device
    4. Writing file operations
      1. Exchanging data between kernel space and user space
        1. A single value copy
      2. The open method
        1. Per-device data
      3. The release method
      4. The write method
        1. Steps to write
      5. The read method
        1. Steps to read
      6. The llseek method
        1. Steps to llseek
      7. The poll method
        1. Steps to poll
      8. The ioctl method
        1. Generating ioctl numbers (command)
        2. Steps for ioctl
      9. Filling the file_operations structure
    5. Summary
  14. Platform Device Drivers
    1. Platform drivers
    2. Platform devices
      1. Resources and platform data
        1. Device provisioning – the old and deprecated way
          1. Resources
          2. Platform data
          3. Where to declare platform devices?
        2. Device provisioning – the new and recommended way
    3. Devices, drivers, and bus matching
      1. How can platform devices and platform drivers match?
        1. Kernel devices and drivers-matching function
          1. OF style and ACPI match
          2. ID table matching
          3. Per device-specific data on ID table matching
          4. Name matching – platform device name matching
    4. Summary
  15. The Concept of a Device Tree
    1. Device tree mechanisms
      1. Naming convention
      2. Aliases, labels, and phandle
      3. DT compiler
    2. Representing and addressing devices
      1. SPI and I2C addressing
      2. Platform device addressing
    3. Handling resources
      1. Concept of named resources
      2. Accessing registers
      3. Handling interrupts
        1. The interrupt handler
        2. Interrupt controller code
      4. Extract application-specific data
        1. Text string
        2. Cells and unsigned 32-bit integers
        3. Boolean
        4. Extracting and parsing sub-nodes
    4. Platform drivers and DTs
      1. OF match style
        1. Dealing with non-device tree platforms
        2. Support multiple hardware devices with per device-specific data
      2. Match style mixing
        1. Platform resources and DTs
      3. Platform data versus DTs
    5. Summary
  16. I2C Client Drivers
    1. The driver architecture
      1. The i2c_driver structure
        1. The probe() function
          1. Per-device data
        2. The remove() function
      2. Driver initialization and registration
      3. Driver and device provisioning
    2. Accessing the client
      1. Plain I2C communication
      2. System Management Bus (SMBus) compatible functions
      3. Instantiating I2C devices in the board configuration file (old and deprecated way)
    3. I2C and device trees
      1. Defining and registering the I2C driver
        1. Remark
      2. Instantiating I2C devices in a DT – the new way
      3. Putting it all together
    4. Summary
  17. SPI Device Drivers
    1. The driver architecture
      1. The device structure
      2. spi_driver structure
        1. The probe() function
          1. Per-device data
        2. The remove() function
      3. Driver initialization and registration
      4. Driver and device provisioning
        1. Instantiating SPI devices in board configuration file – old and deprecated way
        2. SPI and device tree
          1. Instantiate SPI devices in device tree – the new way
          2. Define and register SPI driver
    2. Accessing and talking to the client
    3. Putting it all together
    4. SPI user mode driver
      1. With IOCTL
    5. Summary
  18. Regmap API - A Register Map Abstraction
    1. Programming with the regmap API
      1. regmap_config structure
      2. regmap initialization
        1. SPI initialization
        2. I2C initialization
      3. Device access functions
        1. regmap_update_bits function
        2. Special regmap_multi_reg_write function
        3. Other device access functions
      4. regmap and cache
      5. Putting it all together
      6. A regmap example
    2. Summary
  19. IIO Framework
    1. IIO data structures
      1. iio_dev structure
      2. iio_info structure
      3. IIO channels
        1. Channel attribute naming conventions
          1. Distinguishing channels
      4. Putting it all together
    2. Triggered buffer support
      1. IIO trigger and sysfs (user space)
        1. Sysfs trigger interface
          1. add_trigger file
          2. remove_trigger file
          3. Tying a device with a trigger
        2. The interrupt trigger interface
        3. The hrtimer trigger interface
      2. IIO buffers
        1. IIO buffer sysfs interface
        2. IIO buffer setup
      3. Putting it all together
    3. IIO data access
      1. One-shot capture
      2. Buffer data access
        1. Capturing using the sysfs trigger
        2. Capturing using the hrtimer trigger
    4. IIO tools
    5. Summary
  20. Kernel Memory Management
    1. System memory layout – kernel space and user space
      1. Kernel addresses – concept of low and high memory
        1. Low memory
        2. High memory
      2. User space addresses
      3. Virtual memory area (VMA)
    2. Address translation and MMU
      1. Page lookup and TLB
        1. How does the TLB work?
    3. Memory allocation mechanism
      1. Page allocator
        1. Page allocation API
        2. Conversion functions
      2. Slab allocator
        1. The buddy algorithm
        2. A journey into the slab allocator
      3. kmalloc family allocation
      4. vmalloc allocator
      5. Process memory allocation under the hood
        1. The copy-on-write (CoW) case
    4. Working with I/O memory to talk with hardware
      1. PIO devices access
      2. MMIO device access
        1. __iomem cookie
    5. Memory (re)mapping
      1. kmap
      2. Mapping kernel memory to user space
        1. Using remap_pfn_range
        2. Using io_remap_pfn_range
        3. The mmap file operation
          1. Implementing mmap in the kernel
    6. Linux caching system
      1. What is a cache?
        1. CPU cache – memory caching
        2. The Linux page cache – disk caching
        3. Specialized caches (user space caching)
      2. Why delay writing data to disk?
        1. Write caching strategies
          1. The flusher threads
    7. Device-managed resources – Devres
    8. Summary
  21. DMA - Direct Memory Access
    1. Setting up DMA mappings
      1. Cache coherency and DMA
      2. DMA mappings
        1. Coherent mapping
        2. Streaming DMA mapping
          1. Single-buffer mapping
          2. Scatter/gather mapping
    2. The concept of completion
    3. The DMA engine API
      1. Allocating a DMA slave channel
      2. Setting slave- and controller-specific parameters
      3. Getting a descriptor for transaction
      4. Submitting the transaction
      5. Issuing pending DMA requests and waiting for callback notification
    4. Putting it all together – NXP SDMA (i.MX6)
    5. DMA DT binding
      1. Consumer binding
    6. Summary
  22. The Linux Device Model
    1. LDM data structures
      1. The bus
        1. Bus registration
      2. The device driver
        1. Device driver registration
      3. The device
        1. Device registration
    2. Deep inside LDM
      1. kobject structure
      2. kobj_type
      3. ksets
      4. Attributes
        1. The attributes group
    3. The device model and sysfs
      1. Sysfs files and attributes
        1. Current interfaces
          1. Device attributes
          2. Bus attributes
          3. Device driver attributes
          4. Class attributes
      2. Allowing sysfs attribute files to be pollable
    4. Summary
  23. Pin Control and GPIO Subsystem
    1. The pin control subsystem
      1. Pinctrl and the device tree
    2. The GPIO subsystem
      1. The integer-based GPIO interface – legacy
        1. Claiming and configuring the GPIO
        2. Accessing the GPIO – getting/setting the value
          1. In atomic context
          2. In a non-atomic context (that may sleep)
        3. GPIOs mapped to IRQ
        4. Putting it all together
      2. The descriptor-based GPIO interface – the new and recommended way
        1. GPIO descriptor mapping - the device tree
        2. Allocating and using GPIO
        3. Putting it all together
      3. The GPIO interface and the device tree
        1. The legacy integer-based interface and device tree
        2. GPIO mapping to IRQ in the device tree
      4. GPIO and sysfs
        1. Exporting a GPIO from kernel code
    3. Summary
  24. GPIO Controller Drivers - gpio_chip
    1. Driver architecture and data structures
    2. Pin controller guidelines
    3. Sysfs interface for GPIO controller
    4. GPIO controllers and the DT
    5. Summary
  25. Advanced IRQ Management
    1. Multiplexing interrupts and interrupt controllers
    2. Advanced peripheral IRQ management
    3. Interrupt request and propagation
      1. Chaining IRQs
        1. Chained interrupts
        2. Nested interrupts
      2. A case study – the GPIO and IRQ chip
        1. The legacy GPIO and IRQ chip
        2. The new gpiolib irqchip API
        3. The interrupt controller and DT
    4. Summary
  26. Input Devices Drivers
    1. Inputting device structures
    2. Allocating and registering an input device
      1. The polled input device sub-class
    3. Generating and reporting an input event
    4. The user space interface
    5. Putting it all together
      1. Driver examples
    6. Summary
  27. RTC Drivers
    1. RTC framework data structures
      1. RTC API
        1. Reading and setting time
          1. Driver example
        2. Playing with alarms
    2. RTCs and user space
      1. The sysfs interface
      2. The hwclock utility
    3. Summary
  28. PWM Drivers
    1. PWM controller driver
      1. Driver example
      2. PWM controller binding
    2. The PWM consumer interface
      1. PWM client binding
    3. Using PWMs with the sysfs interface
    4. Summary
  29. Regulator Framework
    1. PMIC/producer driver interface
      1. Driver data structures
        1. Description structure
        2. Constraints structure
        3. init data structure
          1. Feeding init data into a board file
          2. Feeding init data into the DT
        4. Configuration structure
        5. Device operation structure
      2. Driver methods
        1. The probe function
        2. The remove function
        3. Case study – Intersil ISL6271A voltage regulator
      3. Driver example
    2. Regulators consumer interface
      1. Regulator device requesting
      2. Controlling the regulator device
        1. Enabling and disabling regulator output
        2. Voltage control and status
        3. Current limit control and status
        4. Operating mode control and status
    3. Regulator binding
    4. Summary
  30. Framebuffer Drivers
    1. Driver data structures
    2. Device methods
    3. Driver methods
      1. Detailed fb_ops
        1. Checking information
        2. Setting the controller's parameters
        3. Screen blanking
        4. Accelerated methods
      2. Putting it all together
    4. Framebuffer from user space
    5. Summary
  31. Network Interface Card Drivers
    1. Driver data structures
      1. The socket buffer structure
        1. Socket buffer allocation
      2. Network interface structure
    2. Device methods
      1. Opening and closing
      2. Packet handling
        1. Packet reception
        2. Packet transmission
      3. Driver example
      4. Status and control
        1. The interrupt handler
        2. Ethtool support
    3. Driver methods
      1. The probe function
      2. Module unloading
    4. Summary

Product information

  • Title: Linux Device Drivers Development
  • Author(s): John Madieu
  • Release date: October 2017
  • Publisher(s): Packt Publishing
  • ISBN: 9781785280009