Title and Copyright Information
 
About This Manual
Audience
New and Changed Features
Scope of the Book
Organization
Related Documentation
Reader's Comments
Conventions
 
1    Introduction to Kernel Modules
1.1    What Is a Kernel Module?
1.1.1    Purpose of a Kernel Module
1.1.2    Kernel Module Environment
1.1.3    Designing a Kernel Module
1.2    Writing a Kernel Module -- Key Tasks
1.2.1    Required Tasks
1.2.2    Additional Tasks
1.2.3    Building and Testing a Kernel Module
 
2    Module Initialization
2.1    The configure Routine
2.1.1    Parameters
2.1.2    Request Codes
2.1.3    Return Status Values
2.2    Module Initialization
2.2.1    Receiving the CFG_OP_CONFIGURE Request
2.2.1.1    Implementing Statically or Dynamically Loaded Kernel Modules
2.2.1.2    Checking the Configuration
2.2.1.3    Allocating Memory for Data Structures
2.2.2    Receiving the CFG_OP_UNCONFIGURE Request
 
3    Module Attributes
3.1    The Attribute Table
3.2    Attribute Table Entry
3.2.1    Attribute Data Types
3.2.2    Operations Allowed on an Attribute
3.3    Attribute Get Requests
3.4    Attribute Set Requests
 
4    Dispatch Point Callbacks
4.1    Understanding the UNIX Boot Timeline
4.2    Why Use Callbacks?
4.3    Dispatch Points on the Boot Timeline
4.4    Implementing Callbacks in Your Kernel Module
4.4.1    Coding Callbacks
4.4.1.1    Calling the register_callback Routine
4.4.1.2    Writing the Callback Routine
4.4.2    Registering Callbacks
4.4.3    Nesting Callbacks and Deregistering Callbacks
4.4.4    Defining New Dispatch Points in your Kernel Module
 
5    Kernel-Mode Capabilities
5.1    Using String Routines
5.1.1    Comparing Two Null-Terminated Strings
5.1.2    Comparing Two Strings by Using a Specified Number of Characters
5.1.3    Copying a Null-Terminated Character String
5.1.4    Copying a Null-Terminated Character String with a Specified Limit
5.1.5    Returning the Number of Characters in a Null-Terminated String
5.2    Using Data Copying Routines
5.2.1    Copying a Series of Bytes with a Specified Limit
5.2.2    Zeroing a Block of Memory
5.2.3    Copying Data from User Address Space to Kernel Address Space
5.2.4    Copying Data from Kernel Address Space to User Address Space
5.2.5    Moving Data Between User Virtual Space and System Virtual Space
5.3    Using Kernel-Related Routines
5.3.1    Printing Text to the Console and Error Logger
5.3.2    Putting a Calling Process to Sleep
5.3.3    Waking Up a Sleeping Process
5.3.4    Initializing a Timer (Callout) Queue Element
5.3.5    Removing Scheduled Routines from the Timer (Callout) Queue
5.3.6    Setting the Interrupt Priority Mask
5.3.7    Allocating Memory
5.3.7.1    Allocating Data Structures with MALLOC
5.3.7.2    Freeing Up Dynamically Allocated Memory
5.4    Working with System Time
5.4.1    Understanding System Time Concepts
5.4.1.1    How a Kernel Module Uses Time
5.4.1.2    How Is System Time Created?
5.4.2    Fetching System Time
5.4.3    Modifying a Timestamp
5.4.4    Enabling Applications to Convert a Kernel Timestamp to a String
5.4.5    Delaying the Calling Routine a Specified Number of Microseconds
5.5    Using Kernel Threads
5.6    Using Locks
 
6    Symmetric Multiprocessing and Locking Methods
6.1    Understanding Hardware Issues Related to Synchronization
6.1.1    Atomicity
6.1.2    Alignment
6.1.3    Granularity
6.2    Locking in a Symmetric Multiprocessing Environment
6.3    Comparing Simple Locks and Complex Locks
6.3.1    Simple Locks
6.3.2    Complex Locks
6.4    Choosing a Locking Method
6.4.1    Who Has Access to a Particular Resource
6.4.2    Prevention of Access to a Resource While a Kernel Thread Sleeps
6.4.3    Length of Time the Lock Is Held
6.4.4    Execution Speed
6.4.5    Size of Code Blocks
6.4.6    Summary of Locking Methods
6.5    Choosing the Resources to Lock in the Module
6.5.1    Read-Only Resources
6.5.2    Device Control Status Register Addresses
6.5.3    Module-Specific Global Resources
6.5.4    System-Specific Global Resources
6.5.5    How to Determine the Resources to Lock
 
7    Simple Lock Routines
7.1    Declaring a Simple Lock Data Structure
7.2    Initializing a Simple Lock
7.3    Asserting Exclusive Access on a Resource
7.4    Releasing a Previously Asserted Simple Lock
7.5    Trying to Obtain a Simple Lock
7.6    Terminating a Simple Lock
7.7    Using the spl Routines with Simple Locks
 
