10    Building and Testing a Kernel Module

This chapter discusses how to build and test a kernel module:

10.1    Producing a Single Binary Module

Before you can statically or dynamically load a kernel module, you must produce the single binary module. A single binary module is the executable image of the kernel module that can be statically or dynamically brought into the kernel. A single binary module has a file extension of .mod. To produce the single binary module, perform the steps described in the following sections.

10.1.1    Step 1: Create a Directory to Contain Kernel Module Files

Use the mkdir command to create a directory to contain the kernel module files:

# mkdir /usr/sys/ExampMod

In this example, the kernel module writer creates the directory called /usr/sys/ExampMod to contain the files related to the example kernel module. Note that the writer performs the work at the superuser prompt.

When you create your directory, replace ExampMod with a directory that reflects a name specific to your organization or company.

10.1.2    Step 2: Copy Kernel Module Files

Use the cp command to copy the files to the directory you created in Section 10.1.1:

# cd /usr/sys/ExampMod [1]
 
# cp /usr/sys/mydevelopment/example.c . [2]
 
# cp /usr/sys/mydevelopment/files .
 
# cp /usr/sys/mydevelopment/sysconfigtab .

  1. Change to the directory (in this example, the /usr/sys/ExampMod directory), into which you will copy the kernel module files. [Return to example]

  2. Copy the example.c source file associated with your kernel module to the directory you specified in Section 10.1.1 (in this example, the /usr/sys/ExampMod directory). The /usr/sys/mydevelopment directory is where the kernel module writer initially created the example.c file.

    You should have implemented the module's configure routine to follow the single binary module model (that is, your module is both static and dynamic). [Return to example]

10.1.3    Step 3: Create a BINARY.list File

Use an editor such as vi to create a BINARY.list file:

# cd /usr/sys/conf [1]
# vi BINARY.list [2]

  1. Change to the /usr/sys/conf directory. [Return to example]

  2. Use the vi or another editor to create the BINARY.list file. [Return to example]

The following example shows the contents of the BINARY.list file that the kernel module writer creates:

/usr/sys/ExampMod:

The contents is the directory path where you placed the kernel module files (see Section 10.1.1). For this example, the directory is:

/usr/sys/ExampMod:

Replace the path and source file name with the path and source file name associated with your kernel module. You must follow the path and source file name with a colon (:), as shown in the example.

10.1.4    Step 4: Run the sourceconfig Program

Run the sourceconfig program from the /usr/sys/conf directory:

# cd /usr/sys/conf [1]
# ./sourceconfig BINARY [2]

  1. Change to the /usr/sys/conf directory before running the sourceconfig program. [Return to example]

  2. Invoke the sourceconfig program followed by the BINARY configuration file name. This generates a new Makefile in the /usr/sys/BINARY directory. This Makefile contains the information necessary to compile the single binary module or modules defined in the BINARY.list file and the files file fragment. Section 10.1.3 tells you how to create a BINARY.list file in the /usr/sys/conf directory.

    Your files file fragment resides in the directory that you created in Section 10.1.1. [Return to example]

10.1.5    Step 5: Run the make Program

Run the make program from the /usr/sys/BINARY directory:

# cd /usr/sys/BINARY [1]
 
# make example.mod [2]

  1. Change to the /usr/sys/BINARY directory before running the make program. [Return to example]

  2. Invoke the make program followed by the name of your kernel module plus the .mod extension. This step creates the single binary module in the /usr/sys/BINARY directory. In the example, example.mod is the single binary module for the example module, created in the /usr/sys/BINARY directory. This step also creates a link from the /usr/sys/BINARY directory to the directory you created in Section 10.1.1.

    Invoke the make program for each module you want to compile. The appropriate links are created as described in the previous paragraph. [Return to example]

10.1.6    Step 6: Create a Kernel Configuration Development Area

Use an editor such as vi to create a sysconfigtab file fragment (see Section 10.6).

Run the doconfig program from the /usr/sys/conf directory to create a kernel configuration development area:

