当前位置: 首页 > wzjs >正文

网站建设的原则现在感染症状有哪些

网站建设的原则,现在感染症状有哪些,福建已经宣布封城的城市,中山网站建设熊掌号介绍 Sysfs 设备文件系统与proc是同一类的文件系统,基于ramfs实现的内存文件系统。 1.1 为什么会有 sysfs?procfs 的局限性: 早期,Linux 使用 procfs 来提供内核与用户空间的交互接口。但 procfs 的设计不够层次化,设…
  1. 介绍
    Sysfs 设备文件系统与proc是同一类的文件系统,基于ramfs实现的内存文件系统。
    1.1 为什么会有 sysfs?
  2. procfs 的局限性:
  • 早期,Linux 使用 procfs 来提供内核与用户空间的交互接口。
  • 但 procfs 的设计不够层次化,设备信息和其他系统信息混杂在一起,显得混乱。
  • 于是,开发者决定创建一个新的文件系统,专门用来管理设备和硬件信息。
  1. sysfs 的诞生:
  • 最初,这个新文件系统叫 ddfs(Device Driver Filesystem),后来改名为 driverfs。
  • 在 Linux 2.6 中,引入了 kobject 子系统,抛弃了原来基于 ramfs 的实现方式。
  • 最终,driverfs 被正式更名为 sysfs,并挂载在 /sys 目录下。

1.2 sysfs 的作用是什么?

  1. 展示设备信息:
  • sysfs 提供了一个清晰、有层次的目录结构,展示了系统的设备、总线、驱动等信息。
  • 比如,所有块设备的信息会放在 /sys/block,网络设备的信息会放在 /sys/class/net。
  1. 用户与内核的桥梁:
  • 和 procfs 类似,sysfs 允许用户通过简单的命令(如 cat 或 echo)来查看或修改内核中的信息。
  • 例如,可以通过 cat /sys/class/net/eth0/address 查看网卡的 MAC 地址。
  1. 硬件拓扑的映射:
  • 系统中所有的设备和总线都通过 kobject 组织起来,sysfs 将这些关系直接反映到文件系统中。
  • 用户可以通过 /sys 目录轻松了解硬件的拓扑结构。
    uangmang@ubuntu /sys [127]> ls
    block/ bus/ class/ dev/ devices/ firmware/ fs/ hypervisor/ kernel/ module/ power/
1. block/
作用:包含系统中所有的块设备信息(如硬盘、分区等)。
示例:/sys/block/sda/ 对应第一块 SATA 硬盘。
2. bus/
作用:按总线类型(如 PCI、USB、I2C 等)分类的设备列表。
示例:/sys/bus/usb/devices/ 包含所有 USB 设备。
3. class/
作用:按设备功能分类的视图(如网卡、显卡、输入设备等)。
示例:/sys/class/net/ 包含所有网络接口。
4. dev/
作用:提供字符设备和块设备的符号链接,指向实际设备节点。
示例:/sys/dev/block//sys/dev/char/ 分别对应块设备和字符设备的主次设备号。
5. devices/
作用:系统所有设备的物理层次结构,反映硬件实际连接方式。
示例:PCI 设备会显示为 /sys/devices/pci0000:00/6. firmware/
作用:固件相关信息和接口(如 ACPI、EFI 等)。
示例:ACPI 表可通过此目录访问。
7. fs/
作用:文件系统相关信息(如挂载的文件系统、配额等)。
示例:/sys/fs/ext4/ 包含 ext4 文件系统的参数。
8. hypervisor/
作用:虚拟化相关信息和配置(如 Xen、KVM 等虚拟化平台)。
示例:Xen 虚拟机的属性可能在此目录下。
9. kernel/
作用:内核运行时参数和配置(如调试选项、热插拔设置等)。
示例:/sys/kernel/debug/ 提供调试接口(需挂载 debugfs)。
10. module/
作用:已加载内核模块的信息和参数。
示例:/sys/module/ext4/ 包含 ext4 文件系统模块的参数。
11. power/
作用:电源管理相关配置(如休眠、唤醒事件等)。
示例:/sys/power/state 可写入 mem 进入睡眠状态。    
  1. 对象
    Linux是以一切皆文件的哲学,sysfs 保留给用户操作的接口,是用户通向内核的窗户。在 Linux 内核中,kobject、kobj_type 和 kset 是 设备模型(Device Model) 的核心数据结构,它们共同构成了 /sys 文件系统的底层框架。
    暂时无法在飞书文档外展示此内容
  2. 相关代码
    3.1 Kobject
    kobject
    设备模型实现的中心为kobject,kobject提供了这些对象作:
  3. reference count
  4. 管理对象的链接串行(集合)
  5. 集合的 spinlock
  6. 将对象属性导出到用户空间(通过sysfs)
 /include/linux/kobject.h