8    Complex Lock Routines
8.1    Declaring a Complex Lock Data Structure
8.2    Initializing a Complex Lock
8.3    Performing Access Operations on a Complex Lock
8.3.1    Asserting a Complex Lock
8.3.1.1    Asserting a Complex Lock with Read-Only Access
8.3.1.2    Asserting a Complex Lock with Write Access
8.3.2    Releasing a Previously Asserted Complex Lock
8.3.3    Trying to Assert a Complex Lock
8.3.3.1    Trying to Assert a Complex Lock with Read-Only Access
8.3.3.2    Trying to Assert a Complex Lock with Write Access
8.4    Terminating a Complex Lock
 
9    Kernel Threads
9.1    Using Kernel Threads in Kernel Modules
9.1.1    Kernel Threads Execution
9.1.2    Issues Related to Using Kernel Threads
9.1.3    Kernel Threads Operations
9.2    Using the thread and task Data Structures
9.3    Creating and Starting a Kernel Thread
9.3.1    Creating and Starting a Kernel Thread at a Specified Entry Point
9.3.2    Creating and Starting a Fixed-Priority Kernel Thread Dedicated to Interrupt Service
9.4    Blocking (Putting to Sleep) a Kernel Thread
9.4.1    Asserting That the Current Kernel Thread Is About to Block Until the Specified Event Occurs
9.4.2    Using the Symmetric Multiprocessor Sleep Routine
9.5    Unblocking (Awakening) Kernel Threads
9.6    Terminating a Kernel Thread
9.7    Setting a Timer for the Current Kernel Thread
 
10    Building and Testing a Kernel Module
10.1    Producing a Single Binary Module
10.1.1    Step 1: Create a Directory to Contain Kernel Module Files
10.1.2    Step 2: Copy Kernel Module Files
10.1.3    Step 3: Create a BINARY.list File
10.1.4    Step 4: Run the sourceconfig Program
10.1.5    Step 5: Run the make Program
10.1.6    Step 6: Create a Kernel Configuration Development Area
10.1.7    Step 7: Run the sysconfigdb Utility
10.2    Loading and Configuring a Kernel Module
10.2.1    Loading a Module into the Kernel Image
10.2.2    Loading a Kernel Module Dynamically
10.3    Unconfiguring and Unloading Kernel Modules
10.4    Statically Configuring a Single Binary Module
10.4.1    Statically Configuring a Single Binary Module into a /vmunix Kernel
10.4.1.1    Step 1: Edit or Create the NAME.list File
10.4.1.2    Step 2: Run the doconfig Program
10.4.1.3    Step 3: Copy the New Kernel to the Root Directory
10.4.1.4    Step 4: Shut Down and Boot the System
10.5    Dynamically Configuring a Single Binary Module
10.5.1    Step 1: Link to the Single Binary Module
10.5.2    Step 2: Link to the Method File
10.5.3    Step 3: Run the sysconfig Utility
10.6    Creating the sysconfigtab File Fragment
10.7    Changing Attribute Values at Run Time
10.8    Testing a Kernel Module
 
Glossary
 
Examples
10-1    A sysconfigtab File Fragment
 
Figures
1-1    Kernel Module Environment
3-1    Attribute Get Requests
3-2    Attribute Set Requests
4-1    Dispatch Points Along the Boot Timeline
4-2    Using the Kernel Callback Subsystem
5-1    Results of the strcmp Routine
5-2    Results of the strncmp Routine
5-3    Results of the strcpy Routine
5-4    Results of the strncpy Routine
5-5    Results of the strlen Routine
5-6    Results of the bcopy Routine
5-7    Results of the copyin Routine
5-8    Results of the copyout Routine
5-9    When Time Becomes Available During a System Boot
6-1    Why Locking Is Needed in an SMP Environment
6-2    Simple Locks Are Spin Locks
6-3    Complex Locks Are Blocking Locks
7-1    Two Instances of the xx Module Asserting an Exclusive Lock
7-2    One Instance of the xx Module Releasing an Exclusive Lock
7-3    The xx Module Trying to Assert an Exclusive Lock
8-1    Three Instances of the if_fta Module Asserting a Read-Only Complex Lock
8-2    Three Instances of the if_fta Module Asserting a Write Complex Lock
8-3    One Instance of the if_fta Module Releasing a Complex Write Lock
8-4    The if_fta Module Trying to Assert a Complex Read-Only Lock
8-5    The if_fta Module Trying to Assert a Complex Write Lock
9-1    Using Kernel Threads in a Kernel Module
10-1    Format of the sysconfigtab File Fragment
 
Tables
5-1    Uses for spl Routines
6-1    Data Structure and Routines Associated with Simple Locks
6-2    Data Structure and Routines Associated with Complex Locks
6-3    SMP Characteristics for Locking
6-4    Kernel Module Resources for Locking
6-5    Locking Device Register Offset Definitions
9-1    Summary of Operations That Kernel Thread Routines Perform
 
Index