Overview of the Device Tree
Devices in the Solaris OS are represented as a tree of interconnected device
information nodes. The device tree describes the configuration of loaded devices for a
particular machine.
Device Tree Components
The system builds a tree structure that contains information about the devices connected
to the machine at boot time. The device tree can also be modified
by dynamic reconfiguration operations while the system is in normal operation. The tree
begins at the root device node, which represents the platform.
Below the root node are the branches of the device tree. A
branch consists of one or more bus nexus devices and a terminating
leaf device.
A bus nexus device provides bus mapping and translation services to subordinate devices in the
device tree. PCI - PCI bridges, PCMCIA adapters, and SCSI
HBAs are all examples of nexus devices. The discussion of writing drivers
for nexus devices is limited to the development of SCSI HBA drivers (see
Chapter 18, SCSI Host Bus Adapter Drivers).
Leaf devices are typically peripheral devices such as disks, tapes, network adapters, frame buffers,
and so forth. Leaf device drivers export the traditional character driver interfaces
and block driver interfaces. The interfaces enable user processes to read data from
and write data to either storage or communication devices.
The system goes through the following steps to build the tree:
The CPU is initialized and searches for firmware.
The main firmware (OpenBoot, Basic Input/Output System (BIOS), or Bootconf) initializes and creates the device tree with known or self-identifying hardware.
When the main firmware finds compatible firmware on a device, the main firmware initializes the device and retrieves the device's properties.
The firmware locates and boots the operating system.
The kernel starts at the root node of the tree, searches for a matching device driver, and binds that driver to the device.
If the device is a nexus, the kernel looks for child devices that have not been detected by the firmware. The kernel adds any child devices to the tree below the nexus node.
The kernel repeats the process from Step 5 until no further device nodes need to be created.
Each driver exports a device operations structure dev_ops(9S) to define the operations that
the device driver can perform. The device operations structure contains function pointers for
generic operations such as attach(9E), detach(9E), and getinfo(9E). The structure also contains a
pointer to a set of operations specific to bus nexus drivers and a
pointer to a set of operations specific to leaf drivers.
The tree structure creates a parent-child relationship between nodes. This parent-child relationship is
the key to architectural independence. When a leaf or bus nexus driver requires
a service that is architecturally dependent in nature, that driver requests its parent
to provide the service. This approach enables drivers to function regardless of the
architecture of the machine or the processor. A typical device tree is shown
in the following figure.
Figure 2-2 Example Device Tree
The nexus nodes can have one or more children. The leaf nodes
represent individual devices.
Displaying the Device Tree
The device tree can be displayed in three ways:
The libdevinfo library provides interfaces to access the contents of the device tree programmatically.
The prtconf(1M) command displays the complete contents of the device tree.
The /devices hierarchy is a representation of the device tree. Use the ls(1) command to view the hierarchy.
Note - /devices displays only devices that have drivers configured into the system. The prtconf(1M)
command shows all device nodes regardless of whether a driver for the device
exists on the system.
libdevinfo Library
The libdevinfo library provides interfaces for accessing all public device configuration data. See the
libdevinfo(3LIB) man page for a list of interfaces.
prtconf Command
The following excerpted prtconf(1M) command example displays all the devices in the system.
System Configuration: Sun Microsystems sun4u
Memory size: 128 Megabytes
System Peripherals (Software Nodes):
SUNW,Ultra-5_10
packages (driver not attached)
terminal-emulator (driver not attached)
deblocker (driver not attached)
obp-tftp (driver not attached)
disk-label (driver not attached)
SUNW,builtin-drivers (driver not attached)
sun-keyboard (driver not attached)
ufs-file-system (driver not attached)
chosen (driver not attached)
openprom (driver not attached)
client-services (driver not attached)
options, instance #0
aliases (driver not attached)
memory (driver not attached)
virtual-memory (driver not attached)
pci, instance #0
pci, instance #0
ebus, instance #0
auxio (driver not attached)
power, instance #0
SUNW,pll (driver not attached)
se, instance #0
su, instance #0
su, instance #1
ecpp (driver not attached)
fdthree, instance #0
eeprom (driver not attached)
flashprom (driver not attached)
SUNW,CS4231 (driver not attached)
network, instance #0
SUNW,m64B (driver not attached)
ide, instance #0
disk (driver not attached)
cdrom (driver not attached)
dad, instance #0
sd, instance #15
pci, instance #1
pci, instance #0
pci108e,1000 (driver not attached)
SUNW,hme, instance #1
SUNW,isptwo, instance #0
sd (driver not attached)
st (driver not attached)
sd, instance #0 (driver not attached)
sd, instance #1 (driver not attached)
sd, instance #2 (driver not attached)
...
SUNW,UltraSPARC-IIi (driver not attached)
SUNW,ffb, instance #0
pseudo, instance #0
/devices Directory
The /devices hierarchy provides a namespace that represents the device tree. Following is
an abbreviated listing of the /devices namespace. The sample output corresponds to the
example device tree and prtconf(1M) output shown previously.
/devices
/devices/pseudo
/devices/pci@1f,0:devctl
/devices/SUNW,ffb@1e,0:ffb0
/devices/pci@1f,0
/devices/pci@1f,0/pci@1,1
/devices/pci@1f,0/pci@1,1/SUNW,m64B@2:m640
/devices/pci@1f,0/pci@1,1/ide@3:devctl
/devices/pci@1f,0/pci@1,1/ide@3:scsi
/devices/pci@1f,0/pci@1,1/ebus@1
/devices/pci@1f,0/pci@1,1/ebus@1/power@14,724000:power_button
/devices/pci@1f,0/pci@1,1/ebus@1/se@14,400000:a
/devices/pci@1f,0/pci@1,1/ebus@1/se@14,400000:b
/devices/pci@1f,0/pci@1,1/ebus@1/se@14,400000:0,hdlc
/devices/pci@1f,0/pci@1,1/ebus@1/se@14,400000:1,hdlc
/devices/pci@1f,0/pci@1,1/ebus@1/se@14,400000:a,cu
/devices/pci@1f,0/pci@1,1/ebus@1/se@14,400000:b,cu
/devices/pci@1f,0/pci@1,1/ebus@1/ecpp@14,3043bc:ecpp0
/devices/pci@1f,0/pci@1,1/ebus@1/fdthree@14,3023f0:a
/devices/pci@1f,0/pci@1,1/ebus@1/fdthree@14,3023f0:a,raw
/devices/pci@1f,0/pci@1,1/ebus@1/SUNW,CS4231@14,200000:sound,audio
/devices/pci@1f,0/pci@1,1/ebus@1/SUNW,CS4231@14,200000:sound,audioctl
/devices/pci@1f,0/pci@1,1/ide@3
/devices/pci@1f,0/pci@1,1/ide@3/sd@2,0:a
/devices/pci@1f,0/pci@1,1/ide@3/sd@2,0:a,raw
/devices/pci@1f,0/pci@1,1/ide@3/dad@0,0:a
/devices/pci@1f,0/pci@1,1/ide@3/dad@0,0:a,raw
/devices/pci@1f,0/pci@1
/devices/pci@1f,0/pci@1/pci@2
/devices/pci@1f,0/pci@1/pci@2/SUNW,isptwo@4:devctl
/devices/pci@1f,0/pci@1/pci@2/SUNW,isptwo@4:scsi
Binding a Driver to a Device
In addition to constructing the device tree, the kernel determines the drivers that
are used to manage the devices.
Binding a driver to a device refers to the process by which
the system selects a driver to manage a particular device. The binding name
is the name that links a driver to a unique device node in
the device information tree. For each device in the device tree, the system
attempts to choose a driver from a list of installed drivers.
Each device node has an associated name property. This property can be
assigned either from an external agent, such as the PROM, during system boot
or from a driver.conf configuration file. In any case, the name property represents
the node name assigned to a device in the device tree. The node name
is the name visible in /devices and listed in the prtconf(1M) output.
Figure 2-3 Device Node Names
A device node can have an associated compatible property as well. The
compatible property contains an ordered list of one or more possible driver names
or driver aliases for the device.
The system uses both the compatible and the name properties to select
a driver for the device. The system first attempts to match the contents
of the compatible property, if the compatible property exists, to a driver on
the system. Beginning with the first driver name on the compatible property list, the
system attempts to match the driver name to a known driver on
the system. Each entry on the list is processed until the system either
finds a match or reaches the end of the list.
If the contents of either the name property or the compatible property match
a driver on the system, then that driver is bound to the device
node. If no match is found, no driver is bound to the device
node.
Generic Device Names
Some devices specify a generic device name as the value for the name
property. Generic device names describe the function of a device without actually identifying
a specific driver for the device. For example, a SCSI host bus adapter
might have a generic device name of scsi. An Ethernet device might
have a generic device name of ethernet.
The compatible property enables the system to determine alternate driver names for devices
with a generic device name, for example, glm for scsi HBA device
drivers or hme for ethernet device drivers.
Devices with generic device names are required to supply a compatible property.
Note - For a complete description of generic device names, see the IEEE 1275 Open Firmware Boot
Standard.
The following figure shows a device node with a specific device name. The
driver binding name SUNW,ffb is the same name as the device node name.
Figure 2-4 Specific Driver Node Binding
The following figure shows a device node with the generic device name
display. The driver binding name SUNW,ffb is the first name on the compatible
property driver list that matches a driver on the system driver list. In
this case, display is a generic device name for frame buffers.
Figure 2-5 Generic Driver Node Binding