124 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
The Linux Kernel Device Model
 | 
						|
 | 
						|
Patrick Mochel	<mochel@digitalimplant.org>
 | 
						|
 | 
						|
Drafted 26 August 2002
 | 
						|
Updated 31 January 2006
 | 
						|
 | 
						|
 | 
						|
Overview
 | 
						|
~~~~~~~~
 | 
						|
 | 
						|
The Linux Kernel Driver Model is a unification of all the disparate driver
 | 
						|
models that were previously used in the kernel. It is intended to augment the
 | 
						|
bus-specific drivers for bridges and devices by consolidating a set of data
 | 
						|
and operations into globally accessible data structures.
 | 
						|
 | 
						|
Traditional driver models implemented some sort of tree-like structure
 | 
						|
(sometimes just a list) for the devices they control. There wasn't any
 | 
						|
uniformity across the different bus types.
 | 
						|
 | 
						|
The current driver model provides a common, uniform data model for describing
 | 
						|
a bus and the devices that can appear under the bus. The unified bus
 | 
						|
model includes a set of common attributes which all busses carry, and a set
 | 
						|
of common callbacks, such as device discovery during bus probing, bus
 | 
						|
shutdown, bus power management, etc.
 | 
						|
 | 
						|
The common device and bridge interface reflects the goals of the modern
 | 
						|
computer: namely the ability to do seamless device "plug and play", power
 | 
						|
management, and hot plug. In particular, the model dictated by Intel and
 | 
						|
Microsoft (namely ACPI) ensures that almost every device on almost any bus
 | 
						|
on an x86-compatible system can work within this paradigm.  Of course,
 | 
						|
not every bus is able to support all such operations, although most
 | 
						|
buses support most of those operations.
 | 
						|
 | 
						|
 | 
						|
Downstream Access
 | 
						|
~~~~~~~~~~~~~~~~~
 | 
						|
 | 
						|
Common data fields have been moved out of individual bus layers into a common
 | 
						|
data structure. These fields must still be accessed by the bus layers,
 | 
						|
and sometimes by the device-specific drivers.
 | 
						|
 | 
						|
Other bus layers are encouraged to do what has been done for the PCI layer.
 | 
						|
struct pci_dev now looks like this:
 | 
						|
 | 
						|
struct pci_dev {
 | 
						|
	...
 | 
						|
 | 
						|
	struct device dev;     /* Generic device interface */
 | 
						|
	...
 | 
						|
};
 | 
						|
 | 
						|
Note first that the struct device dev within the struct pci_dev is
 | 
						|
statically allocated. This means only one allocation on device discovery.
 | 
						|
 | 
						|
Note also that that struct device dev is not necessarily defined at the
 | 
						|
front of the pci_dev structure.  This is to make people think about what
 | 
						|
they're doing when switching between the bus driver and the global driver,
 | 
						|
and to discourage meaningless and incorrect casts between the two.
 | 
						|
 | 
						|
The PCI bus layer freely accesses the fields of struct device. It knows about
 | 
						|
the structure of struct pci_dev, and it should know the structure of struct
 | 
						|
device. Individual PCI device drivers that have been converted to the current
 | 
						|
driver model generally do not and should not touch the fields of struct device,
 | 
						|
unless there is a compelling reason to do so.
 | 
						|
 | 
						|
The above abstraction prevents unnecessary pain during transitional phases.
 | 
						|
If it were not done this way, then when a field was renamed or removed, every
 | 
						|
downstream driver would break.  On the other hand, if only the bus layer
 | 
						|
(and not the device layer) accesses the struct device, it is only the bus
 | 
						|
layer that needs to change.
 | 
						|
 | 
						|
 | 
						|
User Interface
 | 
						|
~~~~~~~~~~~~~~
 | 
						|
 | 
						|
By virtue of having a complete hierarchical view of all the devices in the
 | 
						|
system, exporting a complete hierarchical view to userspace becomes relatively
 | 
						|
easy. This has been accomplished by implementing a special purpose virtual
 | 
						|
file system named sysfs.
 | 
						|
 | 
						|
Almost all mainstream Linux distros mount this filesystem automatically; you
 | 
						|
can see some variation of the following in the output of the "mount" command:
 | 
						|
 | 
						|
$ mount
 | 
						|
...
 | 
						|
none on /sys type sysfs (rw,noexec,nosuid,nodev)
 | 
						|
...
 | 
						|
$
 | 
						|
 | 
						|
The auto-mounting of sysfs is typically accomplished by an entry similar to
 | 
						|
the following in the /etc/fstab file:
 | 
						|
 | 
						|
none     	/sys	sysfs    defaults	  	0 0
 | 
						|
 | 
						|
or something similar in the /lib/init/fstab file on Debian-based systems:
 | 
						|
 | 
						|
none            /sys    sysfs    nodev,noexec,nosuid    0 0
 | 
						|
 | 
						|
If sysfs is not automatically mounted, you can always do it manually with:
 | 
						|
 | 
						|
# mount -t sysfs sysfs /sys
 | 
						|
 | 
						|
Whenever a device is inserted into the tree, a directory is created for it.
 | 
						|
This directory may be populated at each layer of discovery - the global layer,
 | 
						|
the bus layer, or the device layer.
 | 
						|
 | 
						|
The global layer currently creates two files - 'name' and 'power'. The
 | 
						|
former only reports the name of the device. The latter reports the
 | 
						|
current power state of the device. It will also be used to set the current
 | 
						|
power state. 
 | 
						|
 | 
						|
The bus layer may also create files for the devices it finds while probing the
 | 
						|
bus. For example, the PCI layer currently creates 'irq' and 'resource' files
 | 
						|
for each PCI device.
 | 
						|
 | 
						|
A device-specific driver may also export files in its directory to expose
 | 
						|
device-specific data or tunable interfaces.
 | 
						|
 | 
						|
More information about the sysfs directory layout can be found in
 | 
						|
the other documents in this directory and in the file 
 | 
						|
Documentation/filesystems/sysfs.txt.
 | 
						|
 |