# cd /usr/sys/conf [1]
# doconfig [2]

  1. Change to the /usr/sys/conf directory. [Return to example]

  2. Invoke the doconfig program. [Return to example]

Enter the name of the target configuration file at the following prompt:

*** KERNEL CONFIGURATION AND BUILD PROCEDURE ***
Enter a name for the kernel configuration file. [CONRAD]: EXAMPMOD

In order to test your kernel module, enter a new name for the target configuration file. In this example, the kernel module writer enters the target configuration file name EXAMPMOD. Giving the doconfig program a new target configuration file name allows your existing target configuration file to remain on the system. You can then use the new target configuration file to configure a system that contains the kernel module you are testing.

Select the option from the menu that indicates you are adding no new kernel options.

Indicate that you do not want to edit the target configuration file in response to the following prompt:

Do you want to edit the configuration file? (y/n) [n] no

10.1.7    Step 7: Run the sysconfigdb Utility

Run the sysconfigdb utility to configure the single binary module's attributes:

# cd /usr/sys/ExampMod [1]
# sysconfigdb -a -f sysconfigtab example [2]

  1. Change to the the directory that you created in Section 10.1.1 (in this example, the /usr/sys/ExampMod directory). [Return to example]

  2. Invoke the sysconfigdb utility. In this example, the sysconfigdb utility is invoked with the following flags:

    [Return to example]

10.2    Loading and Configuring a Kernel Module

Kernel module configuration consists of the tasks necessary to incorporate modules into the kernel to make them available to other resources. Chapter 2 described two methods of kernel module configuration:

Section 10.1 describes how to create a single binary module and then how to statically and dynamically configure the kernel module into the kernel. This section discusses the following module configuration and loading operations:

Configuring the kernel module, which initializes the attribute table and registers the module's entry points, is described in Chapter 2 and Chapter 3.

10.2.1    Loading a Module into the Kernel Image

You can statically load a single binary module into the kernel as follows:

10.2.2    Loading a Kernel Module Dynamically

You can dynamically load a single binary module into the kernel as follows:

  1. Make sure your single binary module exists in the/sys/BINARY directory.

  2. Log in as superuser (the root user).

  3. Run the sysconfig -c module_name command, where module_name is the name of your kernel module.

10.3    Unconfiguring and Unloading Kernel Modules

The module framework defines the rules for preparing a kernel module to go off line (unconfiguration) and for unloading. As described in Section 2.2.2, when a kernel module's configure routine receives the CFG_OP_UNCONFIGURE request from the module framework, it prepares the module for unconfiguration and unloading. These tasks are part of the same process that initiates when the CFG_OP_UNCONFIGURE request is received. However, the results of unconfiguring and unloading are different, depending on whether your kernel module was statically loaded or dynamically loaded.

Unconfiguration can occur both at single-user and at multiuser time and only at the user's request. Only dynamically loaded kernel modules are completely removed from the system--that is, the module image is removed from the kernel. Statically loaded kernel modules are taken off line and made unavailable to other modules and system resources. When the user unconfigures and unloads a static kernel module, the module is not removed from the kernel image. In this sense, it is not really unloaded the way dynamic modules are.

Use the following command to unconfigure and unload (in the case of dynamic modules) a kernel module. Note that you must be a superuser to perform this task.

#  sysconfig -u example

10.4    Statically Configuring a Single Binary Module

After creating a single binary module, you can statically configure it into the kernel as follows:

The following sections describe the steps for each of these tasks.

10.4.1    Statically Configuring a Single Binary Module into a /vmunix Kernel

To statically configure a single binary module into a /vmunix kernel, you perform the following steps.

10.4.1.1    Step 1: Edit or Create the NAME.list File

Section 10.1.6 instructs you to create a kernel configuration development area. If your system has a /usr/sys/conf/.product.list file, then the system creates a NAME.list file. Use an editor such as vi to edit or create a NAME.list file in the /usr/sys/conf directory:

# cd /usr/sys/conf [1]
# vi example.list [2]

  1. Change to the /usr/sys/conf directory. [Return to example]

  2. Use the vi or another editor to create a NAME.list file (called example.list in this example).

    You replace NAME with the name you specified for the target configuration file in Section 10.1.6. [Return to example]

