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 |