linux lddbus设备,Linux那些事儿之我是Sysfs(4)举例一lddbus | 技术部落
接下来我们从例子着手
localhost:/home/XX/examples/lddbus#insmod lddbus.ko
此时再看/sys/bus/ 这时就多了一个文件夹ldd。里面的文件构成是这样的
/sys/bus/ldd/
|--device
|--driver
`--version
localhost:/sys/bus/ldd#cat version
$Revision: 1.9$
这表示系统中多了一种名叫ldd的总线类型。同时再看/sys/device/,也多出来一个ldd0的文件夹。这表示系统中多了一个名叫ldd0的硬件。
在lddbus.c中, 定义了一个总线和硬件类型
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模块初始化时调用这个函数
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;
}
其实就是调用了两个注册函数,bus_register(), device_register()。bus_create_file()是在sysfs下创建一个文件夹。
bus_register(),向系统注册ldd_bus_type这个总线类型。bus_create_file()这个就是向sysfs中创建一个文件。device_register()系统注册ldd_bus这个硬件类型。
注册好了之后,我们就可以在sysfs下看到相应的信息。
深入讲解,看看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是对bus->subsys的操作。701-705是操作bus->devices。706-710是操作bus->drivers。
692 kobject_set_name()设置bus->subsys.kset.kobj的名字。此函数很简单,就是调用vsnprintf()。此不列出。
696 subsys_set_kset(bus, bus subsys)
#define subsys_set_kset(obj,_subsys) (obj)->subsys.kset.kobj.kset = &(_subsys).kset
我们先看看bus_subsys的定义,它是一个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, /
} /
}
就相当于
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) : "",
168 kobj->kset ? kobj->kset->kobj.name : "" );
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就是把自己连入到父辈上级kset中。我们注意到在kobject_add()函数中181行调用了create_dir(kobj),这个函数作用是在sysfs下创建一个文件夹。可见kobject和sysfs是同时更新的。
kset_register(&bus->devices) 和kset_register(&bus->drivers)作用类似,把bus->devices这个kset加入到bus->subsys这个subsystem中去。最后形成如下的层次结构
lddbus kobject层次结构
同理,我们可以看看device_register()的代码,它也是向devices_subsys这个subsystem注册,最后形成这样的结构与上图类似。
目前为止,我们知道了所谓的xx_register函数,就是通过其内嵌的kobject链入对应的subsystem,或是kset的层次结构中去。这样就可以通过一些全局的变量找到它们了。
转自:http://blog.csdn.net/fudan_abc/article/details/1768384
linux lddbus设备,Linux那些事儿之我是Sysfs(4)举例一lddbus | 技术部落相关推荐
- Linux那些事儿之我是Sysfs(4)举例一lddbus
对了,你得把ldd3的examples代码下下来.不然没法继续了. 接下来我们从例子着手, localhost:/home/XX/examples/lddbus#insmod lddbus.ko 此时 ...
- Linux那些事儿之我是Sysfs(5)举例二sculld
不妨再把sculld的代码也分析一下,先看初始函数 sculld_init() -> register_ldd_driver() ...
- linux getdents 例子,Linux那些事儿之我是Sysfs(12)举例三:sysfs读入文件夹内容
上回我们说到,如何创建文件夹和文件.我们发现,在sysfs中,inode并不那么重要.这是因为我们所要读写的信息已经就在内存中,并且已经形成了层次结构.我们只需有dentry,就可以dentry-&g ...
- linux lddbus设备,Linux设备驱动程序学习(14)-Linux设备模型(各环节的整合)
Linux设备驱动程序学习(14) -Linux设备模型(各环节的整合) 通过一个设备在内核中生命周期的各个阶段,可以更好地理解Linux设备模型.我将通过分析lddbus和sculld的源码来了解L ...
- Linux那些事儿之我是Sysfs(1)sysfs初探
"sysfs is a ram-based filesystem initially based on ramfs. It provides a means to export kernel ...
- linux hub设备,Linux设备驱动之USB hub驱动(续)
5.2.2:接口驱动中的hub_thread()函数 我们之前在分析usb_hub_init()的代码的时候,忽略掉了一部份. 代码片段如下所示: int usb_hub_init(void) { - ...
- ()shi linux字符设备,Linux字符设备驱动基础(三)
Linux字符设备驱动基础(三) 6 创建设备节点 6.1 手动创建设备节点 查看申请的设备名及主设备号: cat /proc/devices # cat /proc/devices Characte ...
- linux 杂项设备,Linux下自动创建节点的字符杂项设备 misc_register
Linux下自动创建节点的字符杂项设备 misc_register admin • 2020 年 01 月 07 日 杂项设备 Linux里面的misc杂项设备是主设备号为10的驱动设备 定义头文件: ...
- Linux那些事儿之我是Sysfs(3)设备模型上层容器
§1 bus 系统中总线由struct bus_type描述,定义为: include/linux/device.h struct bus_type { const char *name;总线类型的名 ...
最新文章
- 全国大学生电工数学建模竞赛赛题_A
- VTK/ITK 学习资料
- flutter图片预览_flutter好用的轮子推荐四-可定制的图片预览查看器photo
- 模拟模型学习 几何布朗运动_Java的几何布朗运动
- 后缀为frm是什么文件_Shell 点文件可以为你做点什么
- UVA 11582 Colossal Fibonacci Numbers!【数学】
- python-函数定义
- Codeforces 160
- 软件工程实验报告1-可行性分析
- JESD204B调试4
- windows10系统瘦身记
- 什么是归纳法、数学归纳法
- wz框架登录功能详解——demo1
- 八皇后问题(详解带注释)
- ​大连商务英百家外语英语六级水平,适合报考BEC中级还是高级
- 程序员微信名昵称_微信名字大全
- 微信朋友圈技术实现设想
- 30亿流量!梨视频靠什么拍出个“短视频世界杯元年”
- echarts 柱状图,分别给每个柱子设置不同的颜色
- 阿里云IoT投入智物智造战略 三年赋能10亿设备改造10万家数字工厂
热门文章
- editplus配置 linux shell 语法高亮 自动补全
- 在XP SP3中启用支持NLA的远程桌面
- ubuntu系统debootstrap的使用
- Bypass WAF:Burp插件绕过一些WAF设备
- 如何使用windbg在驱动加载时下断
- c语言基本类型学习小结
- Linux的文件系统及其硬盘分区挂载原理
- Linux Core Dump
- 计算机网络本地连接被禁用说明什么,win10系统网络被禁用重新启用本地连接的设置技巧...
- mysql select符合查询_数据库select group by 和having语句 多表连接查询 复合查询