PSE Configuration Routines

To support dynamic loading and unloading, each PSE extension must provide a configuration routine. This routine is called each time the extension is referenced in a load or unload operation.

For more information about kernel extension configuration routine, see the sysconfig subroutine topic. However, PSE requires additional logic to successfully configure an extension.

To establish the linkage between PSE and the extension, the extension configuration routine must eventually call the str_install utility. This utility performs the internal operations necessary to add or remove the extension from PSE internal tables.

The following code fragment provides an example of a minimal configuration routine for a driver called dgb. Device-specific configuration and initialization logic can be added as necessary. The dgb_config entry point defines and initializes the strconf_t structure required by the str_install utility. In this example, the dgb_config operation retrieves the argument pointed to by the uiop parameter and uses it as an example of usage. An extension may ignore the argument. The major number is required for drivers and is retrieved from the dev parameter. Because the dgb driver requires no initialization, its last step is to perform the indicated operation by calling the str_install utility. Other drivers may need to perform other initialization steps either before or after calling the str_install utility.


#include <sys/device.h>          /* for the CFG_* constants */
#include <sys/strconf.h>         /* for the STR_* constants */
dgb_config(dev, cmd, uiop)
      dev_t dev;
      int cmd;
      struct uio *uiop;
{
      char buf[FMNAMESZ+1];
      static strconf_t conf = {
                "dgb", &dgbinfo, STR_NEW_OPEN,
      };
      if (uiomove(buf, sizeof buf, UIO_WRITE, uiop))
                return EFAULT;
      buf[FMNAMESZ] = 0;
      conf.sc_name = buf;
      conf.sc_major = major(dev);
      switch (cmd) {
      case CFG_INIT:  return str_install(STR_LOAD_DEV, &conf);
      case CFG_TERM:  return str_install(STR_UNLOAD_DEV, &conf);
      default:   return EINVAL;
      }
}
A module configuration routine is similar to the driver routine, except a major number is not required and the calling convention is slightly different. The following code fragment provides an example of a minimal complete configuration routine:

#include <sys/device.h>
#include <sys/strconf.h>
/* ARGSUSED */
aoot_config(cmd, uiop)
       int cmd;
       struct uio *uiop;
{
       static strconf_t conf = {
               "aoot", &aootinfo, STR_NEW_OPEN,
       };
       /* uiop ignored */
       switch (cmd) {
       case CFG_INIT:  return str_install(STR_LOAD_MOD, &conf);
       case CFG_TERM:  return str_install(STR_UNLOAD_MOD, &conf);
       default:        return EINVAL;
       }
}
For the strload command to successfully install an extension, the configuration routine of each extension must be marked as the entry point. Assuming the extension exists in a file called dgb.c, and has a configuration routine named dgb_config, a PSE object named dgb can be created by the following commands:

cc -c dgb.c
ld -o dgb dgb.o -edgb_config -bimport:/lib/pse.exp -lcsys
A driver extension created in such a manner can be installed with the following command:

strload -d dgb
and removed with the following command:

strload -u -d dgb