linux内核部件分析(九)——设备驱动模型之device-driver

本文深入探讨Linux内核的设备驱动模型,解析device、driver和bus之间的交互,包括设备注册时如何寻找驱动,驱动注册时如何寻找设备,以及设备与驱动的绑定和解除绑定过程。重点分析了bus_probe_device()和bus_add_driver()函数,涉及设备的probe函数调用、同步机制以及设备和驱动的注销流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    前面我们分析了device、driver、bus三种类型,主要是三者的注册与注销,在sysfs中的目录与属性文件创建等内容。本节就来详细分析下,在设备注册到总线上时,总线是如何为其寻找对应的驱动的;在驱动注册到总线上时,总线又是如何为其寻找对应的设备的。

    本节的实现代码集中在drivers/base/bus.c和drivers/base/dd.c中。

先来回忆下,在device_register()->device_add()中,先是调用bus_add_device()添加device与bus间的联系,并添加bus为device定义的属性,然后会调用bus_probe_device()。bus_probe_device()会试图为已挂在总线上的该设备寻找对应的驱动。我们的故事就从这里开始。

/**
 * bus_probe_device - probe drivers for a new device
 * @dev: device to probe
 *
 * - Automatically probe for a driver if the bus allows it.
 */
void bus_probe_device(struct device *dev)
{
	struct bus_type *bus = dev->bus;
	int ret;

	if (bus && bus->p->drivers_autoprobe) {
		ret = device_attach(dev);
		WARN_ON(ret < 0);
	}
}
bus_probe_device()为总线上的设备寻找驱动。它先是检查bus->p->drivers_autoprobe,看是否允许自动探测。允许了才会调用device_attach()进行实际的寻找工作。

说到bus->p->drivers_autoprobe这个变量,它是在bus_type_private中的,在调用bus_register()前都初始化不了,在bus_register()中自动定为1。所以,除非是用户空间通过drivers_autoprobe属性文件主动禁止,bus总是允许自动探测的,所有的bus都是如此。

/**
 * device_attach - try to attach device to a driver.
 * @dev: device.
 *
 * Walk the list of drivers that the bus has and call
 * driver_probe_device() for each pair. If a compatible
 * pair is found, break out and return.
 *
 * Returns 1 if the device was bound to a driver;
 * 0 if no matching driver was found;
 * -ENODEV if the device is not registered.
 *
 * When called for a USB interface, @dev->parent->sem must be held.
 */
int device_attach(struct device *dev)
{
	int ret = 0;

	down(&dev->sem);
	if (dev->driver) {
		ret = device_bind_driver(dev);
		if (ret == 0)
			ret = 1;
		else {
			dev->driver = NULL;
			ret = 0;
		}
	} else {
		pm_runtime_get_noresume(dev);
		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
		pm_runtime_put_sync(dev);
	}
	up(&dev->sem);
	return ret;
}

device_attach()在实际绑定之前,会用dev->sem进行加锁。不错,dev->sem几乎就是为了在设备与驱动绑定或者解除绑定时加锁用的。还没有看到它在其它地方被调用。

如果在调用device_attach()前就已经有了dev->driver(),就调用device_bind_driver()进行绑定,不然还要调用bus_for_each_drv()进行依次匹配。至于pm_runtime_get_noresume之类的函数,属于电源管理部分,我们现在先忽略。

static void driver_bound(struct device *dev)
{
	if (klist_node_attached(&dev->p->knode_driver)) {
		printk(KERN_WARNING "%s: device %s already bound\n",
			__func__, kobject_name(&dev->kobj));
		return;
	}

	pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
		 __func__, dev->driver->name);

	if (dev->bus)
		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
					     BUS_NOTIFY_BOUND_DRIVER, dev);

	klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
}

static int driver_sysfs_add(struct device *dev)
{
	int ret;

	ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
			  kobject_name(&dev->kobj));
	if (ret == 0) {
		ret = sysfs_create_link(&dev->kobj, &am
This is, on the surface, a book about writing device drivers for the Linux system. That is a worthy goal, of course; the flow of new hardware products is not likely to slow down anytime soon, and somebody is going to have to make all those new gadgets work with Linux. But this book is also about how the Linux kernel works and how to adapt its workings to your needs or interests. Linux is an open system; with this book, we hope, it is more open and accessible to a larger community of developers. This is the third edition of Linux Device Drivers. The kernel has changed greatly since this book was first published, and we have tried to evolve the text to match. This edition covers the 2.6.10 kernel as completely as we are able. We have, this time around, elected to omit the discussion of backward compatibility with previous kernel versions. The changes from 2.4 are simply too large, and the 2.4 interface remains well documented in the (freely available) second edition. This edition contains quite a bit of new material relevant to the 2.6 kernel. The discussion of locking and concurrency has been expanded and moved into its own chapter. The Linux device model, which is new in 2.6, is covered in detail. There are new chapters on the USB bus and the serial driver subsystem; the chapter on PCI has also been enhanced. While the organization of the rest of the book resembles that of the earlier editions, every chapter has been thoroughly updated. We hope you enjoy reading this book as much as we have enjoyed writing it.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值