linux學習筆記2 diver初始化及裝置模型

2021-06-03 07:17:59 字數 4170 閱讀 8680

driver的初始化,主要是填充了device_driver裡的driver_private這個結構體:

struct driver_private ;

下面一一解釋:

1. kobject和 kset:在linux系統中,最基本的元素就是kobject,而 kobject的集合被稱為kset(kobject set),kobject的parent一定是kset的kobject,且同屬於乙個kset的kobjecs他們的ktype是相同的,均為kset的ktype,這點在kobject初始化的時候被確定,下面會詳細解釋。

2. klist_devices,這個變數代表了該driver可以驅動的device。

3. knode_bus,代表了該driver在bus的klist_driver中的節點。

4. mkobject,代表了該driver在moudles裡的物件例項,在moudle_add_driver時被賦值。

5. devicer_driver 指向自己的driver指標。

driver初始化的流程:

首先,我們會在**裡用moudle_init()巨集來宣告我們的driver的初始化函式,在kernel初始化中,被do_initcalls依次呼叫。

kernel\drivers\base\platform.c                                platform_driver_register

kernel\drivers\base\driver.c                                   driver_register

kernel\drivers\base\bus.c                                  bus_add_driver

kernel\drivers\base\dd.c                                        driver_attach

kernel\drivers\base\bus.c                                  bus_for_each_dev

kernel\drivers\base\dd.c                                   __device_attach

kernel\drivers\base\base.h                                  driver_match_device

kernel\drivers\base\dd.c                                        driver_probe_device   

其中,核心函式是bus_add_driver,下面詳細的分析下:

int bus_add_driver(struct device_driver *drv)

klist_init(&priv->klist_devices, null, null);// 初始化diver支援的devicelist,

priv->driver = drv;  

drv->p = priv;  // 互指

priv->kobj.kset = bus->p->drivers_kset; // 將driver的kset賦值為bus的kset

error = kobject_init_and_add(&priv->kobj, &driver_ktype, null, /* 此處會初始化driver的kobject,給driver找了個爹,即將parent指標賦值為bus的driver kset,並將其添    

加到bus的kset 鍊錶尾部,並呼叫create_dir在sysfs中建立對應的目錄:sys/platform/driver/mydriver

再將state_in_sysfs置為1 */

"%s", drv->name);

if (error)

goto out_unregister;

if (drv->bus->p->drivers_autoprobe)

klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); // 將driver新增到bus的 klistdriver裡去

module_add_driver(drv->owner, drv); // 將driver新增到moudles裡,這裡會對mkobject賦值,建立sys/moudles/my/drivers目錄,並在此目錄下建立"platform:mydriver快    

//  捷方式,指向 sys/platform/drivers/mydriver",在sys/platform/drivers/mydrive下建立moudles檔案,指向sys/moudles/my/drivers

error = driver_create_file(drv, &driver_attr_uevent); //建立屬性檔案

if (error)

error = driver_add_attrs(bus, drv);

if (error)

if (!drv->suppress_bind_attrs)

}kobject_uevent(&priv->kobj, kobj_add);

return 0;

out_unregister:

kobject_put(&priv->kobj);

kfree(drv->p);

drv->p = null;

out_put_bus:

bus_put(bus);

return error;

}driver_attach的**如下,實際就是bus_for_each_dev

int driver_attach(struct device_driver *drv)

在bus_for_each_dev裡會遍歷當前bus的klist_devices ,逐一的呼叫__driver_attach與driver匹配。

static int __driver_attach(struct device *dev, void *data)

static int really_probe(struct device *dev, struct device_driver *drv)

if (dev->bus->probe) else if (drv->probe)

driver_bound(dev);  //將device新增到driver的klist_devices末尾,你是我的了~

ret = 1;

pr_debug("bus: '%s': %s: bound device %s to driver %s\n",

drv->bus->name, __func__, dev_name(dev), drv->name);

goto done;

probe_failed:

devres_release_all(dev);

driver_sysfs_remove(dev);

dev->driver = null;

if (ret != -enodev && ret != -enxio)

/** ignore errors returned by ->probe so that the next driver can try

* its luck.

*/ret = 0;

done:

atomic_dec(&probe_count);

wake_up(&probe_waitqueue);

return ret;

}這樣,driver和device就繫結了其實總結下來一共就那麼幾件事情:

1. driver的kobject的完善,在sys/platform/drivers下建立了自己的目錄,並將driver新增到 bus的 ksetlist裡,其實就是按個家,找個爹

2. driver和device的匹配,如果成功,則在sys/platform/drivers/mydriver目錄下建立指向sys/platform/dev/mydevice的link檔案,在ys/platform/dev/mydevice建立「driver」指向sys/platform/drivers/mydrive,將driver賦值給device的driver,將device新增到driver的klist末尾,所謂心心相映,找個物件。

3. 在moudles目錄下建立自己的鏈結,完善mkobject,方便系統呼叫。

t b c

linux學習筆記 2

一些常用的基本命令 uname a 檢視核心版本 ls al 顯示所有檔案的屬性 pwd 顯示當前路徑 cd 返回上一次目錄 cd 返回主目錄 date s 設定時間 日期 cal 顯示日曆 cal 2006 bc 計算器具 man info 幫助手冊 locale 顯示當前字型 locale a ...

Linux學習筆記2

1 linux使用者身份與群組記錄的檔案 預設情況下所有系統賬號的資訊都記錄在 etc passwd這個檔案中 個人密碼則記錄在 etc shadow這個檔案中 所有的組名記錄在 etc group中 2 使用ls all檢視目錄下的檔案詳細資訊 例如 rw r r 1 root root 6849...

Linux學習筆記 (2)

閒著無事,就敲起了linux 命令,熟悉一下。記得昨天在書上看到了 find命令的用法,覺得挺神奇的。其中 find 能夠確定檔案的查詢深度 於是 敲了如下命令 建立如下檔案目錄 樹 來試一下 find 的 maxdepth 與 mindepth 當把最大深度設為1時,找到的是 於 father 目...