Linux kernel 之 kobject
总听有人说 Linux kernel 拥有一团无比巨大看似杂乱无章其实有迹可循的链表,今天参考一下其他大牛的相关资料记录一下。
kset 结构体
151 /**
152 * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
153 *
154 * A kset defines a group of kobjects. They can be individually
155 * different "types" but overall these kobjects all want to be grouped
156 * together and operated on in the same manner. ksets are used to
157 * define the attribute callbacks and other common events that happen to
158 * a kobject.
159 *
160 * @list: the list of all kobjects for this kset
161 * @list_lock: a lock for iterating over the kobjects
162 * @kobj: the embedded kobject for this kset (recursion, isn't it fun...)
163 * @uevent_ops: the set of uevent operations for this kset. These are
164 * called whenever a kobject has something happen to it so that the kset
165 * can add new environment variables, or filter out the uevents if so
166 * desired.
167 */
168 struct kset {
169 struct list_head list; // 这里边包含了这个 kset 所有的 kobject
170 spinlock_t list_lock;
171 struct kobject kobj; // 一个嵌入在里面的kobject
172 const struct kset_uevent_ops *uevent_ops; // 里面包含热拔插事件发生时的响应操作
173 };
* #### kobject 结构体
// include/linux/kobject.h
63 struct kobject {
64 const char *name; // 名字
65 struct list_head entry; // 连接到 kset 建立层次结构
66 struct kobject *parent; // 上一个节点
67 struct kset *kset; // 指向所属的 kset
68 struct kobj_type *ktype; // 指向所属的 ktype
69 struct kernfs_node *sd; /* sysfs directory entry */ // 文件系统内的sysfs 的node
70 struct kref kref; // 引用计数
71 #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
72 struct delayed_work release;
73 #endif
74 unsigned int state_initialized:1; // 初始化状态,只占 1 个位的空间,应用了位域
75 unsigned int state_in_sysfs:1;
76 unsigned int state_add_uevent_sent:1;
77 unsigned int state_remove_uevent_sent:1;
78 unsigned int uevent_suppress:1;
79 };
* #### kobj_type 结构体
116 struct kobj_type {
117 void (*release)(struct kobject *kobj);
118 const struct sysfs_ops *sysfs_ops;
119 struct attribute **default_attrs;
120 const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
121 const void *(*namespace)(struct kobject *kobj);
122 };
* #### kobject_init - initialize a kobject structure : 初始化
// lib/kobject.c
// 318 * This function will properly initialize a kobject such that it can then
// 319 * be passed to the kobject_add() call. 等下还有kobject_add()
// 321 * After this function is called, the kobject MUST be cleaned up by a call
// 322 * to kobject_put(), not by a call to kfree directly to ensure that all of
// 323 * the memory is cleaned up properly. 必须用 kobject_put 去释放,而不是 kfree
325 void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
326 {
327 char *err_str;
328
329 if (!kobj) {
330 err_str = "invalid kobject pointer!";
331 goto error;
332 }
333 if (!ktype) {
334 err_str = "must have a ktype to be initialized properly!\n";
335 goto error;
336 }
337 if (kobj->state_initialized) {
338 /* do not error out as sometimes we can recover */
339 printk(KERN_ERR "kobject (%p): tried to init an initialized "
340 "object, something is seriously wrong.\n", kobj);
341 dump_stack();
342 }
343
344 kobject_init_internal(kobj); // 初始化有关的成员
345 kobj->ktype = ktype;
346 return;
347
348 error:
349 printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str);
350 dump_stack();
351 }
352 EXPORT_SYMBOL(kobject_init);
// kobject_init_internal 一些属性的初始化
187 static void kobject_init_internal(struct kobject *kobj)
188 {
189 if (!kobj)
190 return;
191 kref_init(&kobj->kref); // 设置计数为1
192 INIT_LIST_HEAD(&kobj->entry);
193 kobj->state_in_sysfs = 0;
194 kobj->state_add_uevent_sent = 0;
195 kobj->state_remove_uevent_sent = 0;
196 kobj->state_initialized = 1; // 设置初始化状态
* #### 通过总线注册函数解析 kset , kobjectd , ktype 这些结构体的关系。
// drivers/base/bus.c
// 这里先将 两个变量作为全局变量
25 /* /sys/devices/system */
26 static struct kset *system_kset;
178 static struct kset *bus_kset;
// 入口函数
1278 int __init buses_init(void)
1279 { // kset 创建和添加 , 名字为"bus" "bus事件操作" “父project 为空”
1280 bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
1281 if (!bus_kset)
1282 return -ENOMEM;
1283
1284 system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
1285 if (!system_kset)
1286 return -ENOMEM;
1287
1288 return 0;
1289 }
// kset_create_and_add
// 头文件 include/linux/kobject.h
178 extern struct kset * __must_check kset_create_and_add(const char *name,
179 const struct kset_uevent_ops *u,
180 struct kobject *parent_kobj);
// 源代码 lib/kobject.c
936 struct kset *kset_create_and_add(const char *name,
937 const struct kset_uevent_ops *uevent_ops,
938 struct kobject *parent_kobj)
939 {
940 struct kset *kset;
941 int error;
942 // 名字为"bus" ,申请一段空间并初始化相关kset 属性
943 kset = kset_create(name, uevent_ops, parent_kobj);
944 if (!kset)
945 return NULL;
946 error = kset_register(kset); // 注册
947 if (error) {
948 kfree(kset);
949 return NULL;
950 }
951 return kset;
952 }
// lib/kobject.c
// kset_register
809 int kset_register(struct kset *k)
810 {
811 int err;
812
813 if (!k)
814 return -EINVAL;
815 // 初始化
816 kset_init(k);
817 err = kobject_add_internal(&k->kobj); // 接下
818 if (err)
819 return err;
820 kobject_uevent(&k->kobj, KOBJ_ADD);
821 return 0;
822 }
823 EXPORT_SYMBOL(kset_register);
// kset 初始化
767 void kset_init(struct kset *k)
768 { // 这个在上面已经跟过了
// 最主要是初始化了 state_initialized = 1
769 kobject_init_internal(&k->kobj);
770 INIT_LIST_HEAD(&k->list); // 设置为链表头
771 spin_lock_init(&k->list_lock);
772 }
// kobject_add_internal
200 static int kobject_add_internal(struct kobject *kobj)
201 {
202 int error = 0;
203 struct kobject *parent;
204
205 if (!kobj)
206 return -ENOENT;
207
208 if (!kobj->name || !kobj->name[0]) {
209 WARN(1, "kobject: (%p): attempted to be registered with empty "
210 "name!\n", kobj);
211 return -EINVAL;
212 }
213
214 parent = kobject_get(kobj->parent);
215
216 /* join kset if set, use it as parent if we do not already have one */
217 if (kobj->kset) {
218 if (!parent)
219 parent = kobject_get(&kobj->kset->kobj);
220 kobj_kset_join(kobj);
221 kobj->parent = parent;
222 }
Linux kernel 之 kobject的更多相关文章
- linux kernel 字符设备详解
有关Linux kernel 字符设备分析: 参考:http://blog.jobbole.com/86531/ 一.linux kernel 将设备分为3大类,字符设备,块设备,网络设备. 字符设备 ...
- Linux 内核文档翻译 - kobject.txt
原文地址:Linux 内核文档翻译 - kobject.txt 作者:qh997 Everything you never wanted to know about kobjects, ksets, ...
- Linux Kernel C语言编程范式
介绍 不同的编程语言具有不同的抽象原语(如下),有的原语抽象层次低,有的原语抽象层次高.其中函数式.DSL是这几年十分热门的编程语言概念. 过程式抽象原语:变量 对象式抽象原语:对象 函数式抽象原语: ...
- Linux kernel suspend resume学习:2.6.35与3.0.35比较【转】
转自:http://blog.csdn.net/njuitjf/article/details/18317149 Linux kernel suspend resume学习:2.6.35与3.0.35 ...
- Linux Kernel Maintainers
http://en.wikipedia.org/wiki/Ingo_Molnár http://zh.wikipedia.org/wiki/英格·蒙內 Ingo Molnár Ingo Molnár, ...
- Linux Kernel - Debug Guide (Linux内核调试指南 )
http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...
- Linux内核文档翻译——kobject.txt
==================================================================== Everything you never wanted to ...
- Linux kernel make 常用选项介绍
Linux kernel 编译方法大全记录 一.这是一个我自己写的自动make脚本: #!/bin/sh export ARCH=arm export CROSS_COMPILE=arm-linux- ...
- Linux Kernel代码艺术——系统调用宏定义
我们习惯在SI(Source Insight)中阅读Linux内核,SI会建立符号表数据库,能非常方便地跳转到变量.宏.函数等的定义处.但在处理系统调用的函数时,却会遇到一些麻烦:我们知道系统调用函数 ...
随机推荐
- hadoop文件系统与I/O流
本文地址:http://www.cnblogs.com/archimedes/p/hadoop-filesystem-io.html,转载请注明源地址. hadoop借鉴了Linux虚拟文件系统的概念 ...
- 给 Easyui Datagrid 扩展方法
$.extend($.fn.datagrid.methods, { /** * 更新 非编辑列值 * @param rowIndex : 行索引 * @param cellName : 列索引或列名 ...
- 学习笔记4-Action参数绑定
参数绑定功能默认是开启的,其原理是把URL中的参数(不包括模块.控制器和操作名)和操作方法中的参数进行绑定. 要启用参数绑定功能,首先确保你开启了URL_PARAMS_BIND设置: 'URL_PAR ...
- [转] windows下sublime2 安装破解(key可用)
转: http://jingyan.baidu.com/article/ff4116259b057c12e48237b8.html Sublime Text 2安装汉化破解.插件包安装教程 | 浏览: ...
- [AngularJS] $scope.$warchCollection
For the $watch in last article, we watch 'user.password', actually it is a string. If you watch 'use ...
- (剑指Offer)面试题56:链表中环的入口结点
题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 1.哈希表 遍历整个链表,并将链表结点存入哈希表中(这里我们使用容器set),如果遍历到某个链表结点已经在set中,那么该点即为环的入口 ...
- C语言 域名通配符实现
本例实现通配符 * 的功能,不支持*在字符串的末尾, 仅提供思路,函数仅做简单单元测试. 如有使用,还请自己进行修改 // str1: 待匹配字符串 // str2: 带通配符字串 int wildc ...
- Servlet 异常处理
当一个 Servlet 抛出一个异常时,Web 容器在使用了 exception-type 元素的 web.xml 中搜索与抛出异常类型相匹配的配置.您必须在 web.xml 中使用 error-pa ...
- zookeeper 入门讲解实例 转
转 http://www.blogjava.net/BucketLi/archive/2010/12/21/341268.html zookeeper使用和原理探究(一) zookeeper介绍zo ...
- 铁通网络没有一个真实的公网IP,NAT转换能不能解决?
铁通网络没有一个真实的公网IP,NAT转换能不能解决? 我的是铁通宽带,现在想用自己的机子做一个动态主机,可是因为铁通垃圾网络的NAT转发问题,使用cn99qdns手动更新动态域名IP后公网能 ...