免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
【轉(zhuǎn)】Linux那些事兒之我是Sysfs(4)舉例一lddbus - wilson的日志 ...

【轉(zhuǎn)】Linux那些事兒之我是Sysfs(4)舉例一lddbus

linux kernel 2009-07-14 16:26:04 閱讀146 評(píng)論0   字號(hào): 訂閱

對(duì)了,你得把ldd3的examples代碼下下來。不然沒法繼續(xù)了。

接下來我們從例子著手,
localhost:/home/XX/examples/lddbus#insmod lddbus.ko
此時(shí)再看/sys/bus/ 這時(shí)就多了一個(gè)文件夾ldd。里面的文件構(gòu)成是這樣的
/sys/bus/ldd/
|--device
|--driver
`--version
localhost:/sys/bus/ldd#cat version
$Revision: 1.9$

這表示系統(tǒng)中多了一種名叫l(wèi)dd的總線類型。同時(shí)再看/sys/device/,也多出來一個(gè)ldd0的文件夾。這表示系統(tǒng)中多了一個(gè)名叫l(wèi)dd0的硬件。
在lddbus.c中, 定義了一個(gè)總線和硬件類型 
struct bus_type ldd_bus_type = {
        .name = "ldd",
        .match = ldd_match,
        .hotplug  = ldd_hotplug,
};

struct device ldd_bus = {
        .bus_id   = "ldd0",
        .release  = ldd_bus_release
};

lddbus模塊初始化時(shí)調(diào)用這個(gè)函數(shù)

static int __init ldd_bus_init(void)
{
        int ret;

        ret = bus_register(&ldd_bus_type);
        if (ret)
                return ret;
        if (bus_create_file(&ldd_bus_type, &bus_attr_version))
                printk(KERN_NOTICE "Unable to create version attribute\n");
        ret = device_register(&ldd_bus);
        if (ret)
                printk(KERN_NOTICE "Unable to register ldd0\n");
        return ret;
}

其實(shí)就是調(diào)用了兩個(gè)注冊(cè)函數(shù),bus_register(), device_register()。bus_create_file()是在sysfs下創(chuàng)建一個(gè)文件夾。

bus_register(),向系統(tǒng)注冊(cè)ldd_bus_type這個(gè)總線類型。bus_create_file()這個(gè)就是向sysfs中創(chuàng)建一個(gè)文件。device_register()系統(tǒng)注冊(cè)ldd_bus這個(gè)硬件類型。
注冊(cè)好了之后,我們就可以在sysfs下看到相應(yīng)的信息。

我們深入下去,仔細(xì)看看bus_register的代碼。
    688 int bus_register(struct bus_type * bus)
    689 {
    690         int retval;
    691
    692         retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
    693         if (retval)
    694                 goto out;
    695
    696         subsys_set_kset(bus, bus_subsys);
    697         retval = subsystem_register(&bus->subsys);
    698         if (retval)
    699                 goto out;
    700
    701         kobject_set_name(&bus->devices.kobj, "devices");
    702         bus->devices.subsys = &bus->subsys;
    703         retval = kset_register(&bus->devices);
    704         if (retval)
    705                 goto bus_devices_fail;
    706
    707         kobject_set_name(&bus->drivers.kobj, "drivers");
    708         bus->drivers.subsys = &bus->subsys;
    709         bus->drivers.ktype = &ktype_driver;
    710         retval = kset_register(&bus->drivers);
    711         if (retval)
    712                 goto bus_drivers_fail;
    713         bus_add_attrs(bus);
    714
    715         pr_debug("bus type '%s' registered\n", bus->name);
    716         return 0;
    717
    718 bus_drivers_fail:
    719         kset_unregister(&bus->devices);
    720 bus_devices_fail:
    721         subsystem_unregister(&bus->subsys);
    722 out:
    723         return retval;
    724 }
692-700是對(duì)bus->subsys的操作。701-705是操作bus->devices。706-710是操作bus->drivers。
692 kobject_set_name()設(shè)置bus->subsys.kset.kobj的名字。此函數(shù)很簡單,就是調(diào)用vsnprintf()。此不列出。

696 subsys_set_kset(bus, bus subsys)

#define subsys_set_kset(obj,_subsys)  (obj)->subsys.kset.kobj.kset = &(_subsys).kset

我們先看看bus_subsys的定義,它是一個(gè)subsystem類型的全局變量。在driver/base/bus.c中,decl subsys(bus, &ktype bus, NULL); 在/include/linux/kobject.h中有,decl subsys的原型,
#define decl_subsys(_name,_type,_hotplug_ops) \
struct subsystem _name##_subsys = { \
.kset = { \
.kobj = { .name = __stringify(_name) }, \
.ktype = _type, \
.hotplug_ops =_hotplug_ops, \
} \
}
就相當(dāng)于
struct subsystem bus_subsys = { \
.kset = { \
.kobj = { .name = “bus” }, \
.ktype = ktype_bus, \
.hotplug_ops =NULL, \
} \
}
其中ktype bus定義如下,
static struct kobj_type ktype_bus = {
.sysfs_ops = &bus_sysfs_ops,
};

697 subsystem_register(&bus->subsys)作用是向全局的bus_subsys”登記”, 把自己加入到bus_subsys的鏈表中去。
subsystem_register() -> kset_add() -> kobject_add()
    155 int kobject_add(struct kobject * kobj)
    156 {
    157         int error = 0;
    158         struct kobject * parent;
    159
    160         if (!(kobj = kobject_get(kobj)))
    161                 return -ENOENT;
    162         if (!kobj->k_name)
    163                 kobj->k_name = kobj->name;
    164         parent = kobject_get(kobj->parent);
    165
    166         pr_debug("kobject %s: registering. parent: %s, set: %s\n",
    167                  kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>",
    168                  kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
    169
    170         if (kobj->kset) {
    171                 down_write(&kobj->kset->subsys->rwsem);
    172
    173                 if (!parent)
    174                         parent = kobject_get(&kobj->kset->kobj);
    175
    176                 list_add_tail(&kobj->entry,&kobj->kset->list);
    177                 up_write(&kobj->kset->subsys->rwsem);
    178         }
    179         kobj->parent = parent;
    180
    181         error = create_dir(kobj);
    182         if (error) {
    183                 /* unlink does the kobject_put() for us */
    184                 unlink(kobj);
    185                 if (parent)
    186                         kobject_put(parent);
    187         } else {
    188                 kobject_hotplug(kobj, KOBJ_ADD);
    189         }
    190
    191         return error;
    192 }

代碼的170-178就是把自己連入到父輩上級(jí)kset中。我們注意到在kobject_add()函數(shù)中181行調(diào)用了create_dir(kobj),這個(gè)函數(shù)作用是在sysfs下創(chuàng)建一個(gè)文件夾。可見kobject和sysfs是同時(shí)更新的。

kset_register(&bus->devices) 和kset_register(&bus->drivers)作用類似,把bus->devices這個(gè)kset加入到bus- >subsys這個(gè)subsystem中去。最后形成圖1的層次結(jié)構(gòu)。

圖1:lddbus kobject層次結(jié)構(gòu)

同理,我們可以看看device_register()的代碼,它也是向devices_subsys這個(gè)subsystem注冊(cè),最后形成這樣的結(jié)構(gòu)與圖1類似。

目前為止,我們知道了所謂的xx_register函數(shù),就是通過其內(nèi)嵌的kobject鏈入對(duì)應(yīng)的subsystem,或是kset的層次結(jié)構(gòu)中去。這樣就可以通過一些全局的變量找到它們了。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux 2.6內(nèi)核的設(shè)備模型
kobject,kset,子系統(tǒng)層次結(jié)構(gòu)
設(shè)備驅(qū)動(dòng)的基石驅(qū)動(dòng)模型(3)
linux設(shè)備模型詳解 2( 轉(zhuǎn) )
linux bus總線-steven
Linux 設(shè)備模型驅(qū)動(dòng)篇
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服