热门关键字:  ubuntu  分区  linux系统进程  Fedora  函数
当前位置 :| 主页>Linux教程>内核研究>

The Linux Device Model

来源: 作者: 时间:2008-06-26 Tag: 点击:

The Linux Device Model

Many Linux subsystems, such as the /dev filesystem, hotplug, module autoload, and microcode download have undergone significant changes with the introduction of the new device model. Learn about udev, sysfs, kobjects, classes, and more.

The Linux 2.6 kernel features a new device model built around concepts like sysfs, kobjects, device classes, and udev. The new model makes it easier to develop device drivers by introducing C++- like abstractions that distill commonalities from device drivers into bus and core layers. It also weeds policies out of kernel space and pushes them to user space, which has resulted in a total revamp of many features, including /dev node management, hotplug, coldplug, module autoload and firmware download.
This month, let’s look at the different pieces that constiture the device model and how each piece affects key kernel subsystems. But let’s start by learning about udev with the help of some examples.

Tinkering with Udev

Years ago, when Linux was young, it wasn’t fun to administer device nodes. All the needed nodes (which could run into thousands) had to be statically created under the /dev directory. With the advent of the 2.4 kernels came devfs, which introduced dynamic device node creation. Devfs provided kernel interfaces to request generation of device nodes in an in-memory filesystem, but the onus of naming the nodes still rested with device drivers. However, device naming policy is administrative and doesn’t mix well with the kernel. Udev arrived on the scene to push device management entirely to user space.
Udev depends on the following to do its work:
1.Kernel sysfs support, which is an important part of the Linux device model. We’ll look at sysfs later on, but for now, take the corresponding sysfs file accesses for granted.
2.A set of user space daemons and utilities, such as udevd and udevinfo.
3.User-specified rules located in the /etc/udev/rules.d directory. You can write rules to get a consistent view of your devices.
To understand how to use udev, let’s start off with an example. Assume that you have a USB DVD drive and a USB CD-RW drive. Depending on the order in which you hotplug these devices, one of them is assigned the name sr0, while the other gets the name sr1. During pre-udev days, you had to figure out the associated names before you could use the devices. But with udev, you can consistently view the DVD (say, as /dev/usbdvd) and the CD-RW (say, as /dev/usbcdrw) irrespective of the order in which they are plugged in or out.
First, pull product attributes from corresponding files in sysfs. Use udevinfo to collect device information:
$ udevinfo –a –p /sys/block/sr0

looking at the device chain at
’/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4’:
BUS=”usb”
ID=”1-4″
SYSFS{bConfigurationValue}=”1″

SYSFS{idProduct}=”0701″
SYSFS{idVendor}=”05e3″
SYSFS{manufacturer}=”Genesyslogic”
SYSFS{maxchild}=”0″
SYSFS{product}=”USB Mass Storage Device”

$ udevinfo –a –p /sys/block/sr1

looking at the device chain at
’/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-3’:
BUS=”usb”
ID=”1-3″
SYSFS{bConfigurationValue}=”2″

SYSFS{idProduct}=”0302″
SYSFS{idVendor}=”0dbf”
SYSFS{manufacturer}=”Addonics”
SYSFS{maxchild}=”0″
SYSFS{product}=”USB to IDE Cable”

Now let’s use the product information gleaned above to identify the devices and add udev naming rules. Create a file called /etc/udev/rules.d/40-cdvd.rules and add the rules shown in Listing One to it.
LISTING ONE: A new file for udev configuration

BUS=”usb”, SYSFS{idProduct}=”0701″, SYSFS{idVendor}=”05e3″,
KERNEL=”sr[0-9]*”, NAME=”%k”, SYMLINK=”usbdvd”

BUS=”usb”, SYSFS{idProduct}=”0302″, SYSFS{idVendor}=”0dbf”,
KERNEL=”sr[0-9]*”, NAME=”%k”, SYMLINK=”usbcdrw”

The first rule tells udev that whenever it finds a USB device with a product ID of 0×0701, vendor ID of 0×05e3, and a device name starting with sr, it has to create a node of the same name under /dev and produce a symbolic link named usbdvd to the created node. The second rule orders the creation of a symbolic link named usbcdrw for the CD-RW drive.
To test for syntax errors in your rules, run udevtest on /sys/block/sr1. To turn on verbose messages to /var/log/messages, set udev_log to yes in /etc/udev/udev.conf. To repopulate the /dev directory with the newly-added rules, restart udev using udevstart.
Once all of this is done, your DVD will consistently appear as /dev/usbdvd to the system, while your CD-RW drive will always appear as /dev/usbcdrw. Moreover, you can confidently mount them from shell scripts using commands like mount /dev/usbdvd /mnt/dvd.
Consistent naming of device nodes (and network interfaces) is not the sole capability of udev. Indeed, udev has metamorphosed into the Linux hotplug manager as well. Udev is also in charge of automatically loading modules on demand, and downloading microcode onto devices that need them. But before digging into those capabilities, let’s get a basic understanding of the innards of the device model.

