Devices as Files
In UNIX, almost everything can be treated as a file. UNIX user
applications access devices as if the devices were files. Files that represent devices are
called special files or device nodes. Device special files are divided into two classes: block
devices and character devices. See Character and Block Devices for more information.
Every I/O service request initially refers to a named file. Most I/O operations
that read or write data perform equally well on ordinary or special files.
For example, the same read(2) system call reads bytes from a file
created with a text editor and reads bytes from a terminal device.
Control signals also are handled as files. Use the ioctl(9E) function to
manipulate control signals.
Devices Directories
The Solaris OS includes both /dev and /devices directories for device drivers. Almost
all the drivers in the /dev directory are links to the /devices directory.
The /dev directory is UNIX standard. The /devices directory is specific to the Solaris
OS.
By convention, file names in the /dev directory are more readable. For example,
the /dev directory might contain files with names such as kdb and mouse
that are links to files such as /devices/pseudo/conskbd@0:kbd and /devices/pseudo/consms@0:mouse. The prtconf(1M) command
shows device names that are very similar to the file names in the
/devices directory. In the following example, only selected output of the command is
shown.
% prtconf -P
conskbd, instance #0
consms, instance #0
Entries in the /dev directory that are not links to the /devices directory
are device nodes or special files created by mknod(1M) or mknod(2). These are
zero-length files that just have a major number and minor number attached to
them. Linking to the physical name of the device in the /devices directory is
preferred to using mknod(1M).
Prior to the Solaris 10 OS, /devices was an on-disk filesystem composed of
subdirectories and files. Beginning with the Solaris 10 OS, /devices is a
virtual filesystem that creates these subdirectories and special files on demand.
For more information about the devices file system, see the devfs(7FS) man page.
Device Tree
The device files in the /devices directory are also called the device tree.
The device tree shows relationships among devices. In the device tree, a directory
represents a nexus device. A nexus is a device that can be a
parent of other devices. In the following example, pci@1f,0 is a nexus device.
Only selected output from the command is shown.
# ls -l /devices
drwxr-xr-x 4 root sys 512 date time pci@1f,0/
crw------- 1 root sys 111,255 date time pci@1f,0:devctl
You can use prtconf(1M) or prtpicl(1M) to see a graphic representation of the
device tree. See Overview of the Device Tree in Writing Device Drivers for more information about the device tree.
Character and Block Devices
A file in the device tree that is not a directory represents
either a character device or a block device.
A block device can contain addressable, reusable data. An example of a block
device is a file system. Any device can be a character device. Most
block devices also have character interfaces. Disks have both block and character interfaces.
In your /devices/pseudo directory, you might find devices such as the following:
brw-r----- 1 root sys 85, 0 Nov 3 09:43 md@0:0,0,blk
crw-r----- 1 root sys 85, 0 Nov 3 09:43 md@0:0,0,raw
brw-r----- 1 root sys 85, 1 Nov 3 09:43 md@0:0,1,blk
crw-r----- 1 root sys 85, 1 Nov 3 09:43 md@0:0,1,raw
brw-r----- 1 root sys 85, 2 Nov 3 09:43 md@0:0,2,blk
crw-r----- 1 root sys 85, 2 Nov 3 09:43 md@0:0,2,raw
Block devices have a b as the first character of their file mode.
Character devices have a c as the first character of their file mode.
In this example, the block devices have blk in their names and
the character devices have raw in their names.
The md(7D) device is a metadevice that provides disk services. The block devices
access the disk using the system's normal buffering mechanism. The character devices provide
for direct transmission between the disk and the user's read or write buffer.
Device Names
This section shows a complex device name and explains the meaning of each
part of the name in /dev and also in /devices. The following
example is the name of a disk slice:
/dev/dsk/c0t0d0s7 -> ../../devices/pci@1c,600000/scsi@2/sd@0,0:h
First, examine the name of the file in the /dev directory. These names
are managed by the devfsadmd(1M) daemon.
- c0
Controller 0
- t0
Target 0. On SCSI controllers, this value is the disk number.
- d0
SCSI LUN. This value indicates a virtual partitioning of a target or single physical device.
- s7
Slice 7 on the target 0 disk.
For the same device, compare the name of the file in the
/devices directory. These names show the physical structure and real device names. Note
that some of the components of the device name in the /devices
directory are subdirectories.
- pci@1c,600000
PCI bus at address 1c,600000. These addresses are meaningful only to the parent device.
- scsi@2
SCSI controller at address 2 on the PCI bus at address 1c,600000. This name corresponds to the c0 in /dev/dsk/c0t0d0s7.
- sd@0,0
SCSI disk at address 0,0 on the SCSI controller at address 2. This name represents target 0, LUN 0 and corresponds to the t0d0 in /dev/dsk/c0t0d0s7. The sd name and driver can also apply to IDE CD-ROM devices.
- sd@0,0:h
Minor node h on the SCSI disk at address 0,0. This name corresponds to the s7 in /dev/dsk/c0t0d0s7.
Device Numbers
A device number identifies a particular device and minor node in the device tree.
The dev_t parameter that is required in many DDI/DKI routines is this device
number.
Each device has a major number and a minor number. A device number
is a major,minor pair. A long file listing shows the device number in
the column where file sizes are usually listed. In the following example, the
device number is 86,255. The device major number is 86, and the device
minor number is 255.
% ls -l /devices/pci@0,0:devctl
crw------- 1 root sys 86,255 date time /devices/pci@0,0:devctl
In the Solaris OS, the major number is chosen for you when
you install the driver so that it will not conflict with any other
major number. The kernel uses the major number to associate the I/O request
with the correct driver code. The kernel uses this association to decide which
driver to execute when the user reads or writes the device file. All
devices and their major numbers are listed in the file /etc/name_to_major.
% grep 86 /etc/name_to_major
pci 86
The minor number is assigned in the driver. The minor number must map
each driver to a specific device instance. Minor numbers usually refer to sub-devices. For
example, a disk driver might communicate with a hardware controller device that has
several disk drives attached. Minor nodes do not necessarily have a physical representation.
The following example shows instances 0, 1, and 2 of the md
device. The numbers 0, 1, and 2 are the minor numbers.
brw-r----- 1 root sys 85, 0 Nov 3 09:43 md@0:0,0,blk
crw-r----- 1 root sys 85, 0 Nov 3 09:43 md@0:0,0,raw
brw-r----- 1 root sys 85, 1 Nov 3 09:43 md@0:0,1,blk
crw-r----- 1 root sys 85, 1 Nov 3 09:43 md@0:0,1,raw
brw-r----- 1 root sys 85, 2 Nov 3 09:43 md@0:0,2,blk
crw-r----- 1 root sys 85, 2 Nov 3 09:43 md@0:0,2,raw
In the name sd@0,0:h,, h represents a minor node. When the driver receives
a request for minor node h, the driver actually receives a corresponding minor
number. The driver for the sd node interprets that minor number to be
a particular section of disk, such as slice 7 mounted on /export.
Chapter 2, Template Driver Example shows how to use the ddi_get_instance(9F) routine in your driver to
get an instance number for the device you are driving.