Writing Device Drivers
この本のみを検索
PDF 文書ファイルをダウンロードする

Loading and Unloading Drivers

12

This chapter describes the procedure for installing a device driver in the system, and for dynamically loading and unloading a device driver during testing and development.

Preparing for Installation

Before the driver is actually installed, all necessary files must be prepared. The drivers module name must either match the name of the device nodes, or the system must be informed that other names should be managed by this driver. The driver must then be properly compiled, and a configuration file must be created if necessary.

Module Naming

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, a dev_info node for a device named "wombat" is handled by a driver module called wombat in a subdirectory called drv (resulting in drv/wombat) found in the module path.
If the driver should 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.

Compile and Link the Driver

Compile each driver source file and link the resulting object files into a driver module. For a driver called xx that has two C-language source files the following commands are appropriate:

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

The _KERNEL symbol must be defined while compiling kernel (driver) code. No other symbols (such as sun4c or sun4m) should be defined, other than driver private symbols. DEBUG may also be defined to enable any calls to ASSERT(9F). There is also no need to use the -I flag for the standard headers.
Once the driver is stable, optimization flags can be used. For SPARCompilers 2.0.1 and ProCompilers 2.0.1, the normal -O flag, or its equivalent -xO2, may be used. Note that -xO2 is the highest level of optimization device drivers should use (see cc(1)).

Note - Running "ld -r" is necessary even if there is only one object module.

Write a Hardware Configuration File

If the device is non-self-identifying, the kernel requires a hardware configuration file for it. If the driver is called xx, the hardware configuration file for it should be called xx.conf. See driver.conf(4), isa(4), pseudo(4), sbus(4), scsi(4) and vme(4) for more information on hardware configuration files.
Arbitrary properties can be defined in hardware configuration files by adding entries of the form property=value, where property is the property name, and value is its initial value. This allows devices to be configured by changing the property values.

Installing and Removing Drivers

Before a driver can be used, the system must be informed that it exists. The add_drv(1M) utility must be used to correctly install the device driver. Once the driver is installed, it can be loaded and unloaded from memory without using add_drv(1M) again.

Copy the Driver to a Module Directory

The driver and its configuration file must be copied to a drv directory in the module path. Usually, this is /usr/kernel/drv:

  $ su  
  # cp xx /usr/kernel/drv  
  # cp xx.conf /usr/kernel/drv  

During development, it may be convenient to add the development directory to the module path that the kernel searches by adding a line to /etc/system:
moddir: /kernel:/usr/kernel:/new-mod-dir

Optionally Edit /etc/devlink.tab

If the driver creates minor nodes that do not represent disks, tapes, or ports (terminal devices), /etc/devlink.tab can be modified to cause devlinks(1M) to create logical device names in /dev. See devlink.tab(4) for a description of the syntax of this file.
Alternatively, logical names can be created by a program run at driver installation time.

Run add_drv(1M)

Run add_drv(1M) to install the driver in the system. If the driver installs successfully, add_drv(1M) will run disks(1M), tapes(1M), ports(1M), and devlinks(1M) to create the logical names in /dev.

    # add_drv xx  

This is a simple case in which the device identifies itself as "xx" and the device special files will have default ownership and permissions (0600 root sys). add_drv(1M) also allows additional names for the device (aliases) to be specified. See add_drv(1M) to determine how to add aliases and set file permissions explicitly.

Note - add_drv(1M) should not be run when installing a STREAMS module. See the STREAMS Programmer's Guide for details.

Removing the Driver

To remove a driver from the system, use rem_drv(1M), then delete the driver module and configuration file from the module path. The driver cannot be used again until it is reinstalled with add_drv(1M).

Loading Drivers

Opening a special file associated with the device driver causes the driver to be loaded. modload(1M) can also be used to load the driver into memory, but does not call any routines in the module. Opening the device is the preferred method.

Getting the Driver Module's ID

Individual drivers can be unloaded by module id. To determine the module id assigned to a driver, use modinfo(1M). Find the driver's name in the output. The first column of that entry is the driver's module ID

  # modinfo  
  Id  Loadaddr     Size     Info     Rev      Module Name  
  ...  
  124 ff211000     1df4     101      1        xx (xx driver v1.0)  

The number in the Info field is the major number chosen for the driver.

Unloading Drivers

Normally, the system automatically unloads device drivers when they are no longer in use. During development, it may be necessary to use modunload(1M) to unload the driver before installing a new version. In order for modunload(1M) to be successful, the device driver must not be active; there must be no outstanding references to the device, such as through open(2) or mmap(2).
Use modunload(1M) like this to unload a driver from the system:

  # modunload -i module_id  

In addition to being inactive, the driver must have working detach(9E) and _fini(9E) routines for modunload(1M) to succeed.
To unload all currently unloadable modules, specify module ID zero:

  # modunload -i 0