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

Document Information

Preface

1.  Introduction to Device Drivers

2.  Template Driver Example

3.  Reading and Writing Data in Kernel Memory

Displaying Data Stored in Kernel Memory

Writing Quote Of The Day Version 1

Building, Installing, and Using Quote Of The Day Version 1

Displaying Data on Demand

Writing Quote Of The Day Version 2

Managing Device State

Initializing and Unloading

Attaching and Detaching

Opening the Device, Closing the Device, and Getting Module Information

Reading the Data

Checking Data Validity

Quote Of The Day Version 2 Source

Building, Installing, and Using Quote Of The Day Version 2

Modifying Data Stored in Kernel Memory

Writing Quote Of The Day Version 3

Attaching, Allocating Memory, and Initializing a Mutex and a Condition Variable

Checking for Changes, Cleaning Up, and Detaching

Allocating and Freeing Kernel Memory

Managing Thread Synchronization

Locking Rules for Quote Of The Day Version 3

Lock and Condition Variable Members of the State Structure

Creating and Destroying Locks and Condition Variables

Waiting on Signals

Writing New Data

Reporting and Setting Device Size and Re-initializing the Device

Quote Of The Day Version 3 Source

Building and Installing Quote Of The Day Version 3

Using Quote Of The Day Version 3

Reading the Device

Writing the Device

Exercising the Driver's I/O Controls

4.  Tips for Developing Device Drivers

Index

Displaying Data Stored in Kernel Memory

The pseudo device driver presented in this section writes a constant string to a system log when the driver is loaded.

This first version of the Quote Of The Day driver (qotd_1) is even more simple than the dummy driver from the previous chapter. The dummy driver includes all functions that are required to drive hardware. This qotd_1 driver includes only the bare minimum functions it needs to make a string available to a user command. For example, this qotd_1 driver has no cb_ops(9S) structure. Therefore, this driver defines no open(9E), close(9E), read(9E), or write(9E) function. If you examine the dev_ops(9S) structure for this qotd_1 driver, you see that no getinfo(9E), attach(9E), or detach(9E) function is defined. This driver contains no function declarations because all the functions that are defined in this driver are declared in the modctl.h header file. You must include the modctl.h header file in your qotd_1.c file.

This qotd_1 driver defines a global variable to hold its text data. The _init(9E) entry point for this driver uses the cmn_err(9F) function to write the string to a system log. The dummy driver also uses the cmn_err(9F) function to display messages. The qotd_1 driver is different from the dummy driver because the qotd_1 driver stores its string in kernel memory.

Writing Quote Of The Day Version 1

Enter the source code shown in the following example into a text file named qotd_1.c.

Example 3-1 Quote Of The Day Version 1 Source File

#include <sys/modctl.h>
#include <sys/conf.h>
#include <sys/devops.h>
#include <sys/cmn_err.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>

#define QOTD_MAXLEN     128

static const char qotd[QOTD_MAXLEN]
        = "Be careful about reading health books. \
You may die of a misprint. - Mark Twain\n";

static struct dev_ops qotd_dev_ops = {
        DEVO_REV,               /* devo_rev */
        0,                      /* devo_refcnt */
        ddi_no_info,            /* devo_getinfo */
        nulldev,                /* devo_identify */
        nulldev,                /* devo_probe */
        nulldev,                /* devo_attach */
        nulldev,                /* devo_detach */
        nodev,                  /* devo_reset */
        (struct cb_ops *)NULL,  /* devo_cb_ops */
        (struct bus_ops *)NULL, /* devo_bus_ops */
        nulldev,                /* devo_power */
        ddi_quiesce_not_needed, /* devo_quiesce */
};

static struct modldrv modldrv = {
        &mod_driverops,
        "Quote of the Day 1.0",
        &qotd_dev_ops};

static struct modlinkage modlinkage = {
        MODREV_1,
        (void *)&modldrv,
        NULL
};

int
_init(void)
{
        cmn_err(CE_CONT, "QOTD: %s\n", qotd);
        return (mod_install(&modlinkage));
}

int
_info(struct modinfo *modinfop)
{
        return (mod_info(&modlinkage, modinfop));
}
int
_fini(void)
{
        return (mod_remove(&modlinkage));
}

Enter the configuration information shown in the following example into a text file named qotd_1.conf.

Example 3-2 Quote Of The Day Version 1 Configuration File

name="qotd_1" parent="pseudo" instance=0;

Building, Installing, and Using Quote Of The Day Version 1

Compile and link the driver. Use the -D_KERNEL option to indicate that this code defines a kernel module. The following example shows compiling and linking for a 32-bit architecture using the Oracle Solaris Studio C compiler:

% cc -D_KERNEL -c qotd_1.c
% ld -r -o qotd_1 qotd_1.o

Note that the name of the driver, qotd_1, must match the name property in the configuration file.

Make sure you are user root when you install the driver.

Copy the driver binary to the /tmp directory as discussed in Device Driver Testing Tips.

# cp qotd_1 /tmp
# ln -s /tmp/qotd_1 /usr/kernel/drv/qotd_1

Copy the configuration file to the kernel driver area of the system.

# cp qotd_1.conf /usr/kernel/drv

This qotd_1 driver writes a message to a system log each time the driver is loaded. The cmn_err(9F) function writes low priority messages such as the message defined in this qotd_1 driver to /dev/log. The syslogd(1M) daemon reads messages from /dev/log and writes low priority messages to /var/adm/messages.

To test this driver, watch for the message in /var/adm/messages. In a separate window, enter the following command:

% tail -f /var/adm/messages

Make sure you are user root when you load the driver. Use the add_drv(1M) command to load the driver:

# add_drv qotd_1

You should see the following messages in the window where you are viewing /var/adm/messages:

date time machine pseudo: [ID 129642 kern.info] pseudo-device: devinfo0
date time machine genunix: [ID 936769 kern.info] devinfo0 is /pseudo/devinfo@0
date time machine qotd: [ID 197678 kern.notice] QOTD_1: Be careful about
reading health books. You may die of a misprint. - Mark Twain

This last line is the content of the variable output by the cmn_err(9F) function in the _init(9E) entry point. The _init(9E) entry point is called when the driver is loaded.