1.前言

本文主要介绍Linux内核实现的基本数据类型,包括链表,内核对象,内核对象引用计数,内核对象集合,

2.链表

1. 链表的基本结构

内核链表可以将任何类型的数据结构连接起来,链表结构如下:

1 struct list_head {
2     struct list_head *next, *prev;
3 };

图 标准双链表

典型的循环双向链表如上图所示。

2. 链表相关API

LIST_HEAD(list_name) 定义一个list_head结构体,next和pre成员均初始化为当前新创建的list_headlist_add(new,head) 用于head元素之后紧接着插入new元素list_add_tail(new,head) 在head元素前面插入new元素,由于是循环链表,实际是将new元素插入到末尾list_del(entry) 从链表中删除一项 list_empty(head) 检查链表是否为空list_splice(list, head) 合并两个链表,把list插入到另一个链表head的后面list_entry(ptr, tpe, member) ptr是某数据结构中指向list_head成员的指针,type是该数据结构的类型,member是该数据结构中list_head成员变量名list_for_each(pos, head) 用于遍历链表的所有元素。pos表示链表的当前位置,head指定了表头

3. 内核对象

3.1 kobject

1. kobject的基本结构

 1 struct kobject {
 2     const char        *name; /*kobject的名字*/
 3     struct list_head    entry;/*用于将kobject放置到一个链表中*/
 4     struct kobject        *parent;/*指向当前kobject的父对象,用于建立层次结构*/
 5     struct kset        *kset; /*用于将对象与其他对象放到一个集合中*/
 6     struct kobj_type    *ktype; /*提供了kobject的更多属性,最重要的是释放该数据结构资源的析构器函数*/
 7     struct kernfs_node    *sd; /* sysfs directory entry */
 8     struct kref        kref; /*用于简化引用计数*/
 9 #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
10     struct delayed_work    release;
11 #endif
12     unsigned int state_initialized:1;
13     unsigned int state_in_sysfs:1;
14     unsigned int state_add_uevent_sent:1;
15     unsigned int state_remove_uevent_sent:1;
16     unsigned int uevent_suppress:1;
17 };

注:kobject不是通过指针与其他数据结构连接,而必须直接嵌入到其他数据结构中,这样通过管理kobject达到了包含kobject对象的管理。由于kobject会嵌入到许多数据结构中,因此要保持kobject结构较小。

2. kobject的API

struct kobject *kobject_get(struct kobject *kobj) 增加kobject的引用计数void kobject_put(struct kobject *kobj) 减少kobject的引用计数void kobject_init(struct kobject *kobj, struct kobj_type *ktype) 初始化kobject结构体,即将引用计数设为0,并初始化kobject的链表成员int kobject_add(struct kobject *kobj, struct kobject *parent, 将kobject加入sysfs中显示const char *fmt, ...)int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, struct kobject *parent, const char *fmt, ...) kobject_init和kobject_add的合并操作struct kobject *kobject_create(void)   为一个kobject分配空间,并调用kobject_init初始化struct kobject *kobject_create_and_add(const char *name, struct kobject *parent) kobject_create和kobject_add的合并操作static void kobject_cleanup(struct kobject *kobj) 在不需要kobject(以及包含kobject的对象)时释放kobject占用的资源

3.2 kref

1.kref结构体

引用计数用来检测内核中有多少地方使用了某个对象,当内核一个部分包含某个对象的信息时,需要将该对象对应kobject的kref加1,不需要时则减1,如果减为0则释放该对象

1 struct kref {
2     atomic_t refcount; /*原子计数,给出内核中当期使用某个对象的计数,在计数为0时,kobject就可以从内存中删除了*/
3 };

2.kref的API

static inline void kref_init(struct kref *kref) 初始化kref,即将refcount初始化为1static inline void kref_get(struct kref *kref)  要使用某个对象必须将对应的kobject的引用计数加1static inline int kref_sub(struct kref *kref, unsigned int count,
void (*release)(struct kref *kref))             对象不在使用则将对应的kref减1,如果引用计数为0则调用release释放kobject

3.3 kset

kset是kobject应用的第一个例子,因此它是用kobject 进行管理的,它与kset中包含的各个kobject无关,此处的kobject只是纯粹为了管理kset之需

1 struct kset {
2     struct list_head list; /*用于链接当前kset中所有的kobject的链表*/
3     spinlock_t list_lock;
4     struct kobject kobj;
5     const struct kset_uevent_ops *uevent_ops; /*提供了若干函数指针,用于将kset的相关信息透给应用层*/
6 };

3.4 ktype

1 struct kobj_type {
2     void (*release)(struct kobject *kobj);
3     const struct sysfs_ops *sysfs_ops;
4     struct attribute **default_attrs;
5     const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
6     const void *(*namespace)(struct kobject *kobj);
7 };

注:ktype与kset没有关系,kset已经提供了集合功能,ktype提供了与sysfs文件系统相关的接口。如果多个kobject导出类似的信息,则可以共享一个ktype提供所需要的方法

4.  数据类型

  • 数据类型定义

typedef  为避免依赖体系结构的相关特性,如sector_t, pid_t等

  • 字节序

cpu_to_le64 将64位数据类型转换为小端序格式

le64_to_cpu 将64位小端序格式转换为64位cpu端格式

  • per-cpu变量

可有效避免多处理器并发访问同个变量引发的并发问题

DEFINE_PER_CPU(name, type) name是变量名, type是数据类型

get_cpu(name, cpu) 获取当前cpu上创建的变量实例

