You are previewing Linux Device Drivers, Second Edition.
O'Reilly logo
Linux Device Drivers, Second Edition

Book Description

This book is for anyone who wants to support computer peripherals under the Linux operating system or who wants to develop new hardware and run it under Linux. Linux is the fastest-growing segment of the Unix market, is winning over enthusiastic adherents in many application areas, and is being viewed more and more as a good platform for embedded systems. Linux Device Drivers, already a classic in its second edition, reveals information that heretofore has been shared by word of mouth or in cryptic source code comments, on how to write drivers for a wide range of devices. Version 2.4 of the Linux kernel includes significant changes to device drivers, simplifying many activities, but providing subtle new features that can make a driver both more efficient and more flexible. The second edition of this book thoroughly covers these changes, as well as new processors and buses. You don't have to be a kernel hacker to understand and enjoy this book; all you need is an understanding of C and some background in Unix system calls. You'll learn how to write drivers for character devices, block devices, and network interfaces, guided by full-featured examples that you can compile and run without special hardware. Major changes in the second edition include discussions of symmetric multiprocessing (SMP) and locking, new CPUs, and recently supported buses. For those who are curious about how an operating system does its job, this book provides insights into address spaces, asynchronous events, and I/O. Portability is a major concern in the text. The book is centered on version 2.4, but includes information for kernels back to 2.0 where feasible. Linux Device Driver also shows how to maximize portability among hardware platforms; examples were tested on IA32 (PC) and IA64, PowerPC, SPARC and SPARC64, Alpha, ARM, and MIPS. Contents include:

  • Building a driver and loading modules

  • Complete character, block, and network drivers

  • Debugging a driver

  • Timing

  • Handling symmetric multiprocessing (SMP) systems

  • Memory management and DMA

  • Interrupts

  • Portability issues

  • Peripheral Component Interconnect (PCI)

  • Table of Contents

    1. Linux Device Drivers, 2nd Edition
      1. Preface
        1. Alessandro’s Introduction
        2. Jon’s Introduction
        3. Audience of This Book
        4. Organization of the Material
        5. Background Information
        6. Sources of Further Information
        7. Online Version and License
        8. Conventions Used in This Book
        9. We’d Like to Hear from You
        10. Acknowledgments
      2. 1. An Introduction to Device Drivers
        1. The Role of the Device Driver
        2. Splitting the Kernel
        3. Classes of Devices and Modules
        4. Security Issues
        5. Version Numbering
        6. License Terms
        7. Joining the Kernel Development Community
        8. Overview of the Book
      3. 2. Building and Running Modules
        1. Kernel Modules Versus Applications
          1. User Space and Kernel Space
          2. Concurrency in the Kernel
          3. The Current Process
        2. Compiling and Loading
          1. Version Dependency
          2. Platform Dependency
        3. The Kernel Symbol Table
        4. Initialization and Shutdown
          1. Error Handling in init_module
          2. The Usage Count
          3. Unloading
          4. Explicit Initialization and Cleanup Functions
        5. Using Resources
          1. I/O Ports and I/O Memory
            1. Ports
            2. Memory
          2. Resource Allocation in Linux 2.4
        6. Automatic and Manual Configuration
        7. Doing It in User Space
        8. Backward Compatibility
          1. Changes in Resource Management
          2. Compiling for Multiprocessor Systems
          3. Exporting Symbols in Linux 2.0
          4. Module Configuration Parameters
        9. Quick Reference
      4. 3. Char Drivers
        1. The Design of scull
        2. Major and Minor Numbers
          1. Dynamic Allocation of Major Numbers
          2. Removing a Driver from the System
          3. dev_t and kdev_t
        3. File Operations
        4. The file Structure
        5. open and release
          1. The open Method
          2. The release Method
        6. scull’s Memory Usage
        7. A Brief Introduction to Race Conditions
        8. read and write
          1. The read Method
          2. The write Method
          3. readv and writev
        9. Playing with the New Devices
        10. The Device Filesystem
          1. Using devfs in Practice
          2. Portability Issues and devfs
        11. Backward Compatibility
          1. Changes in the File Operations Structure
          2. The Module Usage Count
          3. Changes in Semaphore Support
          4. Changes in Access to User Space
        12. Quick Reference
      5. 4. Debugging Techniques
        1. Debugging by Printing
          1. printk
          2. How Messages Get Logged
          3. Turning the Messages On and Off
        2. Debugging by Querying
          1. Using the /proc Filesystem
          2. The ioctl Method
        3. Debugging by Watching
        4. Debugging System Faults
          1. Oops Messages
            1. Using klogd
            2. Using ksymoops
          2. System Hangs
        5. Debuggers and Related Tools
          1. Using gdb
          2. The kdb Kernel Debugger
          3. The Integrated Kernel Debugger Patch
          4. The kgdb Patch
          5. Kernel Crash Dump Analyzers
          6. The User-Mode Linux Port
          7. The Linux Trace Toolkit
          8. Dynamic Probes
      6. 5. Enhanced Char Driver Operations
        1. ioctl
          1. Choosing the ioctl Commands
          2. The Return Value
          3. The Predefined Commands
          4. Using the ioctl Argument
          5. Capabilities and Restricted Operations
          6. The Implementation of the ioctl Commands
          7. Device Control Without ioctl
        2. Blocking I/O
          1. Going to Sleep and Awakening
          2. A Deeper Look at Wait Queues
          3. Writing Reentrant Code
          4. Blocking and Nonblocking Operations
          5. A Sample Implementation: scullpipe
        3. poll and select
          1. Interaction with read and write
            1. Reading data from the device
            2. Writing to the device
            3. Flushing pending output
          2. The Underlying Data Structure
        4. Asynchronous Notification
          1. The Driver’s Point of View
        5. Seeking a Device
          1. The llseek Implementation
        6. Access Control on a Device File
          1. Single-Open Devices
          2. Another Digression into Race Conditions
          3. Restricting Access to a Single User at a Time
          4. Blocking open as an Alternative to EBUSY
          5. Cloning the Device on Open
        7. Backward Compatibility
          1. Wait Queues in Linux 2.2 and 2.0
          2. Asynchronous Notification
          3. The fsync Method
          4. Access to User Space in Linux 2.0
          5. Capabilities in 2.0
          6. The Linux 2.0 select Method
          7. Seeking in Linux 2.0
          8. 2.0 and SMP
        8. Quick Reference
      7. 6. Flow of Time
        1. Time Intervals in the Kernel
          1. Processor-Specific Registers
        2. Knowing the Current Time
        3. Delaying Execution
          1. Long Delays
          2. Short Delays
        4. Task Queues
          1. The Nature of Task Queues
          2. How Task Queues Are Run
          3. Predefined Task Queues
            1. How the examples work
            2. The scheduler queue
            3. The timer queue
            4. The immediate queue
          4. Running Your Own Task Queues
          5. Tasklets
        5. Kernel Timers
        6. Backward Compatibility
        7. Quick Reference
      8. 7. Getting Hold of Memory
        1. The Real Story of kmalloc
          1. The Flags Argument
            1. Memory zones
          2. The Size Argument
        2. Lookaside Caches
          1. A scull Based on the Slab Caches: scullc
        3. get_free_page and Friends
          1. A scull Using Whole Pages: scullp
        4. vmalloc and Friends
          1. A scull Using Virtual Addresses: scullv
        5. Boot-Time Allocation
          1. Acquiring a Dedicated Buffer at Boot Time
          2. The bigphysarea Patch
          3. Reserving High RAM Addresses
        6. Backward Compatibility
        7. Quick Reference
      9. 8. Hardware Management
        1. I/O Ports and I/O Memory
          1. I/O Registers and Conventional Memory
        2. Using I/O Ports
          1. String Operations
          2. Pausing I/O
          3. Platform Dependencies
        3. Using Digital I/O Ports
          1. An Overview of the Parallel Port
          2. A Sample Driver
        4. Using I/O Memory
          1. Directly Mapped Memory
          2. Reusing short for I/O Memory
          3. Software-Mapped I/O Memory
          4. ISA Memory Below 1 MB
          5. isa_readb and Friends
          6. Probing for ISA Memory
        5. Backward Compatibility
        6. Quick Reference
      10. 9. Interrupt Handling
        1. Overall Control of Interrupts
        2. Preparing the Parallel Port
        3. Installing an Interrupt Handler
          1. The /proc Interface
          2. Autodetecting the IRQ Number
            1. Kernel-assisted probing
            2. Do-it-yourself probing
          3. Fast and Slow Handlers
            1. The internals of interrupt handling on the x86
        4. Implementing a Handler
          1. Using Arguments
          2. Enabling and Disabling Interrupts
        5. Tasklets and Bottom-Half Processing
          1. Tasklets
          2. The BH Mechanism
          3. Writing a BH Bottom Half
        6. Interrupt Sharing
          1. Installing a Shared Handler
          2. Running the Handler
          3. The /proc Interface
        7. Interrupt-Driven I/O
        8. Race Conditions
          1. Using Circular Buffers
          2. Using Spinlocks
          3. Using Lock Variables
            1. Bit operations
            2. Atomic integer operations
          4. Going to Sleep Without Races
        9. Backward Compatibility
          1. Differences in the 2.2 Kernel
          2. Further Differences in the 2.0 Kernel
        10. Quick Reference
      11. 10. Judicious Use of Data Types
        1. Use of Standard C Types
        2. Assigning an Explicit Size to Data Items
        3. Interface-Specific Types
        4. Other Portability Issues
          1. Time Intervals
          2. Page Size
          3. Byte Order
          4. Data Alignment
        5. Linked Lists
        6. Quick Reference
      12. 11. kmod and Advanced Modularization
        1. Loading Modules on Demand
          1. Requesting Modules in the Kernel
          2. The User-Space Side
          3. Module Loading and Security
          4. Module Loading Example
          5. Running User-Mode Helper Programs
        2. Intermodule Communication
        3. Version Control in Modules
          1. Using Version Support in Modules
          2. Exporting Versioned Symbols
        4. Backward Compatibility
        5. Quick Reference
      13. 12. Loading Block Drivers
        1. Registering the Driver
        2. The Header File blk.h
        3. Handling Requests: A Simple Introduction
          1. The Request Queue
          2. Performing the Actual Data Transfer
        4. Handling Requests: The Detailed View
          1. The I/O Request Queue
            1. The request structure and the buffer cache
            2. Request queue manipulation
            3. The I/O request lock
            4. How the blk.h macros and functions work
          2. Clustered Requests
            1. The active queue head
          3. Multiqueue Block Drivers
          4. Doing Without the Request Queue
        5. How Mounting and Unmounting Works
        6. The ioctl Method
        7. Removable Devices
          1. check_media_change
          2. Revalidation
          3. Extra Care
        8. Partitionable Devices
          1. The Generic Hard Disk
          2. Partition Detection
          3. Partition Detection Using initrd
          4. The Device Methods for spull
        9. Interrupt-Driven Block Drivers
        10. Backward Compatibility
        11. Quick Reference
      14. 13. mmap and DMA
        1. Memory Management in Linux
          1. Address Types
          2. High and Low Memory
          3. The Memory Map and struct page
          4. Page Tables
          5. Virtual Memory Areas
        2. The mmap Device Operation
          1. Using remap_page_range
          2. A Simple Implementation
          3. Adding VMA Operations
          4. Mapping Memory with nopage
          5. Remapping Specific I/O Regions
          6. Remapping RAM
            1. Remapping RAM with the nopage method
          7. Remapping Virtual Addresses
        3. The kiobuf Interface
          1. The kiobuf Structure
          2. Mapping User-Space Buffers and Raw I/O
        4. Direct Memory Access and Bus Mastering
          1. Overview of a DMA Data Transfer
          2. Allocating the DMA Buffer
            1. Do-it-yourself allocation
          3. Bus Addresses
          4. DMA on the PCI Bus
            1. Dealing with difficult hardware
            2. DMA mappings
            3. Setting up consistent DMA mappings
            4. Setting up streaming DMA mappings
            5. Scatter-gather mappings
            6. How different architectures support PCI DMA
            7. A simple PCI DMA example
            8. A quick look at SBus
          5. DMA for ISA Devices
            1. Registering DMA usage
            2. Talking to the DMA controller
        5. Backward Compatibility
          1. Changes to Memory Management
          2. Changes to DMA
        6. Quick Reference
      15. 14. Network Drivers
        1. How snull Is Designed
          1. Assigning IP Numbers
          2. The Physical Transport of Packets
        2. Connecting to the Kernel
          1. Module Loading
          2. Initializing Each Device
          3. Module Unloading
          4. Modularized and Nonmodularized Drivers
        3. The net_device Structure in Detail
          1. The Visible Head
          2. The Hidden Fields
            1. Interface information
            2. The device methods
            3. Utility fields
        4. Opening and Closing
        5. Packet Transmission
          1. Controlling Transmission Concurrency
          2. Transmission Timeouts
        6. Packet Reception
        7. The Interrupt Handler
        8. Changes in Link State
        9. The Socket Buffers
          1. The Important Fields
          2. Functions Acting on Socket Buffers
        10. MAC Address Resolution
          1. Using ARP with Ethernet
          2. Overriding ARP
          3. Non-Ethernet Headers
        11. Custom ioctl Commands
        12. Statistical Information
        13. Multicasting
          1. Kernel Support for Multicasting
          2. A Typical Implementation
        14. Backward Compatibility
          1. Differences in Linux 2.2
          2. Further Differences in Linux 2.0
          3. Probing and HAVE_DEVLIST
        15. Quick Reference
      16. 15. Overview of Peripheral Buses
        1. The PCI Interface
          1. PCI Addressing
          2. Boot Time
          3. Configuration Registers and Initialization
          4. Accessing the Configuration Space
            1. Looking at a configuration snapshot
          5. Accessing the I/O and Memory Spaces
            1. PCI I/O resources in Linux 2.4
            2. Peeking at the base address registers
          6. PCI Interrupts
          7. Handling Hot-Pluggable Devices
            1. The pci_driver structure
          8. Hardware Abstractions
        2. A Look Back: ISA
          1. Hardware Resources
          2. ISA Programming
          3. The Plug-and-Play Specification
        3. PC/104 and PC/104+
        4. Other PC Buses
          1. MCA
          2. EISA
          3. VLB
        5. SBus
        6. NuBus
        7. External Buses
          1. USB
          2. Writing a USB Driver
        8. Backward Compatibility
        9. Quick Reference
      17. 16. Physical Layout of the Kernel Source
        1. Booting the Kernel
        2. Before Booting
        3. The init Process
        4. The kernel Directory
        5. The fs Directory
        6. The mm Directory
        7. The net directory
        8. ipc and lib
        9. include and arch
        10. Drivers
          1. drivers/char
          2. drivers/block
          3. drivers/ide
          4. drivers/md
          5. drivers/cdrom
          6. drivers/scsi
          7. drivers/net
          8. drivers/sound
          9. drivers/video
          10. drivers/input
          11. drivers/media
          12. Bus-Specific Directories
          13. Platform-Specific Directories
          14. Other Subdirectories
      18. Bibliography
        1. Linux Kernel Books
        2. Unix Design and Internals
      19. Index
      20. Colophon