You are previewing Professional Linux Kernel Architecture.
O'Reilly logo
Professional Linux Kernel Architecture

Book Description

Find an introduction to the architecture, concepts and algorithms of the Linux kernel in Professional Linux Kernel Architecture, a guide to the kernel sources and large number of connections among subsystems. Find an introduction to the relevant structures and functions exported by the kernel to userland, understand the theoretical and conceptual aspects of the Linux kernel and Unix derivatives, and gain a deeper understanding of the kernel. Learn how to reduce the vast amount of information contained in the kernel sources and obtain the skills necessary to understand the kernel sources.

Table of Contents

  1. Copyright
  2. About the Author
  3. Credits
  4. Acknowledgments
  5. Introduction
    1. What This Book Covers
  6. 1. Introduction and Overview
    1. 1.1. Tasks of the Kernel
    2. 1.2. Implementation Strategies
    3. 1.3. Elements of the Kernel
      1. 1.3.1. Processes, Task Switching, and Scheduling
      2. 1.3.2. Unix Processes
        1. 1.3.2.1. Threads
        2. 1.3.2.2. Namespaces
      3. 1.3.3. Address Spaces and Privilege Levels
        1. 1.3.3.1. Privilege Levels
        2. 1.3.3.2. Virtual and Physical Address Spaces
      4. 1.3.4. Page Tables
        1. 1.3.4.1. Interaction with the CPU
        2. 1.3.4.2. Memory Mappings
      5. 1.3.5. Allocation of Physical Memory
        1. 1.3.5.1. The Buddy System
        2. 1.3.5.2. The Slab Cache
        3. 1.3.5.3. Swapping and Page Reclaim
      6. 1.3.6. Timing
      7. 1.3.7. System Calls
      8. 1.3.8. Device Drivers, Block and Character Devices
      9. 1.3.9. Networks
      10. 1.3.10. Filesystems
      11. 1.3.11. Modules and Hotplugging
      12. 1.3.12. Caching
      13. 1.3.13. List Handling
      14. 1.3.14. Object Management and Reference Counting
        1. 1.3.14.1. Generic Kernel Objects
        2. 1.3.14.2. Sets of Objects
        3. 1.3.14.3. Reference Counting
      15. 1.3.15. Data Types
        1. 1.3.15.1. Type Definitions
        2. 1.3.15.2. Byte Order
        3. 1.3.15.3. Per-CPU Variables
        4. 1.3.15.4. Access to Userspace
      16. 1.3.16. ... and Beyond the Infinite
    4. 1.4. Why the Kernel Is Special
    5. 1.5. Some Notes on Presentation
    6. 1.6. Summary
  7. 2. Process Management and Scheduling
    1. 2.1. Process Priorities
    2. 2.2. Process Life Cycle
      1. 2.2.1. Preemptive Multitasking
    3. 2.3. Process Representation
      1. 2.3.1. Process Types
      2. 2.3.2. Namespaces
        1. 2.3.2.1. Concept
        2. 2.3.2.2. Implementation
          1. 2.3.2.2.1. The UTS Namespace
          2. 2.3.2.2.2. The User Namespace
      3. 2.3.3. Process Identification Numbers
        1. 2.3.3.1. Process Identifiers
        2. 2.3.3.2. Managing PIDs
          1. 2.3.3.2.1. Data Structures
          2. 2.3.3.2.2. Functions
        3. 2.3.3.3. Generating Unique PIDs
      4. 2.3.4. Task Relationships
    4. 2.4. Process Management System Calls
      1. 2.4.1. Process Duplication
        1. 2.4.1.1. Copy on Write
        2. 2.4.1.2. Executing System Calls
        3. 2.4.1.3. Implementation of do_fork
        4. 2.4.1.4. Copying Processes
        5. 2.4.1.5. Special Points When Generating Threads
      2. 2.4.2. Kernel Threads
      3. 2.4.3. Starting New Programs
        1. 2.4.3.1. Implementation of execve
        2. 2.4.3.2. Interpreting Binary Formats
      4. 2.4.4. Exiting Processes
    5. 2.5. Implementation of the Scheduler
      1. 2.5.1. Overview
      2. 2.5.2. Data Structures
        1. 2.5.2.1. Elements in the Task Structure
        2. 2.5.2.2. Scheduler Classes
        3. 2.5.2.3. Run Queues
        4. 2.5.2.4. Scheduling Entities
      3. 2.5.3. Dealing with Priorities
        1. 2.5.3.1. Kernel Representation of Priorities
        2. 2.5.3.2. Computing Priorities
        3. 2.5.3.3. Computing Load Weights
      4. 2.5.4. Core Scheduler
        1. 2.5.4.1. The Periodic Scheduler
        2. 2.5.4.2. The Main Scheduler
        3. 2.5.4.3. Interaction with fork
        4. 2.5.4.4. Context Switching
          1. 2.5.4.4.1. Intricacies of switch_to
          2. 2.5.4.4.2. Lazy FPU Mode
    6. 2.6. The Completely Fair Scheduling Class
      1. 2.6.1. Data Structures
      2. 2.6.2. CFS Operations
        1. 2.6.2.1. The Virtual Clock
        2. 2.6.2.2. Latency Tracking
      3. 2.6.3. Queue Manipulation
      4. 2.6.4. Selecting the Next Task
      5. 2.6.5. Handling the Periodic Tick
      6. 2.6.6. Wake-up Preemption
      7. 2.6.7. Handling New Tasks
    7. 2.7. The Real-Time Scheduling Class
      1. 2.7.1. Properties
      2. 2.7.2. Data Structures
      3. 2.7.3. Scheduler Operations
    8. 2.8. Scheduler Enhancements
      1. 2.8.1. SMP Scheduling
        1. 2.8.1.1. Extensions to the Data Structures
        2. 2.8.1.2. The Migration Thread
        3. 2.8.1.3. Core Scheduler Changes
      2. 2.8.2. Scheduling Domains and Control Groups
      3. 2.8.3. Kernel Preemption and Low Latency Efforts
        1. 2.8.3.1. Kernel Preemption
        2. 2.8.3.2. Low Latency
    9. 2.9. Summary
  8. 3. Memory Management
    1. 3.1. Overview
    2. 3.2. Organization in the (N)UMA Model
      1. 3.2.1. Overview
      2. 3.2.2. Data Structures
        1. 3.2.2.1. Node Management
          1. 3.2.2.1.1. Node State Management
        2. 3.2.2.2. Memory Zones
        3. 3.2.2.3. Calculation of Zone Watermarks
        4. 3.2.2.4. Hot-N-Cold Pages
        5. 3.2.2.5. Page Frames
          1. 3.2.2.5.1. Definition of page
          2. 3.2.2.5.2. Architecture-Independent Page Flags
    3. 3.3. Page Tables
      1. 3.3.1. Data Structures
        1. 3.3.1.1. Breakdown of Addresses in Memory
        2. 3.3.1.2. Format of Page Tables
        3. 3.3.1.3. PTE-Specific Entries
      2. 3.3.2. Creating and Manipulating Entries
    4. 3.4. Initialization of Memory Management
      1. 3.4.1. Data Structure Setup
        1. 3.4.1.1. Prerequisites
        2. 3.4.1.2. System Start
        3. 3.4.1.3. Node and Zone Initialization
      2. 3.4.2. Architecture-Specific Setup
        1. 3.4.2.1. Arrangement of the Kernel in Memory
        2. 3.4.2.2. Initialization Steps
        3. 3.4.2.3. Initialization of Paging
          1. 3.4.2.3.1. Division of Address Space
          2. 3.4.2.3.2. Alternative Division
          3. 3.4.2.3.3. Splitting the Virtual Address Space
          4. 3.4.2.3.4. Initialization of the Hot-n-Cold Cache
        4. 3.4.2.4. Registering Active Memory Regions
          1. 3.4.2.4.1. Registering Regions on IA-32
          2. 3.4.2.4.2. Registering Regions on AMD64
        5. 3.4.2.5. Address Space Setup on AMD64
      3. 3.4.3. Memory Management during the Boot Process
        1. 3.4.3.1. Data Structures
        2. 3.4.3.2. Initialization
          1. 3.4.3.2.1. Initialization for IA-32
          2. 3.4.3.2.2. Initialization for AMD64
        3. 3.4.3.3. Interface to the Kernel
          1. 3.4.3.3.1. Allocating Memory
          2. 3.4.3.3.2. Releasing Memory
        4. 3.4.3.4. Disabling the Bootmem Allocator
        5. 3.4.3.5. Releasing Initialization Data
    5. 3.5. Management of Physical Memory
      1. 3.5.1. Structure of the Buddy System
      2. 3.5.2. Avoiding Fragmentation
        1. 3.5.2.1. Grouping Pages by Mobility
          1. 3.5.2.1.1. Data Structure
          2. 3.5.2.1.2. Global Variables and Auxiliary Functions
          3. 3.5.2.1.3. Initializing Mobility-Based Grouping
        2. 3.5.2.2. The Virtual Movable Zone
          1. 3.5.2.2.1. Data Structures
          2. 3.5.2.2.2. Implementation
      3. 3.5.3. Initializing the Zone and Node Data Structures
        1. 3.5.3.1. Managing Data Structure Creation
        2. 3.5.3.2. Creating Data Structures for Each Node
      4. 3.5.4. Allocator API
        1. 3.5.4.1. Allocation Masks
        2. 3.5.4.2. Allocation Macros
      5. 3.5.5. Reserving Pages
        1. 3.5.5.1. Selecting Pages
          1. 3.5.5.1.1. Helper Functions
          2. 3.5.5.1.2. Allocation Control
        2. 3.5.5.2. Removing the Selected Pages
          1. 3.5.5.2.1. The __rmqueue Helper Function
      6. 3.5.6. Freeing Pages
      7. 3.5.7. Allocation of Discontiguous Pages in the Kernel
        1. 3.5.7.1. Reserving Memory with vmalloc
          1. 3.5.7.1.1. Data Structures
          2. 3.5.7.1.2. Creating a vm_area
          3. 3.5.7.1.3. Allocating a Memory Area
        2. 3.5.7.2. Alternative Mapping Methods
        3. 3.5.7.3. Freeing Memory
      8. 3.5.8. Kernel Mappings
        1. 3.5.8.1. Persistent Kernel Mappings
          1. 3.5.8.1.1. Data Structures
          2. 3.5.8.1.2. Finding Page Addresses
          3. 3.5.8.1.3. Creating a Mapping
          4. 3.5.8.1.4. Unmapping
        2. 3.5.8.2. Temporary Kernel Mappings
        3. 3.5.8.3. Mapping Functions on Machines without Highmem
    6. 3.6. The Slab Allocator
      1. 3.6.1. Alternative Allocators
      2. 3.6.2. Memory Management in the Kernel
      3. 3.6.3. The Principle of Slab Allocation
        1. 3.6.3.1. Fine Structure of the Cache
        2. 3.6.3.2. Fine Structure of Slabs
      4. 3.6.4. Implementation
        1. 3.6.4.1. Data Structures
        2. 3.6.4.2. Initialization
        3. 3.6.4.3. Creating Caches
        4. 3.6.4.4. Allocating Objects
          1. 3.6.4.4.1. Selecting a Cached Object
          2. 3.6.4.4.2. Refilling the Per-CPU Cache
        5. 3.6.4.5. Growing the Cache
        6. 3.6.4.6. Freeing Objects
        7. 3.6.4.7. Destroying Caches
      5. 3.6.5. General Caches
        1. 3.6.5.1. Implementation of kmalloc
        2. 3.6.5.2. Implementation of kfree
    7. 3.7. Processor Cache and TLB Control
    8. 3.8. Summary
  9. 4. Virtual Process Memory
    1. 4.1. Introduction
    2. 4.2. Virtual Process Address Space
      1. 4.2.1. Layout of the Process Address Space
      2. 4.2.2. Creating the Layout
    3. 4.3. Principle of Memory Mappings
    4. 4.4. Data Structures
      1. 4.4.1. Trees and Lists
      2. 4.4.2. Representation of Regions
      3. 4.4.3. The Priority Search Tree
        1. 4.4.3.1. Additional Data Structures
        2. 4.4.3.2. Representing Priority Trees
    5. 4.5. Operations on Regions
      1. 4.5.1. Associating Virtual Addresses with a Region
      2. 4.5.2. Merging Regions
      3. 4.5.3. Inserting Regions
      4. 4.5.4. Creating Regions
    6. 4.6. Address Spaces
    7. 4.7. Memory Mappings
      1. 4.7.1. Creating Mappings
      2. 4.7.2. Removing Mappings
      3. 4.7.3. Nonlinear Mappings
    8. 4.8. Reverse Mapping
      1. 4.8.1. Data Structures
      2. 4.8.2. Creating a Reverse Mapping
        1. 4.8.2.1. Anonymous Pages
        2. 4.8.2.2. Pages with a File-Based Mapping
      3. 4.8.3. Using Reverse Mapping
    9. 4.9. Managing the Heap
    10. 4.10. Handling of Page Faults
    11. 4.11. Correction of Userspace Page Faults
      1. 4.11.1. Demand Allocation/Paging
      2. 4.11.2. Anonymous Pages
      3. 4.11.3. Copy on Write
      4. 4.11.4. Getting Nonlinear Mappings
    12. 4.12. Kernel Page Faults
    13. 4.13. Copying Data between Kernel and Userspace
    14. 4.14. Summary
  10. 5. Locking and Interprocess Communication
    1. 5.1. Control Mechanisms
      1. 5.1.1. Race Conditions
      2. 5.1.2. Critical Sections
        1. 5.1.2.1. Semaphores
    2. 5.2. Kernel Locking Mechanisms
      1. 5.2.1. Atomic Operations on Integers
      2. 5.2.2. Spinlocks
        1. 5.2.2.1. Data Structures and Usage
      3. 5.2.3. Semaphores
      4. 5.2.4. The Read-Copy-Update Mechanism
        1. 5.2.4.1. Core API
        2. 5.2.4.2. List Operations
      5. 5.2.5. Memory and Optimization Barriers
      6. 5.2.6. Reader/Writer Locks
      7. 5.2.7. The Big Kernel Lock
      8. 5.2.8. Mutexes
        1. 5.2.8.1. Classical Mutexes
        2. 5.2.8.2. Real-Time Mutexes
      9. 5.2.9. Approximate Per-CPU Counters
      10. 5.2.10. Lock Contention and Fine-Grained Locking
    3. 5.3. System V Interprocess Communication
      1. 5.3.1. System V Mechanisms
      2. 5.3.2. Semaphores
        1. 5.3.2.1. Using System V Semaphores
        2. 5.3.2.2. Data Structures
        3. 5.3.2.3. Implementing System Calls
        4. 5.3.2.4. Permission Checks
      3. 5.3.3. Message Queues
      4. 5.3.4. Shared Memory
    4. 5.4. Other IPC Mechanisms
      1. 5.4.1. Signals
        1. 5.4.1.1. Implementing Signal Handlers
        2. 5.4.1.2. Implementing Signal Handling
        3. 5.4.1.3. Implementing Signal Handling
          1. 5.4.1.3.1. Sending Signals
          2. 5.4.1.3.2. Processing the Signal Queue
      2. 5.4.2. Pipes and Sockets
    5. 5.5. Summary
  11. 6. Device Drivers
    1. 6.1. I/O Architecture
      1. 6.1.1. Expansion Hardware
        1. 6.1.1.1. Bus Systems
        2. 6.1.1.2. Interaction with the Peripherals
          1. 6.1.1.2.1. I/O Ports
          2. 6.1.1.2.2. I/O Memory Mapping
          3. 6.1.1.2.3. Polling and Interrupts
        3. 6.1.1.3. Device Control via Buses
    2. 6.2. Access to Devices
      1. 6.2.1. Device Files
      2. 6.2.2. Character, Block, and Other Devices
        1. 6.2.2.1. Identifying Device Files
        2. 6.2.2.2. Dynamic Creation of Device Files
      3. 6.2.3. Device Addressing Using Ioctls
        1. 6.2.3.1. Network Cards and Other Devices
      4. 6.2.4. Representation of Major and Minor Numbers
      5. 6.2.5. Registration
        1. 6.2.5.1. Data Structures
          1. 6.2.5.1.1. The Device Database
          2. 6.2.5.1.2. Character Device Range Database
        2. 6.2.5.2. Registration Procedures
          1. 6.2.5.2.1. Character Devices
          2. 6.2.5.2.2. Block Devices
    3. 6.3. Association with the Filesystem
      1. 6.3.1. Device File Elements in Inodes
      2. 6.3.2. Standard File Operations
      3. 6.3.3. Standard Operations for Character Devices
      4. 6.3.4. Standard Operations for Block Devices
    4. 6.4. Character Device Operations
      1. 6.4.1. Representing Character Devices
      2. 6.4.2. Opening Device Files
      3. 6.4.3. Reading and Writing
    5. 6.5. Block Device Operations
      1. 6.5.1. Representation of Block Devices
      2. 6.5.2. Data Structures
        1. 6.5.2.1. Block Devices
        2. 6.5.2.2. Generic Hard Disks and Partitions
        3. 6.5.2.3. Connecting the Pieces
        4. 6.5.2.4. Block Device Operations
        5. 6.5.2.5. Request Queues
      3. 6.5.3. Adding Disks and Partitions to the System
        1. 6.5.3.1. Adding Partitions
        2. 6.5.3.2. Adding Disks
      4. 6.5.4. Opening Block Device Files
      5. 6.5.5. Request Structure
      6. 6.5.6. BIOs
      7. 6.5.7. Submitting Requests
        1. 6.5.7.1. Creating Requests
        2. 6.5.7.2. Queue Plugging
        3. 6.5.7.3. Executing Requests
      8. 6.5.8. I/O Scheduling
      9. 6.5.9. Implementation of Ioctls
    6. 6.6. Resource Reservation
      1. 6.6.1. Resource Management
        1. 6.6.1.1. Tree Data Structures
        2. 6.6.1.2. Requesting and Releasing Resources
          1. 6.6.1.2.1. Requesting Resources
          2. 6.6.1.2.2. Releasing Resources
      2. 6.6.2. I/O Memory
      3. 6.6.3. I/O Ports
    7. 6.7. Bus Systems
      1. 6.7.1. The Generic Driver Model
        1. 6.7.1.1. Representation of Devices
        2. 6.7.1.2. Representation of Buses
        3. 6.7.1.3. Registration Procedures
          1. 6.7.1.3.1. Registering Buses
          2. 6.7.1.3.2. Registering Devices
          3. 6.7.1.3.3. Registering Device Drivers
      2. 6.7.2. The PCI Bus
        1. 6.7.2.1. Layout of a PCI System
          1. 6.7.2.1.1. Identification of Devices
          2. 6.7.2.1.2. Address Spaces
          3. 6.7.2.1.3. Configuration Information
        2. 6.7.2.2. Implementation in the Kernel
          1. 6.7.2.2.1. Data Structures
          2. 6.7.2.2.2. Representation of Buses
          3. 6.7.2.2.3. Device Management
          4. 6.7.2.2.4. Driver Functions
          5. 6.7.2.2.5. Registering Drivers
      3. 6.7.3. USB
        1. 6.7.3.1. Features and Mode of Operation
        2. 6.7.3.2. Management of Drivers
        3. 6.7.3.3. Representation of the Device Tree
    8. 6.8. Summary
  12. 7. Modules
    1. 7.1. Overview
    2. 7.2. Using Modules
      1. 7.2.1. Adding and Removing
        1. 7.2.1.1. Handling Unresolved References
      2. 7.2.2. Dependencies
      3. 7.2.3. Querying Module Information
      4. 7.2.4. Automatic Loading
    3. 7.3. Inserting and Deleting Modules
      1. 7.3.1. Module Representation
      2. 7.3.2. Dependencies and References
        1. 7.3.2.1. Manipulating Data Structures
      3. 7.3.3. Binary Structure of Modules
        1. 7.3.3.1. Initialization and Cleanup Functions
        2. 7.3.3.2. Exporting Symbols
        3. 7.3.3.3. General Module Information
          1. 7.3.3.3.1. Module License
          2. 7.3.3.3.2. Author and Description
          3. 7.3.3.3.3. Alternative Name
          4. 7.3.3.3.4. Elementary Version Control
      4. 7.3.4. Inserting Modules
        1. 7.3.4.1. System Call Implementation
        2. 7.3.4.2. Loading Modules
          1. 7.3.4.2.1. Rewriting Section Addresses
          2. 7.3.4.2.2. Finding Section Addresses
          3. 7.3.4.2.3. Organizing Data in Memory
          4. 7.3.4.2.4. Transferring Data
          5. 7.3.4.2.5. Querying the Module License
          6. 7.3.4.2.6. Resolving References and Relocation
        3. 7.3.4.3. Resolving References
      5. 7.3.5. Removing Modules
    4. 7.4. Automation and Hotplugging
      1. 7.4.1. Automatic Loading with kmod
      2. 7.4.2. Hotplugging
    5. 7.5. Version Control
      1. 7.5.1. Checksum Methods
        1. 7.5.1.1. Generating a Checksum
        2. 7.5.1.2. Linking Into Modules and the Kernel
          1. 7.5.1.2.1. Exported Functions
          2. 7.5.1.2.2. Unresolved References
      2. 7.5.2. Version Control Functions
    6. 7.6. Summary
  13. 8. The Virtual Filesystem
    1. 8.1. Filesystem Types
    2. 8.2. The Common File Model
      1. 8.2.1. Inodes
      2. 8.2.2. Links
      3. 8.2.3. Programming Interface
      4. 8.2.4. Files as a Universal Interface
    3. 8.3. Structure of the VFS
      1. 8.3.1. Structural Overview
        1. 8.3.1.1. File Representation
        2. 8.3.1.2. Filesystem and Superblock Information
      2. 8.3.2. Inodes
        1. 8.3.2.1. Inode Operations
        2. 8.3.2.2. Inode Lists
      3. 8.3.3. Process-Specific Information
        1. 8.3.3.1. Associated Files
          1. 8.3.3.1.1. Increasing the Initial Limits
      4. 8.3.4. File Operations
        1. 8.3.4.1. Directory Information
        2. 8.3.4.2. VFS Namespaces
      5. 8.3.5. Directory Entry Cache
        1. 8.3.5.1. Dentry Structure
        2. 8.3.5.2. Cache Organization
        3. 8.3.5.3. Dentry Operations
        4. 8.3.5.4. Standard Functions
    4. 8.4. Working with VFS Objects
      1. 8.4.1. Filesystem Operations
        1. 8.4.1.1. Registering Filesystems
        2. 8.4.1.2. Mounting and Unmounting
          1. 8.4.1.2.1. VFS Mount Structures
          2. 8.4.1.2.2. Superblock Management
          3. 8.4.1.2.3. The Mount System Call
          4. 8.4.1.2.4. Shared Subtrees
          5. 8.4.1.2.5. The umount System Call
          6. 8.4.1.2.6. Automatic Expiration
          7. 8.4.1.2.7. Pseudo-Filesystems
      2. 8.4.2. File Operations
        1. 8.4.2.1. Finding Inodes
          1. 8.4.2.1.1. Implementation of do_lookup
          2. 8.4.2.1.2. Implementation of do_follow_link
        2. 8.4.2.2. Opening Files
        3. 8.4.2.3. Reading and Writing
          1. 8.4.2.3.1. Read
          2. 8.4.2.3.2. Write
    5. 8.5. Standard Functions
      1. 8.5.1. Generic Read Routine
        1. 8.5.1.1. Asynchronous Reading
        2. 8.5.1.2. Reading from Mappings
      2. 8.5.2. The fault Mechanism
      3. 8.5.3. Permission-Checking
    6. 8.6. Summary
  14. 9. The Extended Filesystem Family
    1. 9.1. Introduction
    2. 9.2. Second Extended Filesystem
      1. 9.2.1. Physical Structure
        1. 9.2.1.1. Structure Overview
        2. 9.2.1.2. Indirection
        3. 9.2.1.3. Fragmentation
      2. 9.2.2. Data Structures
        1. 9.2.2.1. Superblock
        2. 9.2.2.2. Group Descriptor
        3. 9.2.2.3. Inodes
        4. 9.2.2.4. Directories and Files
        5. 9.2.2.5. Data Structures in Memory
          1. 9.2.2.5.1. Pre-allocation
      3. 9.2.3. Creating a Filesystem
      4. 9.2.4. Filesystem Actions
        1. 9.2.4.1. Mounting and Unmounting
        2. 9.2.4.2. Reading and Generating Data and Indirection Blocks
          1. 9.2.4.2.1. Finding Data Blocks
          2. 9.2.4.2.2. Requesting New Blocks
          3. 9.2.4.2.3. Block Allocation
          4. 9.2.4.2.4. Pre-allocation Handling
          5. 9.2.4.2.5. Creating New Reservations
        3. 9.2.4.3. Creating and Deleting Inodes
        4. 9.2.4.4. Registering Inodes
          1. 9.2.4.4.1. Orlov Allocation
          2. 9.2.4.4.2. Classic Directory Allocation
          3. 9.2.4.4.3. Inode Allocation for Other Files
        5. 9.2.4.5. Deleting Inodes
        6. 9.2.4.6. Removing Data Blocks
        7. 9.2.4.7. Address Space Operations
    3. 9.3. Third Extended Filesystem
      1. 9.3.1. Concepts
        1. 9.3.1.1. Log Records, Handles, and Transactions
      2. 9.3.2. Data Structures
    4. 9.4. Summary
  15. 10. Filesystems without Persistent Storage
    1. 10.1. The proc Filesystem
      1. 10.1.1. Contents of /proc
        1. 10.1.1.1. Process-Specific Data
        2. 10.1.1.2. General System Information
        3. 10.1.1.3. Network Information
        4. 10.1.1.4. System Control Parameters
      2. 10.1.2. Data Structures
        1. 10.1.2.1. Representation of proc Entries
        2. 10.1.2.2. proc inodes
      3. 10.1.3. Initialization
      4. 10.1.4. Mounting the Filesystem
      5. 10.1.5. Managing /proc Entries
        1. 10.1.5.1. Creating and Registering Entries
        2. 10.1.5.2. Finding Entries
      6. 10.1.6. Reading and Writing Information
        1. 10.1.6.1. Implementation of proc_file_read
        2. 10.1.6.2. Implementation of proc_file_write
      7. 10.1.7. Task-Related Information
        1. 10.1.7.1. The self directory
        2. 10.1.7.2. Selection According to PID
          1. 10.1.7.2.1. Creating the Directory Inode
          2. 10.1.7.2.2. Processing Files
      8. 10.1.8. System Control Mechanism
        1. 10.1.8.1. Using Sysctls
        2. 10.1.8.2. Data Structures
        3. 10.1.8.3. Static Sysctl Tables
        4. 10.1.8.4. Registering Sysctls
        5. 10.1.8.5. /proc/sys File Operations
    2. 10.2. Simple Filesystems
      1. 10.2.1. Sequential Files
        1. 10.2.1.1. Writing Sequential File Handlers
        2. 10.2.1.2. Connection with the Virtual Filesystem
      2. 10.2.2. Writing Filesystems with Libfs
      3. 10.2.3. The Debug Filesystem
        1. 10.2.3.1. Example
        2. 10.2.3.2. Programming Interface
      4. 10.2.4. Pseudo Filesystems
    3. 10.3. Sysfs
      1. 10.3.1. Overview
      2. 10.3.2. Data Structures
        1. 10.3.2.1. Directory Entries
        2. 10.3.2.2. Attributes
          1. 10.3.2.2.1. Data Structures
          2. 10.3.2.2.2. Declaring New Attributes
      3. 10.3.3. Mounting the Filesystem
      4. 10.3.4. File and Directory Operations
        1. 10.3.4.1. Opening Files
          1. 10.3.4.1.1. Data Structures
          2. 10.3.4.1.2. Implementation
        2. 10.3.4.2. Reading and Writing File Contents
          1. 10.3.4.2.1. Reading
          2. 10.3.4.2.2. Writing
        3. 10.3.4.3. Directory Traversal
      5. 10.3.5. Populating Sysfs
        1. 10.3.5.1. Registering Subsystems
    4. 10.4. Summary
  16. 11. Extended Attributes and Access Control Lists
    1. 11.1. Extended Attributes
      1. 11.1.1. Interface to the Virtual Filesystem
        1. 11.1.1.1. Data Structures
        2. 11.1.1.2. System Calls
        3. 11.1.1.3. Generic Handler Functions
      2. 11.1.2. Implementation in Ext3
        1. 11.1.2.1. Data Structures
        2. 11.1.2.2. Implementation
          1. 11.1.2.2.1. Retrieving Extended Attributes
          2. 11.1.2.2.2. Setting Extended Attributes
          3. 11.1.2.2.3. Listing Extended Attributes
      3. 11.1.3. Implementation in Ext2
    2. 11.2. Access Control Lists
      1. 11.2.1. Generic Implementation
        1. 11.2.1.1. Data Structures
        2. 11.2.1.2. Permission Checks
      2. 11.2.2. Implementation in Ext3
        1. 11.2.2.1. Data Structures
        2. 11.2.2.2. Conversion between On-Disk and In-Memory Representation
        3. 11.2.2.3. Inode Initialization
        4. 11.2.2.4. Retrieving ACLs
        5. 11.2.2.5. Modifying ACLs
        6. 11.2.2.6. Permission Checks
      3. 11.2.3. Implementation in Ext2
    3. 11.3. Summary
  17. 12. Networks
    1. 12.1. Linked Computers
    2. 12.2. ISO/OSI and TCP/IP Reference Model
    3. 12.3. Communication via Sockets
      1. 12.3.1. Creating a Socket
      2. 12.3.2. Using Sockets
        1. 12.3.2.1. Echo Client
        2. 12.3.2.2. Echo Server
      3. 12.3.3. Datagram Sockets
    4. 12.4. The Layer Model of Network Implementation
    5. 12.5. Networking Namespaces
    6. 12.6. Socket Buffers
      1. 12.6.1. Data Management Using Socket Buffers
      2. 12.6.2. Management Data of Socket Buffers
    7. 12.7. Network Access Layer
      1. 12.7.1. Representation of Network Devices
        1. 12.7.1.1. Data Structure
        2. 12.7.1.2. Registering Network Devices
      2. 12.7.2. Receiving Packets
        1. 12.7.2.1. Traditional Method
        2. 12.7.2.2. Support for High-Speed Interfaces
          1. 12.7.2.2.1. Implementing Poll Functions
          2. 12.7.2.2.2. Implementing IRQ Handlers
          3. 12.7.2.2.3. Handling the Rx SoftIRQ
          4. 12.7.2.2.4. Implementation of the Old API on Top of NAPI
      3. 12.7.3. Sending Packets
    8. 12.8. Network Layer
      1. 12.8.1. IPv4
      2. 12.8.2. Receiving Packets
      3. 12.8.3. Local Delivery to the Transport Layer
        1. 12.8.3.1. Defragmentation
        2. 12.8.3.2. Delivery to the Transport Layer
      4. 12.8.4. Packet Forwarding
      5. 12.8.5. Sending Packets
        1. 12.8.5.1. Transition to the Network Access Layer
        2. 12.8.5.2. Packet Fragmenting
        3. 12.8.5.3. Routing
      6. 12.8.6. Netfilter
        1. 12.8.6.1. Extending Network Functionality
        2. 12.8.6.2. Calling Hook Functions
        3. 12.8.6.3. Scanning the Hook Table
        4. 12.8.6.4. Activating the Hook Functions
      7. 12.8.7. IPv6
        1. 12.8.7.1. Overview and Innovations
        2. 12.8.7.2. Implementation
    9. 12.9. Transport Layer
      1. 12.9.1. UDP
      2. 12.9.2. TCP
        1. 12.9.2.1. TCP Headers
        2. 12.9.2.2. Receiving TCP Data
        3. 12.9.2.3. Three-Way Handshake
        4. 12.9.2.4. Passive Connection Establishment
        5. 12.9.2.5. Active Connection Establishment
        6. 12.9.2.6. Transmission of Data Packets
        7. 12.9.2.7. Receiving Packets
        8. 12.9.2.8. Sending Packets
        9. 12.9.2.9. Connection Termination
    10. 12.10. Application Layer
      1. 12.10.1. Socket Data Structures
      2. 12.10.2. Sockets and Files
      3. 12.10.3. The socketcall System Call
      4. 12.10.4. Creating Sockets
      5. 12.10.5. Receiving Data
      6. 12.10.6. Sending Data
    11. 12.11. Networking from within the Kernel
      1. 12.11.1. Communication Functions
      2. 12.11.2. The Netlink Mechanism
        1. 12.11.2.1. Data Structures
          1. 12.11.2.1.1. Specifying Addresses
          2. 12.11.2.1.2. Netlink Protocol Family
          3. 12.11.2.1.3. Message Format
          4. 12.11.2.1.4. Keeping Track of Netlink Connections
          5. 12.11.2.1.5. Protocol-Specific Operations
        2. 12.11.2.2. Programming Interface
    12. 12.12. Summary
  18. 13. System Calls
    1. 13.1. Basics of System Programming
      1. 13.1.1. Tracing System Calls
      2. 13.1.2. Supported Standards
      3. 13.1.3. Restarting System Calls
    2. 13.2. Available System Calls
    3. 13.3. Implementation of System Calls
      1. 13.3.1. Structure of System Calls
        1. 13.3.1.1. Implementation of Handler Functions
        2. 13.3.1.2. Dispatching and Parameter Passing
          1. 13.3.1.2.1. Parameter Passing
          2. 13.3.1.2.2. System Call Table
        3. 13.3.1.3. Return to User Mode
          1. 13.3.1.3.1. Meaning of Return Values
      2. 13.3.2. Access to Userspace
      3. 13.3.3. System Call Tracing
        1. 13.3.3.1. System Call Tracing
        2. 13.3.3.2. Kernel-Side Implementation
          1. 13.3.3.2.1. Starting Tracing
          2. 13.3.3.2.2. Implementation of PTRACE_CONT and _SYSCALL
          3. 13.3.3.2.3. Stopping Tracing
          4. 13.3.3.2.4. Reading and Modifying Target Process Data
    4. 13.4. Summary
  19. 14. Kernel Activities
    1. 14.1. Interrupts
      1. 14.1.1. Interrupt Types
      2. 14.1.2. Hardware IRQs
      3. 14.1.3. Processing Interrupts
        1. 14.1.3.1. Entry and Exit Tasks
        2. 14.1.3.2. Interrupt Handlers
      4. 14.1.4. Data Structures
        1. 14.1.4.1. IRQ Controller Abstraction
        2. 14.1.4.2. Handler Function Representation
      5. 14.1.5. Interrupt Flow Handling
        1. 14.1.5.1. Setting Controller Hardware
        2. 14.1.5.2. Flow Handling
          1. 14.1.5.2.1. Edge-Triggered Interrupts
          2. 14.1.5.2.2. Level-Triggered Interrupts
          3. 14.1.5.2.3. Other Types of Interrupts
      6. 14.1.6. Initializing and Reserving IRQs
        1. 14.1.6.1. Registering IRQs
        2. 14.1.6.2. Freeing IRQs
        3. 14.1.6.3. Registering Interrupts
      7. 14.1.7. Servicing IRQs
        1. 14.1.7.1. Switching to Kernel Mode
        2. 14.1.7.2. IRQ Stacks
        3. 14.1.7.3. Calling the Flow Handler Routine
          1. 14.1.7.3.1. Processing on AMD64 Systems
          2. 14.1.7.3.2. Processing on IA-32 Systems
          3. 14.1.7.3.3. Old-Style Processing
        4. 14.1.7.4. Calling the High-level ISR
        5. 14.1.7.5. Implementing Handler Routines
          1. 14.1.7.5.1. Restrictions
          2. 14.1.7.5.2. Implementing Handlers
    2. 14.2. Software Interrupts
      1. 14.2.1. Starting SoftIRQ Processing
      2. 14.2.2. The SoftIRQ Daemon
    3. 14.3. Tasklets
      1. 14.3.1. Generating Tasklets
      2. 14.3.2. Registering Tasklets
      3. 14.3.3. Executing Tasklets
    4. 14.4. Wait Queues and Completions
      1. 14.4.1. Wait Queues
        1. 14.4.1.1. Data Structures
        2. 14.4.1.2. Putting Processes to Sleep
        3. 14.4.1.3. Waking Processes
      2. 14.4.2. Completions
      3. 14.4.3. Work Queues
    5. 14.5. Summary
  20. 15. Time Management
    1. 15.1. Overview
      1. 15.1.1. Types of Timers
      2. 15.1.2. Configuration Options
    2. 15.2. Implementation of Low-Resolution Timers
      1. 15.2.1. Timer Activation and Process Accounting
      2. 15.2.2. Working with Jiffies
        1. 15.2.2.1. Comparing Times
        2. 15.2.2.2. Time Conversion
      3. 15.2.3. Data Structures
      4. 15.2.4. Dynamic Timers
        1. 15.2.4.1. Mode of Operation
        2. 15.2.4.2. Data Structures
        3. 15.2.4.3. Implementing Timer Handling
        4. 15.2.4.4. Activating Timers
    3. 15.3. Generic Time Subsystem
      1. 15.3.1. Overview
      2. 15.3.2. Configuration Options
      3. 15.3.3. Time Representation
      4. 15.3.4. Objects for Time Management
        1. 15.3.4.1. Clock Sources
        2. 15.3.4.2. Working with Clock Sources
        3. 15.3.4.3. Clock Event Devices
        4. 15.3.4.4. Tick Devices
    4. 15.4. High-Resolution Timers
      1. 15.4.1. Data Structures
      2. 15.4.2. Setting Timers
      3. 15.4.3. Implementation
        1. 15.4.3.1. High-Resolution Timers in High-Resolution Mode
        2. 15.4.3.2. High-Resolution Timers in Low-Resolution Mode
      4. 15.4.4. Periodic Tick Emulation
      5. 15.4.5. Switching to High-Resolution Timers
    5. 15.5. Dynamic Ticks
      1. 15.5.1. Data Structures
      2. 15.5.2. Dynamic Ticks for Low-Resolution Systems
        1. 15.5.2.1. Switching to Dynamic Ticks
        2. 15.5.2.2. The Dynamic Tick Handler
        3. 15.5.2.3. Updating Jiffies
      3. 15.5.3. Dynamic Ticks for High-Resolution Systems
      4. 15.5.4. Stopping and Starting Periodic Ticks
        1. 15.5.4.1. Stopping Ticks
        2. 15.5.4.2. Restarting Ticks
    6. 15.6. Broadcast Mode
    7. 15.7. Implementing Timer-Related System Calls
      1. 15.7.1. Time Bases
      2. 15.7.2. The alarm and setitimer System Calls
        1. 15.7.2.1. Extensions to the Task Structure
        2. 15.7.2.2. Real-Time Timers
      3. 15.7.3. Getting the Current Time
    8. 15.8. Managing Process Times
    9. 15.9. Summary
  21. 16. Page and Buffer Cache
    1. 16.1. Structure of the Page Cache
      1. 16.1.1. Managing and Finding Cached Pages
      2. 16.1.2. Writing Back Modified Data
    2. 16.2. Structure of the Buffer Cache
    3. 16.3. Address Spaces
      1. 16.3.1. Data Structures
      2. 16.3.2. Page Trees
        1. 16.3.2.1. Implementation
          1. 16.3.2.1.1. Tagging
          2. 16.3.2.1.2. Accessing Radix Tree Elements
          3. 16.3.2.1.3. Locking
      3. 16.3.3. Operations on Address Spaces
    4. 16.4. Implementation of the Page Cache
      1. 16.4.1. Allocating Pages
      2. 16.4.2. Finding Pages
      3. 16.4.3. Waiting on Pages
      4. 16.4.4. Operations with Whole Pages
      5. 16.4.5. Page Cache Readahead
    5. 16.5. Implementation of the Buffer Cache
      1. 16.5.1. Data Structures
      2. 16.5.2. Operations
      3. 16.5.3. Interaction of Page and Buffer Cache
        1. 16.5.3.1. Linking of Pages and Buffer Heads
        2. 16.5.3.2. Interaction
          1. 16.5.3.2.1. Reading Whole Pages in Buffers
          2. 16.5.3.2.2. Writing Whole Pages into Buffers
      4. 16.5.4. Independent Buffers
        1. 16.5.4.1. Mode of Operation
        2. 16.5.4.2. Implementation
          1. 16.5.4.2.1. Data Structures
          2. 16.5.4.2.2. Interface Functions
          3. 16.5.4.2.3. The function __getblk
          4. 16.5.4.2.4. The function __bread
          5. 16.5.4.2.5. Use in the Filesystem
    6. 16.6. Summary
  22. 17. Data Synchronization
    1. 17.1. Overview
    2. 17.2. The pdflush Mechanism
    3. 17.3. Starting a New Thread
    4. 17.4. Thread Initialization
    5. 17.5. Performing Actual Work
    6. 17.6. Periodic Flushing
    7. 17.7. Associated Data Structures
      1. 17.7.1. Page Status
      2. 17.7.2. Writeback Control
      3. 17.7.3. Adjustable Parameters
    8. 17.8. Central Control
    9. 17.9. Superblock Synchronization
    10. 17.10. Inode Synchronization
      1. 17.10.1. Walking the Superblocks
      2. 17.10.2. Examining Superblock Inodes
      3. 17.10.3. Writing Back Single Inodes
    11. 17.11. Congestion
      1. 17.11.1. Data Structures
      2. 17.11.2. Thresholds
      3. 17.11.3. Setting and Clearing the Congested State
      4. 17.11.4. Waiting on Congested Queues
    12. 17.12. Forced Writeback
    13. 17.13. Laptop Mode
    14. 17.14. System Calls for Synchronization Control
    15. 17.15. Full Synchronization
      1. 17.15.1. Synchronization of Inodes
      2. 17.15.2. Synchronization of Individual Files
      3. 17.15.3. Synchronization of Memory Mappings
    16. 17.16. Summary
  23. 18. Page Reclaim and Swapping
    1. 18.1. Overview
      1. 18.1.1. Swappable Pages
      2. 18.1.2. Page Thrashing
      3. 18.1.3. Page-Swapping Algorithms
        1. 18.1.3.1. Second Chance
        2. 18.1.3.2. LRU Algorithm
    2. 18.2. Page Reclaim and Swapping in the Linux Kernel
      1. 18.2.1. Organization of the Swap Area
      2. 18.2.2. Checking Memory Utilization
      3. 18.2.3. Selecting Pages to Be Swapped Out
      4. 18.2.4. Handling Page Faults
      5. 18.2.5. Shrinking Kernel Caches
    3. 18.3. Managing Swap Areas
      1. 18.3.1. Data Structures
        1. 18.3.1.1. Characterization of Swap Areas
        2. 18.3.1.2. Extents for Implementing Non-Contiguous Swap Areas
      2. 18.3.2. Creating a Swap Area
      3. 18.3.3. Activating a Swap Area
        1. 18.3.3.1. Reading the Swap Area Characteristics
        2. 18.3.3.2. Creating the Extent List
    4. 18.4. The Swap Cache
      1. 18.4.1. Identifying Swapped-Out Pages
      2. 18.4.2. Structure of the Cache
      3. 18.4.3. Adding New Pages
        1. 18.4.3.1. Reserving Page Slots
        2. 18.4.3.2. Allocating Swap Space
        3. 18.4.3.3. Caching Swap Pages
      4. 18.4.4. Searching for a Page
    5. 18.5. Writing Data Back
    6. 18.6. Page Reclaim
      1. 18.6.1. Overview
      2. 18.6.2. Data Structures
        1. 18.6.2.1. Page Vectors
        2. 18.6.2.2. The LRU Cache
      3. 18.6.3. Determining Page Activity
      4. 18.6.4. Shrinking Zones
        1. 18.6.4.1. Controlling Scanning
        2. 18.6.4.2. Implementation
      5. 18.6.5. Isolating LRU Pages and Lumpy Reclaim
      6. 18.6.6. Shrinking the List of Active Pages
      7. 18.6.7. Reclaiming Inactive Pages
        1. 18.6.7.1. Shrinking the Inactive List
        2. 18.6.7.2. Performing Page Reclaim
    7. 18.7. The Swap Token
    8. 18.8. Handling Swap-Page Faults
      1. 18.8.1. Swapping Pages in
      2. 18.8.2. Reading the Data
      3. 18.8.3. Swap Readahead
    9. 18.9. Initiating Memory Reclaim
      1. 18.9.1. Periodic Reclaim with kswapd
      2. 18.9.2. Swap-out in the Event of Acute Memory Shortage
    10. 18.10. Shrinking Other Caches
      1. 18.10.1. Data Structures
      2. 18.10.2. Registering and Removing Shrinkers
      3. 18.10.3. Shrinking Caches
    11. 18.11. Summary
  24. 19. Auditing
    1. 19.1. Overview
    2. 19.2. Audit Rules
    3. 19.3. Implementation
      1. 19.3.1. Data Structures
        1. 19.3.1.1. Extensions to task_struct
        2. 19.3.1.2. Records, Rules and Filtering
      2. 19.3.2. Initialization
      3. 19.3.3. Processing Requests
      4. 19.3.4. Logging Events
        1. 19.3.4.1. Audit Start
        2. 19.3.4.2. Writing Log Messages
        3. 19.3.4.3. Closing the Audit Log
      5. 19.3.5. System Call Auditing
        1. 19.3.5.1. Audit Context Allocation
        2. 19.3.5.2. System Call Events
        3. 19.3.5.3. Access Vector Cache Auditing
        4. 19.3.5.4. Standard Hooks
    4. 19.4. Summary
  25. A. Architecture Specifics
    1. A.1. Overview
    2. A.2. Data Types
    3. A.3. Alignment
    4. A.4. Memory Pages
    5. A.5. System Calls
    6. A.6. String Processing
    7. A.7. Thread Representation
      1. A.7.1. IA-32
      2. A.7.2. IA-64
      3. A.7.3. ARM
      4. A.7.4. Sparc64
      5. A.7.5. Alpha
      6. A.7.6. Mips
      7. A.7.7. PowerPC
      8. A.7.8. AMD64
    8. A.8. Bit Operations and Endianness
      1. A.8.1. Manipulation of Bit Chains
      2. A.8.2. Conversion between Byte Orders
    9. A.9. Page Tables
    10. A.10. Miscellaneous
      1. A.10.1. Checksum Calculation
      2. A.10.2. Context Switch
      3. A.10.3. Finding the Current Process
    11. A.11. Summary
  26. B. Working with the Source Code
    1. B.1. Organization of the Kernel Sources
    2. B.2. Configuration with Kconfig
      1. B.2.1. A Sample Configuration File
      2. B.2.2. Language Elements of Kconfig
        1. B.2.2.1. Menus
        2. B.2.2.2. Configuration Options
        3. B.2.2.3. Attributes
        4. B.2.2.4. Dependencies
      3. B.2.3. Processing Configuration Information
    3. B.3. Compiling the Kernel with Kbuild
      1. B.3.1. Using the Kbuild System
      2. B.3.2. Structure of the Makefiles
        1. B.3.2.1. The Main Makefile
        2. B.3.2.2. Driver and Subsystem Makefiles
    4. B.4. Useful Tools
      1. B.4.1. LXR
        1. B.4.1.1. Working with LXR
      2. B.4.2. Patch and Diff
        1. B.4.2.1. Unified Context Diffs
        2. B.4.2.2. Applying Patches
      3. B.4.3. Git
        1. B.4.3.1. Tracking Development History
          1. B.4.3.1.1. Displaying Commits
          2. B.4.3.1.2. Tracking the Development History of a Single File
        2. B.4.3.2. Incorporating Modifications
        3. B.4.3.3. Exporting
    5. B.5. Debugging and Analyzing the Kernel
      1. B.5.1. GDB and DDD
      2. B.5.2. Local Kernel
      3. B.5.3. KGDB
    6. B.6. User-Mode Linux
    7. B.7. Summary
  27. C. Notes on C
    1. C.1. How the GNU C Compiler Works
      1. C.1.1. From Source Code to Machine Program
      2. C.1.2. Assembly and Linking
      3. C.1.3. Procedure Calls
      4. C.1.4. Optimization
        1. C.1.4.1. Constant Simplification
        2. C.1.4.2. Loop Optimization
        3. C.1.4.3. Common Subexpression Elimination
        4. C.1.4.4. Dead Code Elimination
      5. C.1.5. Inline Functions
      6. C.1.6. Attributes
      7. C.1.7. Inline Assembler
      8. C.1.8. __builtin Functions
      9. C.1.9. Pointer Arithmetic
    2. C.2. Standard Data Structures and Techniques of the Kernel
      1. C.2.1. Reference Counters
      2. C.2.2. Pointer Type Conversions
      3. C.2.3. Alignment Issues
        1. C.2.3.1. Natural Alignment
        2. C.2.3.2. Generic Alignment
      4. C.2.4. Bit Arithmetic
      5. C.2.5. Pre-Processor Tricks
      6. C.2.6. Miscellaneous
      7. C.2.7. Doubly Linked Lists
      8. C.2.8. Hash Lists
      9. C.2.9. Red-Black Trees
      10. C.2.10. Radix Trees
    3. C.3. Summary
  28. D. System Startup
    1. D.1. Architecture-Specific Setup on IA-32 Systems
    2. D.2. High-Level Initialization
      1. D.2.1. Subsystem Initialization
        1. D.2.1.1. Architecture-Specific Setup
        2. D.2.1.2. Interpreting Command-Line Arguments
        3. D.2.1.3. Initializing Central Data Structures and Caches
        4. D.2.1.4. Searching for Known System Errors
        5. D.2.1.5. Idle and init Thread
          1. D.2.1.5.1. Driver Setup
          2. D.2.1.5.2. Removing Initialization Data
          3. D.2.1.5.3. Starting Userspace Initialization
    3. D.3. Summary
  29. E. The ELF Binary Format
    1. E.1. Layout and Structure
      1. E.1.1. ELF Header
      2. E.1.2. Program Header Table
      3. E.1.3. Sections
      4. E.1.4. Symbol Table
      5. E.1.5. String Tables
    2. E.2. Data Structures in the Kernel
      1. E.2.1. Data Types
      2. E.2.2. Headers
        1. E.2.2.1. ELF Header
        2. E.2.2.2. Program Header
        3. E.2.2.3. Section Header
      3. E.2.3. String Tables
      4. E.2.4. Symbol Tables
      5. E.2.5. Relocation Entries
        1. E.2.5.1. Data Structures
        2. E.2.5.2. Relocation Types
          1. E.2.5.2.1. Example of Relative Displacements
      6. E.2.6. Dynamic Linking
    3. E.3. Summary
  30. F. The Kernel Development Process
    1. F.1. Introduction
    2. F.2. Kernel Trees and the Structure of Development
      1. F.2.1. The Command Chain
      2. F.2.2. The Development Cycle
      3. F.2.3. Online Resources
    3. F.3. The Structure of Patches
      1. F.3.1. Technical Issues
        1. F.3.1.1. Coding Style
        2. F.3.1.2. Portability
        3. F.3.1.3. Documenting Code
      2. F.3.2. Submission and Review
        1. F.3.2.1. Preparing Patches for a Mailing List
        2. F.3.2.2. Origin of Patches
    4. F.4. Linux and Academia
      1. F.4.1. Some Examples
      2. F.4.2. Adopting Research
        1. F.4.2.1. Different Communities
    5. F.5. Summary
  31. References