Writing Device Drivers

Using the kmdb Kernel Debugger

The kmdb debugger is an interactive kernel debugger that provides the following capabilities:

This section assumes that you are already familiar with the kmdb debugger. The focus in this section is on kmdb capabilities that are useful in device driver design. To learn how to use kmdb in detail, refer to the kmdb(1) man page and to the Oracle Solaris Modular Debugger Guide. If you are familiar with kadb, refer to the kadb(1M) man page for the major differences between kadb and kmdb.

The kmdb debugger can be loaded and unloaded at will. Instructions for loading and unloading kmdb are in the Solaris Modular Debugger Guide. For safety and convenience, booting with an alternate kernel is highly encouraged. The boot process is slightly different between the SPARC platform and the x86 platform, as described in this section.


Note –

By default, kmdb uses the CPU ID as the prompt when kmdb is running. In the examples in this chapter [0] is used as the prompt unless otherwise noted.


Booting kmdb With an Alternate Kernel on the SPARC Platform

Use either of the following commands to boot a SPARC system with both kmdb and an alternate kernel:


boot kmdb -D kernel.test/sparcv9/unix 
boot kernel.test/sparcv9/unix -k

Booting kmdb With an Alternate Kernel on the x86 Platform

Use either of the following commands to boot an x86 system with both kmdb and an alternate kernel:


b kmdb -D kernel.test/unix 
b kernel.test/unix -k

Setting Breakpoints in kmdb

Use the bp command to set a breakpoint, as shown in the following example.


Example 22–7 Setting Standard Breakpoints in kmdb


[0]> myModule`myBreakpointLocation::bp
        

If the target module has not been loaded, then an error message that indicates this condition is displayed, and the breakpoint is not created. In this case you can use a deferred breakpoint. A deferred breakpoint activates automatically when the specified module is loaded. Set a deferred breakpoint by specifying the target location after the bp command. The following example demonstrates a deferred breakpoint.


Example 22–8 Setting Deferred Breakpoints in kmdb


[0]>::bp myModule`myBreakpointLocation       

For more information on using breakpoints, see the Solaris Modular Debugger Guide. You can also get help by typing either of the following two lines:


> ::help bp
> ::bp dcmd

kmdb Macros for Driver Developers

The kmdb(1M) debugger supports macros that can be used to display kernel data structures. Use $M to display kmdb macros. Macros are used in the form:


[ address ] $<macroname

Note –

Neither the information displayed by these macros nor the format in which the information is displayed, constitutes an interface. Therefore, the information and format can change at any time.


The kmdb macros in the following table are particularly useful to developers of device drivers. For convenience, legacy macro names are shown where applicable.

Table 22–1 kmdb Macros

Dcmd 

Legacy Macro 

Description 

::devinfo

devinfo

devinfo_brief

devinfo.prop

Print a summary of a device node 

::walk devinfo_parents

devinfo.parent

Walk the ancestors of a device node 

::walk devinfo_sibling

devinfo.sibling

Walk the siblings of a device node 

::minornodes

devinfo.minor

Print the minor nodes that correspond to the given device node 

::major2name

 

Print the name of a device that is bound to a given device node. 

::devbindings

 

Print the device nodes that are bound to a given device node or major number. 

The ::devinfo dcmd displays a node state that can have one of the following values:

DS_ATTACHED

The driver's attach(9E) routine returned successfully.

DS_BOUND

The node is bound to a driver, but the driver's probe(9E) routine has not yet been called.

DS_INITIALIZED

The parent nexus has assigned a bus address for the driver. The implementation-specific initializations have been completed. The driver's probe(9E) routine has not yet been called at this point.

DS_LINKED

The device node has been linked into the kernel's device tree, but the system has not yet found a driver for this node.

DS_PROBED

The driver's probe(9E) routine returned successfully.

DS_READY

The device is fully configured.