You are previewing Linux Device Drivers.
O'Reilly logo
Linux Device Drivers

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 and is winning over enthusiastic adherents in many application areas. This book reveals information that heretofore has been passed by word-of-mouth or in cryptic source code comments, showing how to write a driver for a wide range of devices. 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. Drivers for character devices, block devices, and network interfaces are all described in step-by-step form and are illustrated with full-featured examples that show driver design issues, which can be executed without special hardware. 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.0, but also covers 1.2.13 and experimental versions up to 2.1.43. You are also told how to maximize portability among hardware platforms. Contents include:

  • Building a driver and loading modules

  • Complete character, block, and network drivers

  • Debugging a driver

  • Timing

  • Memory management and DMA

  • Interrupts

  • Portability issues

  • Peripheral Component Interconnect (PCI)

  • A tour of kernel internals

Table of Contents

  1. Linux Device Drivers
    1. Preface
      1. Audience of This Book
      2. Organization of the Material
      3. Background Information
      4. Sources for Further Information
      5. Relevant Books
      6. Conventions Used in This Book
      7. We’d Like to Hear from You
      8. Acknowledgments
    2. 1. An Introduction to the Linux Kernel
      1. The Role of the Driver Writer
      2. Splitting the Kernel
      3. Classes of Devices and Modules
      4. Security Issues
      5. Version Numbering
      6. License Terms
      7. Overview of the Book
    3. 2. Building and Running Modules
      1. Modules Versus Applications
        1. User Space and Kernel Space
        2. Concurrency in the Kernel
      2. Compiling and Loading
        1. Version Dependency
      3. The Kernel Symbol Table
        1. Registering Symbol Tables
      4. Initialization and Shutdown
        1. Error Handling in init_module
        2. The Usage Count
        3. Unloading
      5. Using Resources
        1. Ports
        2. ISA Memory
      6. Automatic and Manual Configuration
      7. Doing It in User Space
      8. 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
        1. Overview of the Different Operations
      4. The file Structure
      5. Open and Release
        1. The open Method
        2. The release Method
      6. Scull’s Memory Usage
      7. Read and Write
        1. The read Method
        2. The write Method
      8. Playing with the New Devices
      9. Quick Reference
    5. 4. Debugging Techniques
      1. Debugging by Printing
        1. Printk
        2. How Messages Get Logged
        3. Using the Preprocessor to Ease Monitoring
      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 ksymoops
          2. Using oops
          3. Using klogd
        2. System Hangs
      5. Using a Debugger
        1. Using gdb
        2. Using kdebug
        3. Remote Debugging
    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. Device Control Without ioctl
      2. Blocking I/O
        1. Going to Sleep and Awakening
        2. Writing Reentrant Code
        3. Wait Queues
        4. Blocking and Nonblocking Operations
        5. A Sample Implementation: scullpipe
      3. 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 lseek Implementation
      6. Access Control on a Device File
        1. Single-Open Devices
        2. Restricting Access to a Single User at a Time
        3. Blocking Open as an Alternative to EBUSY
        4. Cloning the Device on Open
      7. Quick Reference
    7. 6. Flow of Time
      1. Time Intervals in the Kernel
      2. Knowing the Current Time
      3. Delaying Execution
        1. Long Delays
        2. Short Delays
      4. Task Queues
        1. The Nature of Task Queues
        2. Predefined Task Queues
          1. How the examples work
          2. The scheduler queue
          3. The timer queue
          4. The immediate queue
        3. Running Your Own Task Queues
      5. Kernel Timers
        1. The New Timer List
      6. Quick Reference
    8. 7. Getting Hold of Memory
      1. The Real Story of kmalloc
        1. The Priority Argument
        2. The Size Argument
      2. get_free_page and Friends
        1. A scull Using Whole Pages: scullp
      3. vmalloc and Friends
        1. A scull Using Virtual Addresses: scullv
      4. Playing Dirty
      5. Quick Reference
    9. 8. Hardware Management
      1. Using I/O Ports
        1. Platform Dependencies
        2. Pausing I/O
        3. String Operations
      2. Using the Parallel Port
        1. Basics of the Parallel Port
        2. A Sample Driver
      3. Accessing Memory on Device Boards
        1. ISA Memory Below 1M
        2. ISA Memory Above 1M
        3. High PCI Memory
      4. Accessing the Text-Mode Video Buffer
      5. Quick Reference
    10. 9. Interrupt Handling
      1. Preparing the Parallel Port
      2. Installing an Interrupt Handler
        1. The /proc Interface
        2. Autodetecting the IRQ Number
          1. Kernel-helped probing
          2. Do-it-yourself probing
        3. Fast and Slow Handlers
          1. The internals of interrupt handling on the x86
      3. Implementing a Handler
        1. Using Arguments
        2. Enabling and Disabling Interrupts
      4. Bottom Halves
        1. The Design of Bottom Halves
        2. Writing a Bottom Half
      5. Interrupt Sharing
        1. Installing a Shared Handler
        2. Running the Handler
        3. The /proc Interface
      6. Interrupt-Driven I/O
      7. Race Conditions
        1. Using Circular Buffers
        2. Disabling Interrupts
        3. Using Lock Variables
          1. Bit operations
          2. Atomic integer operations
        4. Going to Sleep Without Races
      8. Version Dependencies of IRQ Handling
        1. Different Prototypes for request_irq
        2. Probing the IRQ Line
      9. 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
      5. Quick Reference
    12. 11. Kerneld and Advanced Modularization
      1. Loading Modules on Demand
        1. The User-Level Side
        2. The Kernel-Level Side
      2. Version Control in Modules
        1. Using Version Support in Modules
        2. Exporting Versioned Symbols
      3. Persistent Storage Across Unload/Load
      4. Quick Reference
    13. 12. Loading Block Drivers
      1. Registering the Driver
      2. The Header File blk.h
      3. Handling Requests
        1. Performing the Actual Data Transfer
        2. Clustered Requests
      4. How Mounting Works
      5. The ioctl Method
      6. Removable Devices
        1. check_media_change
        2. revalidate
        3. Extra Care
      7. Partitionable Devices
        1. The Generic Hard Disk
        2. Partition Detection in the Kernel
        3. Partition Detection in Modules
        4. Partition Detection Using Initrd
        5. The Device Methods for spull
      8. Interrupt-Driven Block Drivers
      9. Quick Reference
    14. 13. Mmap and DMA
      1. Memory Management in Linux
        1. Page Tables
        2. Virtual Memory Areas
        3. The Memory Map
      2. The mmap Device Operation
        1. A Simple Implementation
        2. Maintaining the Usage Count
        3. Supporting the mremap System Call
        4. Remapping Specific I/O Regions
        5. Remapping RAM
          1. Playing with the reserved bit
          2. Implementing the nopage method
        6. Remapping Virtual Addresses
      3. Direct Memory Access
        1. Overview of a DMA Data Transfer
        2. Allocating the DMA Buffer
          1. Do-it-yourself allocation
        3. Bus Addresses
        4. DMA for ISA devices
          1. Registering DMA usage
          2. Talking to the DMA controller
        5. DMA and PCI Devices
      4. 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 Non-Modularized Drivers
      3. The 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
      6. Packet Reception
      7. Interrupt-Driven Operation
      8. The Socket Buffers
        1. The Important Fields
        2. Functions Acting on Socket Buffers
      9. Address Resolution
        1. Using ARP with Ethernet
        2. Overriding ARP
        3. Non-Ethernet Headers
      10. Load-Time Configuration
      11. Run-Time Configuration
      12. Custom ioctl Commands
      13. Statistical Information
      14. Multicasting
        1. Kernel Support for Multicasting
        2. A Typical Implementation
      15. Quick Reference
    16. 15. Overview of Peripheral Buses
      1. The PCI Interface
        1. PCI Addressing
        2. Boot Time
        3. Detecting the Device
        4. Accessing the Configuration Space
          1. Looking at a configuration snapshot
        5. Accessing the I/O and Memory Spaces
        6. PCI Interrupts
      2. A Look Back: ISA
        1. Hardware Resources
        2. ISA Programming
        3. The ``Plug and Play'' Specification
      3. Other PC Buses
        1. MCA
        2. EISA
        3. VLB
      4. Sbus
      5. Quick Reference
    17. 16. Physical Layout of the Kernel Source
      1. Booting the Kernel
      2. Before Booting
        1. Setting Up the X86 Processors
          1. Booting a bare-bones zImage kernel
          2. Booting a bare-bones bzImage kernel
          3. Using lilo
          4. Using loadlin
          5. Other booters
        2. Setting Up Alpha Processors
        3. Setting Up Sparc Processors
      3. The Init Process
      4. The kernel Directory
        1. sched.c
        2. Process Control
        3. Modularization
        4. Other Operations
      5. The mm Directory
        1. Paging and Swapping
        2. Allocation and Deallocation
        3. Other Interfaces
      6. The fs Directory
        1. Exec and Binary Formats
        2. devices.c and block_dev.c
        3. The VFS: Superblocks
        4. Inodes and Caching Techniques
        5. open.c
        6. read_write.c and readdir.c
        7. select.c
        8. Pipes and fifos
        9. Control Functions
        10. File Locks
        11. Minor Files
      7. Networking
      8. IPC and lib Functions
      9. Drivers
        1. Char, Block, and Network Drivers
        2. SCSI Drivers
        3. Other Subdirectories
      10. Architecture Dependencies
    18. 17. Recent Developments
      1. Modularization
        1. Exporting Symbols
        2. Declaring Parameters
        3. /proc/modules
      2. File Operations
        1. Prototype Differences
        2. The poll Method
      3. Accessing User Space
        1. Using the New Interface
      4. Task Queues
      5. Interrupt Management
      6. Bit Operations
      7. Conversion Functions
      8. vremap
      9. Virtual Memory
      10. Handling Kernel-Space Faults
      11. Other Changes
    19. Index
    20. Colophon