Kobjects, Sysfs, and Device Classes

Kobjects, sysfs, and device classes are the building blocks of the device model, but are publicity shy and prefer to remain behind the scene. Each is almost exclusively in the usage domain of bus and core implementations, and hide inside APIs that provide services to device drivers.
Kobjects introduce an encapsulation of common object properties, like usage reference counts. They are usually embedded inside larger structures. If you look at the definition of a kobject in include/linux/kobject.h, you’ll notice two interesting fields:
1.A pointer to a kset, which is an object set to which the kobject belongs.
2.A ktype, which is an object type that describes the kobject.
Kobjects are intertwined with an in-memory filesystem called sysfs, which is mounted under /sys at boot time (look at /etc/fstab). Every kobject instantiated within the kernel has a representation inside sysfs. Sysfs is similar to the process filesystem (procfs) in that both are in-memory filesystems containing information about kernel data structures. While procfs is a generic window into kernel internals, sysfs is specific to the device model. Sysfs is hence not a replacement for procfs- information such as sysctl parameters and process descriptors belong to procfs and not sysfs.
Browse through /sys looking for entries that associate with say, your network card, to get a feel for its hierarchical organization. As will be apparent when you read the rest of this article, udev depends on sysfs for most of its extended functions. Sysfs is also the user space manifestation of the kernel’s structured device model.
The concept of device classes is another feature of the device model, and is an interface that you’re more likely to use in your device driver than the others. The class interface abstracts the idea that each device falls under a broader class (or category) of devices. A USB mouse, a PS/2 keyboard, and a joystick, all fall under the input class and own entries under /sys/class/input/.
The device class programming interface is built on top of kobjects and sysfs, so it’s good place to start digging to understand the end-to-end interactions between the components of the device model. Let’s take the Real Time Clock (RTC) driver as an example. The RTC driver is a miscellaneous (or “misc”) driver. Misc drivers are simple character drivers that have common characteristics.
First, let’s insert the RTC driver module and look at the nodes created in /sys and /dev:
$ modprobe rtc
$ ls –lR /sys/class/misc
drwr-xr-x 2 root root 0 Jan 15 01:23 rtc
/sys/class/misc/rtc:
total 0
-r–r–r– 1 root root 4096 Jan 15 01:23 dev
–w——- 1 root root 4096 Jan 15 01:23 uevent
$ ls –l /dev/rtc
crw-r–r– 1 root root 10, 135 Jan 15 01:23 /dev/rtc
/sys/class/misc/rtc/dev contains the major and minor numbers assigned to this device; /sys/class/misc/rtc/uevent is used for coldplugging (discussed later), while /dev/rtc is used by applications to access the RTC driver.
Now let’s understand the code flow through the device model. Misc devices utilize the services of misc_register() during initialization, which looks like Listing Two if you strip off some code:
LISTING TWO: So-called “misc” devices utilize the services of misc_register() during initialization

/* … */
dev = MKDEV(MISC_MAJOR, misc->minor);

misc->class = class_device_create(misc_class, NULL, dev, misc->dev,
“%s”, misc->name);
if (IS_ERR(misc->class))
{
err = PTR_ERR(misc->class);
goto out;
}
/* … */

Figure One continues to peel off more layers to get to the bottom of the device modeling. It illustrates the transitions that ripple through classes, kobjects, sysfs and udev, which result in the generation of the /sys and /dev files listed above.
FIGURE ONE: The many layers of the Linux device model



The Bus-Device-Driver Model

Another abstraction that is part of the device model is the bus/device/driver programming interface. Kernel device support is structured cleanly into buses, devices, and drivers. This renders the individual driver implementations simpler and more general. Bus implementations can, for example, search for drivers that can handle a particular device.
Consider the kernel Inter-Integrated Circuit (I2C) subsystem. The I2C core layer registers each detected I2C bus adapter using bus_register(). When an I2C client device, say an EEPROM, is probed and detected, its existence is recorded via device_register(). Finally, the I2C EEPROM client driver registers itself using driver_register().
bus_register() adds a corresponding entry to /sys/bus/, while device_register() adds entries under sys/devices/. struct bus_type, struct device, and struct device_driver are the main datastructures used respectively by buses, devices and drivers. Take a peek inside include/linux/device.h for their definitions.
上一篇:从Linux内核中提取的链表封装
下一篇:没有了
最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册