The following example shows the contents of the example.list file the kernel module writer creates:

/usr/sys/ExampMod:

The contents of your NAME.list file is the directory you created in Section 10.1.1. You must follow the path and file name with a colon (:), as shown in the example.

10.4.1.2    Step 2: Run the doconfig Program

Run the doconfig program from the /usr/sys/conf directory to rebuild the kernel. You previously created this kernel (and associated configuration development area) in Section 10.1.6.

# cd /usr/sys/conf [1]
# doconfig -c EXAMPMOD [2]

  1. Change to the /usr/sys/conf directory. [Return to example]

  2. Invoke doconfig with the -c option and replace EXAMPMOD with the name of your target configuration file. [Return to example]

Enter the name of the target configuration file at the following prompt:

*** KERNEL CONFIGURATION AND BUILD PROCEDURE ***
Enter a name for the kernel configuration file. [CONRAD]: EXAMPMOD

In order to test your kernel module, enter a new name for the target configuration file. In the example, the writer enters the target configuration file name EXAMPMOD. Giving the doconfig program a new target configuration file name allows your existing target configuration file to remain on the system. You can then use the existing target configuration file to configure a system that omits the kernel module you are testing.

Select the option from the Kernel Option Selection menu that indicates you are adding no new kernel options.

In response to the following prompt, indicate that you do not want to edit the target configuration file:

Do you want to edit the configuration file? (y/n) [n] no

10.4.1.3    Step 3: Copy the New Kernel to the Root Directory

Copy the new /vmunix kernel into the root directory:

# cd / [1]
# cp /usr/sys/EXAMPMOD/vmunix /vmunix.example [2]

  1. Change to the root directory. [Return to example]

  2. Copy the new /vmunix kernel to the root directory. You should perform a similar copy operation, replacing example with the target configuration file name you specified in Section 10.4.1.2.

    Note that the kernel module writer specifies the name vmunix.example as the name for the new kernel. This is typically done when testing the module. You should replace the name example in vmunix.example with some other appropriate name. [Return to example]

10.4.1.4    Step 4: Shut Down and Boot the System

Shut down and boot the system:

# shutdown -h now [1]
>>> boot -fi "vmunix.example" [2]

  1. Specify the shutdown command with the -h option to shut down the system. [Return to example]

  2. Specify the boot command followed by the -fi options and the name of the new kernel, replacing vmunix.example with the name of the kernel you copied to the root directory in Section 10.4.1.3.

    The kernel module product (single binary module) is now part of this new kernel. You can test it with the appropriate utilities. [Return to example]

10.5    Dynamically Configuring a Single Binary Module

This section describes the procedure to dynamically configure a single binary module into the kernel.

10.5.1    Step 1: Link to the Single Binary Module

Run the ln command to link the single binary module attributes:

# cd /var/subsys [1]
# ln -s /usr/sys/BINARY/example.mod example.mod [2]

  1. Change to the /var/subsys directory. [Return to example]

  2. Create a symbolic link. In this example, the source of the link is /usr/sys/BINARY/example.mod and the destination is example.mod.

    You should also create a symbolic link by replacing example with the name of your kernel module. [Return to example]

10.5.2    Step 2: Link to the Method File

Run the ln command to link to the method file:

# pwd [1]
/var/subsys
# ln -s /subsys/device.mth example.mth [2]

  1. Use the pwd command to make sure the working directory is /var/subsys. The pwd command displays /var/subsys, the directory you changed to in Section 10.5.1. [Return to example]

  2. Create a symbolic link. In this example, the source of the link is /subsys/device.mth and the destination is example.mth.

    You should also create a symbolic link by replacing example with the name of your kernel module. [Return to example]

10.5.3    Step 3: Run the sysconfig Utility

Use the sysconfig utility with the -c option to load the single binary module:

# sysconfig -c example

Replace example with the name of your kernel module. The -c option configures the single binary module into the kernel and creates the device special files (for device driver modules).