smp_processor_id() 返回当前 cpu 的id

  • 访问用户空间

__user 使用此标记来标识指向用户空间的指针

5. 参考文档

[1] 深入Linux内核架构(PLKA)

转载于:https://www.cnblogs.com/smartjourneys/p/6681801.html

Linux内核基础设施相关推荐

  1. 直播回顾:如何基于Linux内核构建起商用密码基础设施?| 龙蜥技术

    编者按:本文整理自龙蜥大讲堂技术解读,分享主题为<构建商用密码操作系统>,直播视频回放已上线至龙蜥社区官网(文末阅读原文直接跳转):首页-支持-视频,欢迎观看. 作者张天佳,来⾃阿⾥云操作 ...

  2. linux内核源代码分析----内核基础设施之klist

    概述 klist是list的线程安全版本,他提供了整个链表的自旋锁,查找链表节点,对链表节点的插入和删除操作都要获得这个自旋锁.klist的节点数据结构是klist_node,klist_node引入 ...

  3. Facebook 开源了一整套重要的 Linux 内核组件与工具!

    近日,Facebook 开源了一套解决重要计算集群管理问题的 Linux 内核组件和相关工具,这些项目覆盖了资源控制.资源利用.工作负载隔离.负载均衡.测量和监控等方面:BPF.Btrfs.Netco ...

  4. linux 内核 调试工具介绍

    1 内核调试以及工具总结 内核总是那么捉摸不透, 内核也会犯错, 但是调试却不能像用户空间程序那样, 为此内核开发者为我们提供了一系列的工具和系统来支持内核的调试. 内核的调试, 其本质是内核空间与用 ...

  5. Linux内核的namespace机制分析

    1.  Linux内核namespace机制 Linux Namespaces机制提供一种资源隔离方案.PID,IPC,Network等系统资源不再是全局性的,而是属于某个特定的Namespace.每 ...

  6. linux中的vsprintf_Git29 年超 100 万次 commit,Linux 内核何以发展至今?

    1991 年,21 岁的芬兰大学生 Linus Torvalds 写下第一行 Linux 内核代码时,多半没有想到它会成长为今天这样的庞然大物. 当年 8 月 25 日,Torvalds 在 Mini ...

  7. Facebook 开源了一整套重要的 Linux 内核组件与工具!

    近日,Facebook 开源了一套解决重要计算集群管理问题的 Linux 内核组件和相关工具,这些项目覆盖了资源控制.资源利用.工作负载隔离.负载均衡.测量和监控等方面:BPF.Btrfs.Netco ...

  8. SM2 国密算法被 Linux 内核社区接受

    喜欢就关注我们吧! 10 月 25 日,有开发者发文称,SM2 国密算法终于被 Linux 内核社区接受了.该作者表示,SM2 的补丁已经更新到了 v7 版本,这个版本的补丁最终被社区接受,目前已经合 ...

  9. Linux内核品读 /基础组件/ 模块机制快速入门

    哈喽,我是杰克吴,继续记录我的学习心得. 一.关于兴趣的几点思考 1. 享受不是兴趣,愿意付出才是: 兴趣很容易跟享受混淆.享受是被动的,无需付出:而兴趣则要求你甘愿为了这件事情付出努力. 2.任何事 ...

  10. Linux内核调试原理和工具介绍--理解静态插装/动态插装、tracepoint、ftrace、kprobe、SystemTap、Perf、eBPF

    可以将linux跟踪系统分成Tracer(跟踪数据来自哪里),数据收集分析(如"ftrace")和跟踪前端(更方便的用户态工具). 1. 数据源(Tracers) printk 是 ...

最新文章

  1. JZOJ 5616. 【NOI2018模拟3.31】沧海尘记
  2. sed,awk,grep,trap,trap,cut,tr,curl,find
  3. VC++控件加载BMP图片(静态和动态方式)
  4. log4cplus c++开源日志系统
  5. 实习笔记 6: 测试技巧,json序列化对象
  6. canvas压缩图片成base64,传到后台解码需要注意的问题
  7. win10右下角的天气怎么关闭
  8. yii 获取当前域名_yii2 在域名后面加一个路径作为首页
  9. android4.4 计算器,卡西欧仿真计算器
  10. linux区分三种用户角色,Linux用户角色划分
  11. devops学习(三) K8环境部署jenkins
  12. 360°全景图制作步骤和技巧有哪些?
  13. 改变ubuntu终端显示语言(桌面系统是中文,终端提示是英文)
  14. EasyDSS部署在C盘,录像回看无法正常播放该如何解决?
  15. c语言blackjack设计思路,写一个“BlackJack ”Java应用程序 该计划将测试你的逻辑思维。...
  16. 2019暑假集训感触与收获
  17. 五洲御瓷精彩绽放2020第八届特色酒店案例分享论坛暨十周年庆典
  18. python延时执行下一步
  19. Python分别用迭代/递归的方式实现阶乘
  20. C语言 求10的阶乘

热门文章

  1. java泛型好处及案例
  2. Hybrid App是如何实现网页语言与程序语言的混合?谁占主体?
  3. Oracle下sqlplus无法使用命令退格删除和历史记录的解决方法--使用rlwrap
  4. 沫沫金::struts下载文档[解决方案]
  5. Sql Server 存储过程分页大全(2005,2000)
  6. 为Android添加一门新语言
  7. 阿里双十一技术揭秘——双十一 手淘技术用了这几招
  8. “123456”连续七年霸榜,2019最糟糕密码榜单出炉
  9. 普通人在互联网还有机会么?
  10. 一场重新定义的发布会