struct kobject {const char *name;                           // 物件的文字名稱,可利用 sysfs 導出至 user spacestruct list_head entry;                     // 雙向鏈結串列,用於將若干 kobject 放置到一個鏈結串列中struct kobject *parent;                     // 用於 kobject 的階層結構struct kset *kset;                          // 用於將物件與其他物件放置到一個集合時struct kobj_type *ktype;                    // 提供包含 kobject 的資料結構的更多詳細資訊struct sysfs_dirent *sd;                    // 用於 kobject 與 sysfs 間的關聯struct kref kref;                           // 管理 reference countunsigned int state_initialized : 1;         // 是否已經初始化unsigned int state_in_sysfs : 1;            // 是否已在 sysfs 呈現unsigned int state_add_uevent_sent : 1;     // 紀錄 add uevent 是否發送unsigned int state_remove_uevent_sent : 1;  // 若有 add uevent 沒有 remove uevent 會補發 remove ueventunsigned int uevent_suppress : 1;           // 若為 1,在設備發生變化時不發送 uevent};

3.2 kobj_type
对象读写行为和释放逻辑

// /include/linux/kobject.hstruct kobj_type {void (*release)(struct kobject *kobj);       // 对象销毁时的回调const struct sysfs_ops *sysfs_ops;           // sysfs 文件读写方法struct attribute **default_attrs;            // 默认属性文件列表
};

3.3 Kset
kset 是包含了多个 kobject 的集合,也就是说 kset 用来打包 kobject,例如现在我们需要在
/sys 目录下出创建多个目录或者文件,那么就需要使用 kset 来指定这些目录在同一级目录下。

// include/linux/kobject.h
struct kset {struct list_head list;                     // 所有屬於目前集合的 kobject 的鏈結串列spinlock_t list_lock;                      // 用於保護 liststruct kobject kobj;                       // kset 即為使用 kobject 的第一個例子,用於管理 kset 本身const struct kset_uevent_ops *uevent_ops;  // function pointer,用於將集合的狀態資訊傳遞給 user space
};

3.4 Kref
kref 用来储存 kobject 的 reference count。

//include/linux/kref.h
struct kref {atomic_t refcount; // when o,release 
};

3.5 树状图
在这里插入图片描述

3.6 文件操作

sysfs_buffer
/fs/sysfs/file.c
为了方便 user space 与 sysfs 交换数据,核心设计了 sysfs_buffer 这个资料结构。
在这里插入图片描述

open
/fs/sysfs/file.c
在open时,首先通过file取得kobject,指定ops为kobject内的ktype上的,检查写与 store、检查读与 show,没问题的话就分配一个 sysfs_buffer,最后将 file 指标中的 关连到 sysfs_buffer。sysfs_opsprivate_data

read
/fs/sysfs/file.c
若是在第一次读取或是写入后,就呼叫 show 函式来 refresh sysfs_buffer。 最后将sysfs_buffer 内的数据复制到参数传入的 buf。
write
/fs/sysfs/file.c
分配一个新的 page,再呼叫 store 函数。
4. 实验
4.1 关键点:

  1. 创建一个sysfs层次结构,包含多级子目录
  2. 添加一个可读写属性文件来控制整数值
  3. 当整数值被设为0时,动态删除一个子目录和符号链接
  4. 在模块卸载时正确清理sysfs条目
  5. 使用正确的引用计数管理kobject对象
    // git 相关代码 Gist
