总听有人说 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的更多相关文章

  1. linux kernel 字符设备详解

    有关Linux kernel 字符设备分析: 参考:http://blog.jobbole.com/86531/ 一.linux kernel 将设备分为3大类,字符设备,块设备,网络设备. 字符设备 ...

  2. Linux 内核文档翻译 - kobject.txt

    原文地址:Linux 内核文档翻译 - kobject.txt 作者:qh997 Everything you never wanted to know about kobjects, ksets, ...

  3. Linux Kernel C语言编程范式

    介绍 不同的编程语言具有不同的抽象原语(如下),有的原语抽象层次低,有的原语抽象层次高.其中函数式.DSL是这几年十分热门的编程语言概念. 过程式抽象原语:变量 对象式抽象原语:对象 函数式抽象原语: ...

  4. 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 ...

  5. Linux Kernel Maintainers

    http://en.wikipedia.org/wiki/Ingo_Molnár http://zh.wikipedia.org/wiki/英格·蒙內 Ingo Molnár Ingo Molnár, ...

  6. Linux Kernel - Debug Guide (Linux内核调试指南 )

    http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...

  7. Linux内核文档翻译——kobject.txt

    ==================================================================== Everything you never wanted to ...

  8. Linux kernel make 常用选项介绍

    Linux kernel 编译方法大全记录 一.这是一个我自己写的自动make脚本: #!/bin/sh export ARCH=arm export CROSS_COMPILE=arm-linux- ...

  9. Linux Kernel代码艺术——系统调用宏定义

    我们习惯在SI(Source Insight)中阅读Linux内核,SI会建立符号表数据库,能非常方便地跳转到变量.宏.函数等的定义处.但在处理系统调用的函数时,却会遇到一些麻烦:我们知道系统调用函数 ...

随机推荐

  1. [置顶] 自娱自乐1之Linux UDC驱动(形式模板)

    首先,我不是做驱动的开发人员.所以只能用自娱自乐来表示我的行为. 我不知道udc和gadget驱动是不是冷门的驱动,资料真是不多.我之前买了一本书,上面说到这些,就教你如何调试已写好的驱动.这样也可以 ...

  2. An extensible Factory Pattern example

    I have read the book Api Design For C++ recently , and I must say that it is a masterpiece. There is ...

  3. python 3 爬取百度图片

    python 3 爬取百度图片 学习了:https://blog.csdn.net/X_JS612/article/details/78149627

  4. 在 WF 4 中编写自定义控制流活动

    在 WF 4 中编写自定义控制流活动 Leon Welicki 控制流是指组织和执行程序中各个指令的方法. 在 Windows Workflow Foundation 4 (WF 4) 中,控制流活动 ...

  5. UNIX网络编程读书笔记:简介

    认知套接口编程接口 理解原始套接口(raw socket)的概念   值得注意的是,客户和服务器是典型的用户进程,而TCP和IP协议则通常是系统内核协议栈的一部分. 上图中在TCP和UDP之间留有间隙 ...

  6. js 实现sleep函数

    1.sleep函数 sleep函数作用是让线程休眠,等到指定时间在重新唤起. 2.sleep实现 <!DOCTYPE html> <html lang="zh"& ...

  7. WebApi2 知识点总结

    1.建议使用异步接口async Task<> public async Task<IHttpActionResult> Get() 如果返回的是IEnumerable请使用: ...

  8. 小米电视2S加量不加价,你还会买吗?

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  9. thunder 更改迅雷默认播放器

      更改迅雷的边下边播默认播放器 CreateTime--2017年10月31日08:33:57 Author:Marydon 1.找到迅雷的安装目录,如:D:\SoftWares\PortableE ...

  10. 多语言 SEO

    https://productforums.google.com/forum/?hl=zh-CN#!topic/webmaster-zh-cn/I0MMsm737pc