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 Sun 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.