#include <linux/device.h>      // 设备相关函数和结构体
#include <linux/init.h>        // 模块初始化宏
#include <linux/kernel.h>      // 内核日志和类型定义
#include <linux/module.h>      // 模块相关宏和函数
#include <linux/sysfs.h>       // sysfs 相关函数和结构体// 模块静态变量
static int dev_int;            // 将通过sysfs暴露的整数值
static struct device *dev;     // 指向根设备的指针
static struct kobject *root, *s1, *s2, *s3;  // sysfs层次结构中的kobject对象// sysfs属性的show函数
// 当读取属性时调用
static ssize_t dev1_show(struct device *dev, struct device_attribute *attr, char *buf) {return sprintf(buf, "dev_int: %d\n", dev_int);  // 返回dev_int的当前值
}// sysfs属性的store函数
// 当写入属性时调用
static ssize_t dev1_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) {sscanf(buf, "%d", &dev_int);  // 解析输入并存储到dev_int// 当dev_int被设为0时的特殊行为if (dev_int == 0) {kobject_del(s3);                      // 删除subdir3的kobjectsysfs_remove_link(s2, "symlink_demo"); // 删除subdir2中的符号链接}return count;  // 返回处理的字节数
}// 定义设备属性,包含show/store函数和权限(0660)
static struct device_attribute dev_attr = __ATTR(dev1, 0660, dev1_show, dev1_store);// 模块初始化函数
static int sysfs_demo_init(void) {printk(KERN_INFO "sysfs demo init\n");// 创建并注册根设备dev = root_device_register("sysfs_demo");root = &dev->kobj;  // 获取根设备的kobject// 在sysfs中创建目录层次结构:// /sys/sysfs_demo/// /sys/sysfs_demo/subdir1/// /sys/sysfs_demo/subdir1/subdir2/// /sys/sysfs_demo/subdir1/subdir2/subdir3/s1 = kobject_create_and_add("subdir1", root);  // 在root下创建subdir1s2 = kobject_create_and_add("subdir2", s1);    // 在subdir1下创建subdir2s3 = kobject_create_and_add("subdir3", s2);    // 在subdir2下创建subdir3// 在subdir2中创建属性文件sysfs_create_file(s2, &dev_attr.attr);// 在subdir2中创建指向subdir1的符号链接sysfs_create_link(s2, s1, "symlink_demo");return 0;
}// 模块清理函数
static void sysfs_demo_exit(void) {printk(KERN_INFO "sysfs demo exit\n");// 清理sysfs条目(按创建顺序的逆序)sysfs_remove_file(root, &dev_attr.attr);  // 删除属性文件kobject_put(s2);                         // 递减s2的引用计数kobject_put(s1);                         // 递减s1的引用计数root_device_unregister(dev);             // 注销根设备
}// 指定初始化和清理函数
module_init(sysfs_demo_init);
module_exit(sysfs_demo_exit);// 设置模块许可证(必需)
MODULE_LICENSE("GPL");

4.2 结果

这是一个 kernel module,一开始会建立一个名称为 dev1 的 device_attribute,传入的 function pointer,通过核心提供的 API作 kobject, 如果对 dev1 写入 0,会将 subdir2 下的符号连结与 subdir3 移除。
/sys/sysfs_demo/subdir1/subdir2/dev1        (属性文件)subdir3/symlink_demo (指向subdir1的符号链接)

4.3 创建实例
Task