10.6    Creating the sysconfigtab File Fragment

Users can configure attributes at run time. Any configurable attributes, or attributes that users can query, are defined in /etc/sysconfigtab.

You should supply initial values for your kernel module's configurable attributes in a sysconfigtab file fragment. The sysconfigtab file fragment is an ASCII file. The sysconfigdb utility appends the sysconfigtab file fragment to the customer's /etc/sysconfigtab file when the kernel module is installed on the system. Using sysconfigdb ensures that users never manually edit the etc/sysconfigtab file.

Figure 10-1 shows the format of the entries in the sysconfigtab file fragment.

Figure 10-1:  Format of the sysconfigtab File Fragment

Each entry contains the following information:

The following restrictions apply to sysconfigtab file fragments:

Example 10-1 shows the sysconfigtab file fragment for a device driver kernel module (in this example, temp driver). The development tool generates all of the necessary attribute entries; only the TEMP_Developer_Debug attribute was added to the file. The sysconfigtab file fragment does not specify a value for the Device_Dir attribute. Therefore, the device special file for the temp module resides in the /dev directory.

Example 10-1:  A sysconfigtab File Fragment

# /usr/sys/io/TEMP/sysconfigtab
# sysconfigtab file fragment for temp driver
temp: [1]
        Module_Config_Name = temp    [2]
    [3]  PCI_Option =  PCI_SE_Rev - 0x210, Vendor_Id - 0x1002, Device_Id - 0x4354, Rev - 0, Base - 0, Sub - 0, Pif - 0 Sub_Vid - 0, Sub_Did - 0, Vid_Mo_Flag - 1, Did_Mo_Flag - 1, Rev_Mo_Flag - 0, Base_Mo_Flag - 0, Sub_Mo_Flag - 0, Pif_Mo_Flag - 0, Sub_Vid_Mo_Flag - 0, Sub_Did_Mo_Flag - 0, Driver_Name - temp, Type - C, Adpt_Config - N
        ISA_Option =  Board_Id - Null, Function_Name - 'TEMP' , Driver_Name - temp, Type - C, Adpt_Config - N
        EISA_Option =  Board_Id - TEMP, Function_Name - Null, Driver_Name - temp, Type - C, Adpt_Config - N
#
# Initialize driver-specific attributes
#
        TEMP_Developer_Debug = 1     [4]
 
 

  1. Indicates that the attributes that follow belong to the temp module. [Return to example]

  2. Initializes the Module_Config_Name attribute to temp. This is the string that the module framework uses to identify the configure routine and attribute table for the kernel module. [Return to example]

  3. Initializes the bus option data for the PCI, ISA, and EISA buses. The driver in this example is designed to operate on these three types of buses. [Return to example]

  4. Initializes the TEMP_Developer_Debug attirbute to 1, which turns on debugging messages. [Return to example]

10.7    Changing Attribute Values at Run Time

Users, especially system administrators, may sometimes want to change attributes. You may also need to change an attribute value during kernel module development to test features of the kernel module. The sysconfig program allows you and your users to reconfigure a kernel module with new attribute values.

For example, the temp kernel module from Section 10.6 initializes the TEMP_Developer_Debug attribute to 1 by default, which turns debugging messages on. To turn the messages off, call the sysconfig program as follows:

# sysconfig -r temp TEMP_Developer_Debug=0

Not all attributes can be changed with sysconfig. To allow an attribute to change at run time, you must assign the CFG_OP_RECONFIGURE constant to the operation member of the attribute's cfg_subsys_attr_t data structure. The sysconfig program returns an error if you try to change an attribute that does not have this operation value.

The sysconfig program calls the module framework to change the value stored in memory. The module framework then calls the kernel module's configure entry point to perform any other operations required to reconfigure the module.

10.8    Testing a Kernel Module

After you have statically or dynamically configured your module into the kernel, you should test it. There are many ways to test the functioning of your kernel module that depend on the purpose and function of your kernel module. If your module is a device driver, see Writing Device Drivers for specific information on testing device drivers. The following list provides some general suggestions for testing kernel modules: