核心版本:2.6.29
裝置驅動模型框架是linux驅動程式設計的基礎。它通過kobject,kset,ktype等底層資料結構將bus_type, device, device_driver 等高層資料結構組織起來,形成乙個層次、分類清晰的驅動模型。優點如下:
1. **重用。將物件抽象為匯流排、驅動、裝置三種,各司其職。同一匯流排的多個驅動使用相同的匯流排物件。同一驅動可以關聯驅動多個裝置。
2. 通過sysfs檔案系統,清晰了展示核心驅動模型中的層次關係。同時sysfs檔案系統還提供了方便的同使用者控制項互動的介面。
kobject是代表驅動模型中的乙個物件。匯流排、驅動、裝置都繼承了它。(在結構體中包含kobject)。每個kobject在sysfs中表現為乙個目錄。
每個kobject都有乙個parent kobject和所屬的kset。kset就是kobject所屬的kset,通過kset的鍊錶可以找到所有屬於它的kobject。這些kobject進行uevent操作時,都會呼叫所屬的kset的uevent_ops方法。父kobj,用於表示kobject之間或者kobject和kset,kset之間的在sysfs中的目錄結構關係。如果父kobj不存在,並且所屬的kset存在的話,則父kobj就是設定為所屬的kset的內嵌kobj。因此,註冊裝置、驅動或者匯流排的時候如果不指定parent kobj的話,父kobj則會設定為所屬的kset的kobj。(todo:最好畫圖表示關係)
struct kobject else {
//將裝置和該匯流排上的所有驅動進行匹配
ret = bus_for_each_drv(dev->bus, null, dev, __device_attach);
up(&dev->sem);
return ret;
static int __device_attach(struct device_driver * drv, void * data)
struct device * dev = data;
return driver_probe_device(drv, dev);
int driver_probe_device(struct device_driver * drv, struct device * dev)
int ret = 0;
if (!device_is_registered(dev))
return -enodev;
//首先呼叫匯流排的match方法進行匹配
if (drv->bus->match && !drv->bus->match(dev, drv))
goto done;
pr_debug("%s: matched device %s with driver %s\n",
drv->bus->name, dev->bus_id, drv->name);
//呼叫匯流排或者驅動的probe方法繼續進一步的匹配。
ret = really_probe(dev, drv);
done:
return ret;
int driver_register(struct device_driver *drv)
註冊驅動到裝置驅動模型,在sysfs建立相應的目錄結構,以及自動匹配裝置驅動。一般在核心中會包裝在其他的方法中在內部呼叫driver_register方法。在sysfs中的結構是:
/sys/bus/platform/drivers/serial8250/
|-- bind
|-- serial8250 -> ../../../../devices/platform/serial8250
|-- uevent
`-- unbind
/sys/devices/platform/serial8250
|-- driver -> ../../../bus/platform/drivers/serial8250
int driver_register(struct device_driver * drv)
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown)) {
printk(kern_warning "driver '%s' needs updating - please use bus_type methods\n", drv->name);
klist_init(&drv->klist_devices, null, null);
return bus_add_driver(drv);
int bus_add_driver(struct device_driver *drv)
struct bus_type * bus = bus_get(drv->bus);
int error = 0;
if (!bus)
return -einval;
pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
error = kobject_set_name(&drv->kobj, "%s", drv->name);
if (error)
goto out_put_bus;
drv->kobj.kset = &bus->drivers;
error = kobject_register(&drv->kobj);
if (error)
goto out_put_bus;
//自動匹配裝置和驅動
if (drv->bus->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
module_add_driver(drv->owner, drv);
error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
printk(kern_err "%s: uevent attr (%s) failed\n",
__function__, drv->name);
error = driver_add_attrs(bus, drv);
if (error) {
/* how the hell do we get out of this pickle? give up */
printk(kern_err "%s: driver_add_attrs(%s) failed\n",
__function__, drv->name);
error = add_bind_files(drv);
if (error) {
/* ditto */
printk(kern_err "%s: add_bind_files(%s) failed\n",
__function__, drv->name);
return error;
out_unregister:
kobject_unregister(&drv->kobj);
out_put_bus:
bus_put(bus);
return error;
linux驅動模型 裝置
thebasic device structure see the kerneldoc for the struct device.programminginte ce 檢測到裝置的匯流排驅動使用如下函式將裝置註冊到核心 int device register struct device dev 匯...
Linux裝置驅動模型
一 裝置驅動模型 驅動模型提供硬體的抽象,核心可以使用該抽象完成很多重複的工作。這些抽象主要有 電源管理,即插即用裝置支援,與使用者空間的通訊 二 核心資料結構 kobject 通過它可以以樹狀結構來管理裝置 kobj type 用來表示kobject的屬性 三 三大元件 匯流排 裝置 驅動 匯流排...
Linux驅動模型 裝置
1 裝置描述 linux 系統中的每個裝置由乙個 struct device 描述。2 裝置註冊 登出 int device register struct device dev void device unregister struct device dev 一條匯流排也是個裝置,也必須按裝置註冊...