- 创建makefile
- obj-m += simple.o
all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules  clean:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
- 创建simple.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/string.h>// 定义 kset 和 kobject
static struct kset *my_kset;
static struct kobject *my_kobj;// sysfs 属性的值
static char my_value[100] = "default_value";// 读取 sysfs 属性
static ssize_t my_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{return sprintf(buf, "%s\n", my_value);
}// 写入 sysfs 属性
static ssize_t my_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{strncpy(my_value, buf, count);my_value[count - 1] = '\0';  // 确保字符串以 '\0' 结尾return count;
}// 定义一个 kobject 的属性
static struct kobj_attribute my_attribute = __ATTR(my_attr, 0664, my_show, my_store);// 初始化模块
static int __init my_module_init(void)
{int retval;// 创建 ksetmy_kset = kset_create_and_add("my_kset", NULL, kernel_kobj);if (!my_kset) {pr_err("Failed to create kset\n");return -ENOMEM;}// 创建 kobjectmy_kobj = kobject_create_and_add("my_kobj", &my_kset->kobj);if (!my_kobj) {pr_err("Failed to create kobject\n");kset_unregister(my_kset);return -ENOMEM;}// 创建 sysfs 属性retval = sysfs_create_file(my_kobj, &my_attribute.attr);if (retval) {pr_err("Failed to create sysfs file\n");kobject_put(my_kobj);kset_unregister(my_kset);return retval;}pr_info("Module loaded successfully\n");return 0;
}// 清理模块
static void __exit my_module_exit(void)
{// 删除 sysfs 属性sysfs_remove_file(my_kobj, &my_attribute.attr);// 释放 kobjectkobject_put(my_kobj);// 删除 ksetkset_unregister(my_kset);pr_info("Module unloaded successfully\n");
}module_init(my_module_init);
module_exit(my_module_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple kset/kobject sysfs example");

生成文件

tree                                                                                                             
.                                                                                                                                                   
├── Makefile                                                                                                                                        
├── modules.order                                                                                                                                   
├── Module.symvers                                                                                                                                  
├── simple.c                                                                                                                                        
├── simple.ko                                                                                                                                       
├── simple.mod                                                                                                                                      
├── simple.mod.c                                                                                                                                    
├── simple.mod.o                                                                                                                                    
└── simple.o                  
// 装载 module
insmod simple.ko查看装载是否成功
lsmod | grep simple                                                                                                    simple                 16384  0      
创建节点成功 生成了my_kset 节点
huangmang@ubuntu /s/k/my_kset> tree                                                                                                                 
.                                                                                                                                                   
└── my_kobj                                                                                                                                         └── my_attr                                                                                                                                     1 directory, 1 file                        

参考资料
Linux Kernel v2.6.34 Source Code
Linux Kernel Development 3/e, Robert Love
Professional Linux Kernel Architecture, Wolfgang Mauerer
The sysfs Filesystem, Patrick Moch
udev – A Userspace Implementation of devfs, Greg Kroah-Hartman
https://blog.ykzheng.com/tech/sysfs/

http://www.dtcms.com/wzjs/364570.html

相关文章:

  • 做货代的可以在哪些网站打广告5151app是交友软件么
  • 搞笑图片网站源码最近一周新闻大事
  • 芜湖酒店网站建设百度首页排名优化多少钱
  • 什么信息发布型网站百度竞价渠道代理商
  • 购物网站建设公司凡科建站小程序
  • 台州品牌网站建设看啥网一个没有人工干预的网
  • 电子商务网站的特点湖人队最新消息
  • 毕业论文的网站做网站收录排名
  • 怎样做网站ppt重庆seo怎么样
  • 网站建立失败的原因是北京网站推广营销服务电话
  • 微信商城小程序多少钱桂林网站优化
  • 做资金盘网站计算机基础培训机构
  • 网站 特效都是用什么软件做的刷粉网站推广
  • 手机网站建设公司哪家好app拉新怎么做
  • 网站建设有利点沈阳百度seo
  • 音乐网站开发参考文献微信朋友圈产品推广语
  • 网站工程师平均工资自贡网站seo
  • wordpress做成论坛优化seo方案
  • 媒体公司网站模板seo关键词优化公司哪家好
  • 电子商务网站建设的具体内容竞价广告是怎么推广的
  • 手机网站做seo百度一下京东
  • 中山建网站价格网站排名点击工具
  • 淮安市政府门户网站建设的调查报告网站优化排名方案
  • gif动图素材网站收录批量查询工具
  • 泰安网站建设焦点网络自动推广软件免费
  • 哪些网站做彩票预测途径文章推广平台
  • 一台服务器如何做两个网站网站推广营销的步骤
  • 兰州网站seo按天计费百度推广开户代理商
  • web网站开发需要什么18岁以上站长统计
  • 电影html网页模板设计素材百度seo关键词排名价格