The system(4) file in the /etc directory enables you to set the value of kernel variables at boot time. With kernel variables, you can toggle different behaviors in a driver and take advantage of debugging features that are provided by the kernel. The kernel variables moddebug and kmem_flags, which can be very useful in debugging, are discussed later in this section. See also Using the Deadman Feature.
Changes to kernel variables after boot are unreliable, because /etc/system is read only once when the kernel boots. After this file is modified, the system must be rebooted for the changes to take effect. If a change in the file causes the system not to work, boot with the ask (-a) option. Then specify /dev/null as the system file.
The set command changes the value of module or kernel variables. To set module variables, specify the module name and the variable:
For example, to set the variable test_debug in a driver that is named myTest, use set as follows:
% set myTest:test_debug=1
To set a variable that is exported by the kernel itself, omit the module name.
You can also use a bitwise OR operation to set a value, for example:
% set moddebug | 0x80000000
The commands modload(1M), modunload(1M), and modinfo(1M) can be used to add test modules, which is a useful technique for debugging and stress-testing drivers. These commands are generally not needed in normal operation, because the kernel automatically loads needed modules and unloads unused modules. The moddebug kernel variable works with these commands to provide information and set controls.
Use modload(1M) to force a module into memory. The modload command verifies that the driver has no unresolved references when that driver is loaded. Loading a driver does not necessarily mean that the driver can attach. When a driver loads successfully, the driver's _info(9E) entry point is called. The attach() entry point is not necessarily called.
Use modinfo(1M) to confirm that the driver is loaded.Example 126 Using modinfo to Confirm a Loaded Driver
$ modinfo Id Loadaddr Size Info Rev Module Name 6 101b6000 732 - 1 obpsym (OBP symbol callbacks) 7 101b65bd 1acd0 226 1 rpcmod (RPC syscall) 7 101b65bd 1acd0 226 1 rpcmod (32-bit RPC syscall) 7 101b65bd 1acd0 1 1 rpcmod (rpc interface str mod) 8 101ce8dd 74600 0 1 ip (IP STREAMS module) 8 101ce8dd 74600 3 1 ip (IP STREAMS device) ... $ modinfo | grep mydriver 169 781a8d78 13fb 0 1 mydriver (Test Driver 1.5)
The number in the info field is the major number that has been chosen for the driver. The modunload(1M) command can be used to unload a module if the module ID is provided. The module ID is found in the left column of modinfo output.
Sometimes a driver does not unload as expected after a modunload is issued, because the driver is determined to be busy. This situation occurs when the driver fails detach(9E), either because the driver really is busy, or because the detach entry point is implemented incorrectly.
To remove all of the currently unused modules from memory, run modunload(1M) with a module ID of 0:
# modunload -i 0
The moddebug kernel variable controls the module loading process. The possible values of moddebug are:
Prints messages to the console when loading or unloading modules.
Gives more detailed error messages.
Prints more detail when loading or unloading, such as including the address and size.
No auto-unloading drivers. The system does not attempt to unload the device driver when the system resources become low.
No auto-unloading streams. The system does not attempt to unload the STREAMS module when the system resources become low.
No auto-unloading of kernel modules of any type.
If running with kmdb, moddebug causes a breakpoint to be executed and a return to kmdb immediately before each module's _init() routine is called. This setting also generates additional debug messages when the module's _info() and _fini() routines are executed.
The kmem_flags kernel variable enables debugging features in the kernel's memory allocator. Set kmem_flags to 0xf to enable the allocator's debugging features. These features include runtime checks to find the following code conditions:
Writing to a buffer after the buffer is freed
Using memory before the memory is initialized
Writing past the end of a buffer
The Oracle Solaris Modular Debugger Guide describes how to use the kernel memory allocator to analyze such problems.