JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Writing Device Drivers     Oracle Solaris 11.1 Information Library
search filter icon
search icon

Document Information

Preface

Part I Designing Device Drivers for the Oracle Solaris Platform

1.  Overview of Oracle Solaris Device Drivers

2.  Oracle Solaris Kernel and Device Tree

3.  Multithreading

4.  Properties

5.  Managing Events and Queueing Tasks

6.  Driver Autoconfiguration

7.  Device Access: Programmed I/O

8.  Interrupt Handlers

9.  Direct Memory Access (DMA)

10.  Mapping Device and Kernel Memory

11.  Device Context Management

12.  Power Management

13.  Hardening Oracle Solaris Drivers

14.  Layered Driver Interface (LDI)

Part II Designing Specific Kinds of Device Drivers

15.  Drivers for Character Devices

16.  Drivers for Block Devices

17.  SCSI Target Drivers

18.  SCSI Host Bus Adapter Drivers

19.  Drivers for Network Devices

20.  USB Drivers

21.  SR-IOV Drivers

Part III Building a Device Driver

22.  Compiling, Loading, Packaging, and Testing Drivers

Driver Development Summary

Driver Code Layout

Header Files

Source Files

Configuration Files

Preparing for Driver Installation

Compiling and Linking the Driver

Module Dependencies

Writing a Hardware Configuration File

Installing, Updating, and Removing Drivers

Copying the Driver to a Module Directory

Installing Drivers with add_drv

Updating Driver Information

Removing the Driver

Loading and Unloading Drivers

Driver Packaging

Criteria for Testing Drivers

Configuration Testing

Functionality Testing

Error Handling

Testing Loading and Unloading

Stress, Performance, and Interoperability Testing

DDI/DKI Compliance Testing

Installation and Packaging Testing

Testing Specific Types of Drivers

Testing Tape Drivers

Testing Disk Drivers

Asynchronous Communication Drivers

Testing Network Drivers

Testing SR-IOV Drivers

23.  Debugging, Testing, and Tuning Device Drivers

24.  Recommended Coding Practices

Part IV Appendixes

A.  Hardware Overview

B.  Summary of Oracle Solaris DDI/DKI Services

C.  Making a Device Driver 64-Bit Ready

D.  Console Frame Buffer Drivers

E.  pci.conf File

Index

Preparing for Driver Installation

The following steps precede installation of a driver:

  1. Compile the driver.

  2. Create a configuration file if necessary.

  3. Identify the driver module to the system through either of the following alternatives:

    • Match the driver's name to the name of the device node.

    • Use either add_drv(1M) or update_drv(1M) to inform the system of the module names.

The system maintains a one-to-one association between the name of the driver module and the name of the dev_info node. For example, consider a dev_info node for a device that is named mydevice. The device mydevice is handled by a driver module that is also named mydevice. The mydevice module resides in a subdirectory that is called drv, which is in the module path. The module is in drv/mydevice if you are using a 32-bit kernel. The module is in drv/sparcv9/mydevice if you are using a 64-bit SPARC kernel. The module is in drv/amd64/mydevice if you are using a 64-bit x86 kernel.

If the driver is a STREAMS network driver, then the driver name must meet the following constraints:

If the driver must manage dev_info nodes with different names, the add_drv(1M) utility can create aliases. The -i flag specifies the names of other dev_info nodes that the driver handles. The update_drv command can also modify aliases for an installed device driver.

Compiling and Linking the Driver

You need to compile each driver source file and link the resulting object files into a driver module. The Oracle Solaris OS is compatible with both the Oracle Solaris Studio C compiler and the GNU C compiler from the Free Software Foundation, Inc. The examples in this section use the Oracle Solaris Studio C compiler unless otherwise noted. For information on the Oracle Solaris Studio C compiler, see the Oracle Solaris Studio 12.3: C User’s Guide and the Oracle Solaris Studio Documentation. For more information on compile and link options, see the Oracle Solaris Studio 12.3 Command-Line Reference documentation. The GNU C compiler is supplied in the /usr/sfw directory. For information on the GNU C compiler, see http://gcc.gnu.org/ or check the man pages in /usr/sfw/man.

The example below shows a driver that is called xx with two C source files. A driver module that is called xx is generated. The driver that is created in this example is for a 32-bit kernel. You must use ld -r even if your driver has only one object module.

% cc -D_KERNEL -c xx1.c
% cc -D_KERNEL -c xx2.c
% ld -r -o xx xx1.o xx2.o

The _KERNEL symbol must be defined to indicate that this code defines a kernel module. No other symbols should be defined, except for driver private symbols. The DEBUG symbol can be defined to enable any calls to ASSERT(9F).

Table 22-1 Compiler Options for SPARC and x86 64–bit Architectures

Compiler
SPARC 64
x86 64
Studio 9
cc -D_KERNEL -xarch=v9 -c xx.c
Not Supported
Studio 10
cc -D_KERNEL -xarch=v9 -c xx.c
cc -D_KERNEL -xarch=amd64 -xmodel=kernel -c xx.c
Studio 11
cc -D_KERNEL -xarch=v9 -c xx.c
cc -D_KERNEL -xarch=amd64 -xmodel=kernel -c xx.c
Oracle Solaris Studio 12
cc -D_KERNEL -m64 -c xx.c
cc -D_KERNEL -m64 -xmodel=kernel -c xx.c

Note - If you are compiling for a 32–bit or 64–bit x86 architecture using Oracle Solaris Studio 12.2 or older compilers, do not add -xarch=sse2a since the default value is SSE2.



Caution

Caution - MMX instructions are not supported in the x86 kernel. Use of MMX instructions triggers a kernel panic and therefore should not be used.


After the driver is stable, you might want to add optimization flags to build a production quality driver. See the cc(1) man page in Oracle Solaris Studio 12.3 Command-Line Reference for specific information on optimizations in the Oracle Solaris Studio C compiler.

Global variables should be treated as volatile in device drivers. The volatile tag is discussed in greater detail in Declaring a Variable Volatile. Use of the flag depends on the platform. See the man pages.

Module Dependencies

If the driver module depends on symbols exported by another kernel module, the dependency can be specified by the -dy and -N options of the loader, ld(1). If the driver depends on a symbol exported by misc/mySymbol, the example below should be used to create the driver binary.

% ld -dy -r -o xx xx1.o xx2.o -N misc/mySymbol

Writing a Hardware Configuration File

If a device is non-self-identifying, the kernel might require a hardware configuration file for that device. If the driver is called xx, the hardware configuration file for the driver should be called xx.conf.

On the x86 platform, device information is now supplied by the booting system. Hardware configuration files should no longer be needed, even for non-self-identifying devices.

See the driver.conf(4), pseudo(4), sbus(4), scsi_free_consistent_buf(9F), and update_drv(1M) man pages for more information on hardware configuration files.

Arbitrary properties can be defined in hardware configuration files. Entries in the configuration file are in the form property=value, where property is the property name and value is its initial value. The configuration file approach enables devices to be configured by changing the property values.