Driver Initialization
- The kernel loads the device driver into kernel space and calls
the driver's _init() routine (which must exist). The _init()
function creates a mutex lock (for later use) and then calls
the kernel routine mod_install() which does some housekeeping,
allocation of kernel data structures, and does run-time linking
to resolve any entries from the driver symbol table against
the kernel symbol table.
- The driver then stays in this state until it is probed by
the autoconfiguration code in the kernel (which is usually
initiated with the drvconfig command). The kernel looks up
the driver-specific attach function through the dev_ops structure
(which must exist) and winds up calling perfmon_attach().
- The perfmon_attach() function calls ddi_create_minor_node()
which creates the device node (using the major device number
found for the driver in /etc/name_to_major) under the /devices
directory. Assuming that the driver attach succeeded, perfmon_attach()
calls perfmon_init() which finishes up driver initialization.
- Inside of perfmon_init(), all CPUs are told to execute a function
which turns off the upper bit of the TICK register. This allows
non-privileged code to access the TICK register. The actual
mechanism used to accomplish this is a cross-call (xc_all()).
This sends a software interrupt packet to all CPUs directing
them to run a given function, which in our case clears the
upper bit of the TICK register.