Linux裝置驅動模型

2021-06-01 22:33:02 字數 3705 閱讀 1141

核心版本: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 一條匯流排也是個裝置,也必須按裝置註冊...