使用 sysfs 文件系统访问 Linux 内核Word文档下载推荐.docx
- 文档编号:21359250
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:26
- 大小:59.43KB
使用 sysfs 文件系统访问 Linux 内核Word文档下载推荐.docx
《使用 sysfs 文件系统访问 Linux 内核Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《使用 sysfs 文件系统访问 Linux 内核Word文档下载推荐.docx(26页珍藏版)》请在冰豆网上搜索。
00:
01.0/0000:
01:
00.0/
broken_parity_statusenablemodaliasresource0romuevent
classirqmsi_busresource0_wcsubsystem@vendor
configlocal_cpulistpower/resource1subsystem_device
devicelocal_cpusresourceresource2subsystem_vendor
这是在Fedora10的2.6.27.5-117.fc10.i686的内核上,可以看到在/sys目录下有block,bus,class,dev,devices,firmware,fs,kernel,module,power这些子目录,本文将分别介绍这些目录存在的含义。
第二个ls命令展示了在一个pci设备目录下的文件,"
ls"
命令的"
-F"
命令为所列出的每个文件使用后缀来显示文件的类型,后缀"
/"
表示列出的是目录,后缀"
@"
表示列出的是符号链接文件。
可以看到第二个目录下包含有普通文件(regularfile)和符号链接文件(symboliclinkfile),本文也将以这个具体的设备为例说明其中每一个普通文件的用途。
/sys文件系统下的目录结构
/sys下的目录结构是经过精心设计的:
在/sys/devices下是所有设备的真实对象,包括如视频卡和以太网卡等真实的设备,也包括ACPI等不那么显而易见的真实设备、还有tty,bonding等纯粹虚拟的设备;
在其它目录如class,bus等中则在分类的目录中含有大量对devices中真实对象引用的符号链接文件;
清单1中在/sys根目录下顶层目录的意义如下:
表1./sys下的目录结构
/sys下的子目录
所包含的内容
/sys/devices
这是内核对系统中所有设备的分层次表达模型,也是/sys文件系统管理设备的最重要的目录结构,下文会对它的内部结构作进一步分析;
/sys/dev
这个目录下维护一个按字符设备和块设备的主次号码(major:
minor)链接到真实的设备(/sys/devices下)的符号链接文件,它是在内核2.6.26首次引入;
/sys/bus
这是内核设备按总线类型分层放置的目录结构,devices中的所有设备都是连接于某种总线之下,在这里的每一种具体总线之下可以找到每一个具体设备的符号链接,它也是构成Linux统一设备模型的一部分;
/sys/class
这是按照设备功能分类的设备模型,如系统所有输入设备都会出现在/sys/class/input之下,而不论它们是以何种总线连接到系统。
它也是构成Linux统一设备模型的一部分;
/sys/block
这里是系统中当前所有的块设备所在,按照功能来说放置在/sys/class之下会更合适,但只是由于历史遗留因素而一直存在于/sys/block,但从2.6.22开始就已标记为过时,只有在打开了CONFIG_SYSFS_DEPRECATED配置下编译才会有这个目录的存在,并且在2.6.26内核中已正式移到/sys/class/block,旧的接口/sys/block为了向后兼容保留存在,但其中的内容已经变为指向它们在/sys/devices/中真实设备的符号链接文件;
/sys/firmware
这里是系统加载固件机制的对用户空间的接口,关于固件有专用于固件加载的一套API,在附录LDD3一书中有关于内核支持固件加载机制的更详细的介绍;
/sys/fs
这里按照设计是用于描述系统中所有文件系统,包括文件系统本身和按文件系统分类存放的已挂载点,但目前只有fuse,gfs2等少数文件系统支持sysfs接口,一些传统的虚拟文件系统(VFS)层次控制参数仍然在sysctl(/proc/sys/fs)接口中中;
/sys/kernel
这里是内核所有可调整参数的位置,目前只有uevent_helper,kexec_loaded,mm,和新式的slab分配器等几项较新的设计在使用它,其它内核可调整参数仍然位于sysctl(/proc/sys/kernel)接口中;
/sys/module
这里有系统中所有模块的信息,不论这些模块是以内联(inlined)方式编译到内核映像文件(vmlinuz)中还是编译为外部模块(ko文件),都可能会出现在/sys/module中:
∙编译为外部模块(ko文件)在加载后会出现对应的/sys/module/<
module_name>
/,并且在这个目录下会出现一些属性文件和属性目录来表示此外部模块的一些信息,如版本号、加载状态、所提供的驱动程序等;
∙编译为内联方式的模块则只在当它有非0属性的模块参数时会出现对应的/sys/module/<
这些模块的可用参数会出现在/sys/modules/<
modname>
/parameters/<
param_name>
中,
o如/sys/module/printk/parameters/time这个可读写参数控制着内联模块printk在打印内核消息时是否加上时间前缀;
o所有内联模块的参数也可以由"
<
.<
=<
value>
"
的形式写在内核启动参数上,如启动内核时加上参数"
printk.time=1"
与向"
/sys/module/printk/parameters/time"
写入1的效果相同;
∙没有非0属性参数的内联模块不会出现于此。
/sys/power
这里是系统中电源选项,这个目录下有几个属性文件可以用于控制整个机器的电源状态,如可以向其中写入控制命令让机器关机、重启等。
/sys/slab(对应2.6.23内核,在2.6.24以后移至/sys/kernel/slab)
从2.6.23开始可以选择SLAB内存分配器的实现,并且新的SLUB(UnqueuedSlabAllocator)被设置为缺省值;
如果编译了此选项,在/sys下就会出现/sys/slab,里面有每一个kmem_cache结构体的可调整参数。
对应于旧的SLAB内存分配器下的/proc/slabinfo动态调整接口,新式的/sys/kernel/slab/<
slab_name>
接口中的各项信息和可调整项显得更为清晰。
接下来对/sys/devices/下的目录结构作进一步探讨:
清单2.查看/sys/devices/的目录结构
$ls-F/sys/devices/
isa/LNXSYSTM:
00/pci0000:
00/platform/pnp0/pnp1/system/virtual/
可以看到,在/sys/devices/目录下是按照设备的基本总线类型分类的目录,再进入进去查看其中的PCI类型的设备:
清单3.查看/sys/devices/pci0000:
00/的目录结构
00/
0000:
00.0/0000:
02.5/0000:
03.1/0000:
0e.0/power/
01.0/0000:
02.7/0000:
03.2/firmware_node@uevent
02.0/0000:
03.0/0000:
03.3/pci_bus/
在/sys/devices/pci0000:
00/目录下是按照PCI总线接入的设备号分类存放的目录,再查看其中一个,
清单4.查看/sys/devices/pci0000:
01.0/
00.0/devicelocal_cpuspower/subsystem_vendor
broken_parity_statusenablemodaliasresourceuevent
classirqmsi_bussubsystem@vendor
configlocal_cpulistpci_bus/subsystem_device
可以看到,其中有一个目录0000:
00.0/,其它都是属性文件和属性组,而如果对0000:
00.0/子目录中进行再列表查看则会得到清单1的目录结构。
继续以上过程可以了解整个目录树的结构,这里把它整理成图1.sysfs目录层次图
图1.sysfs目录层次图
其中涉及到ksets,kobjects,attrs等很多术语,这就不得不提到Linux统一设备模型。
Linux统一设备模型
在Linux2.5内核的开发过程中,人们设计了一套新的设备模型,目的是为了对计算机上的所有设备进行统一地表示和操作,包括设备本身和设备之间的连接关系。
这个模型是在分析了PCI和USB的总线驱动过程中得到的,这两个总线类型能代表当前系统中的大多数设备类型,它们都有完善的热挺拔机制和电源管理的支持,也都有级连机制的支持,以桥接的PCI/USB总线控制器的方式可以支持更多的PCI/USB设备。
为了给所有设备添加统一的电源管理的支持,而不是让每个设备中去独立实现电源管理的支持,人们考虑的是如何尽可能地重用代码;
而且在有层次模型的PCI/USB总线中,必须以合理形式展示出这个层次关系,这也是电源管理等所要求的必须有层次结构。
如在一个典型的PC系统中,中央处理器(CPU)能直接控制的是PCI总线设备,而USB总线设备是以一个PCI设备(PCI-USB桥)的形式接入在PCI总线设备上,外部USB设备再接入在USB总线设备上;
当计算机执行挂起(suspend)操作时,Linux内核应该以“外部USB设备->
USB总线设备->
PCI总线设备”的顺序通知每一个设备将电源挂起;
执行恢复(resume)时则以相反的顺序通知;
反之如果不按此顺序则将有设备得不到正确的电源状态变迁的通知,将无法正常工作。
sysfs是在这个Linux统一设备模型的开发过程中的一项副产品(见参考资料中GregK.Hartman写作的LinuxJournal文章)。
为了将这些有层次结构的设备以用户程序可见的方式表达出来,人们很自然想到了利用文件系统的目录树结构(这是以UNIX方式思考问题的基础,一切都是文件!
)在这个模型中,有几种基本类型,它们的对应关系见表2.Linux统一设备模型的基本结构:
表2.Linux统一设备模型的基本结构
类型
对应内核数据结构
对应/sys项
设备(Devices)
设备是此模型中最基本的类型,以设备本身的连接按层次组织
structdevice
/sys/devices/*/*/.../
设备驱动(DeviceDrivers)
在一个系统中安装多个相同设备,只需要一份驱动程序的支持
structdevice_driver
/sys/bus/pci/drivers/*/
总线类型(BusTypes)
在整个总线级别对此总线上连接的所有设备进行管理
structbus_type
/sys/bus/*/
设备类别(DeviceClasses)
这是按照功能进行分类组织的设备层次树;
如USB接口和PS/2接口的鼠标都是输入设备,都会出现在/sys/class/input/下
structclass
/sys/class/*/
从内核在实现它们时所使用的数据结构来说,Linux统一设备模型又是以两种基本数据结构进行树型和链表型结构组织的:
∙kobject:
在Linux设备模型中最基本的对象,它的功能是提供引用计数和维持父子(parent)结构、平级(sibling)目录关系,上面的device,device_driver等各对象都是以kobject基础功能之上实现的;
structkobject{
constchar*name;
structlist_headentry;
structkobject*parent;
structkset*kset;
structkobj_type*ktype;
structsysfs_dirent*sd;
structkrefkref;
unsignedintstate_initialized:
1;
unsignedintstate_in_sysfs:
unsignedintstate_add_uevent_sent:
unsignedintstate_remove_uevent_sent:
};
∙
其中structkref内含一个atomic_t类型用于引用计数,parent是单个指向父节点的指针,entry用于父kset以链表头结构将kobject结构维护成双向链表;
∙kset:
它用来对同类型对象提供一个包装集合,在内核数据结构上它也是由内嵌一个kboject实现,因而它同时也是一个kobject(面向对象OOP概念中的继承关系),具有kobject的全部功能;
structkset{
structlist_headlist;
spinlock_tlist_lock;
structkobjectkobj;
structkset_uevent_ops*uevent_ops;
其中的structlist_headlist用于将集合中的kobject按structlist_headentry维护成双向链表;
涉及到文件系统实现来说,sysfs是一种基于ramfs实现的内存文件系统,与其它同样以ramfs实现的内存文件系统(configfs,debugfs,tmpfs,...)类似,sysfs也是直接以VFS中的structinode和structdentry等VFS层次的结构体直接实现文件系统中的各种对象;
同时在每个文件系统的私有数据(如dentry->
d_fsdata等位置)上,使用了称为structsysfs_dirent的结构用于表示/sys中的每一个目录项。
structsysfs_dirent{
atomic_ts_count;
atomic_ts_active;
structsysfs_dirent*s_parent;
structsysfs_dirent*s_sibling;
constchar*s_name;
union{
structsysfs_elem_dirs_dir;
structsysfs_elem_symlinks_symlink;
structsysfs_elem_attrs_attr;
structsysfs_elem_bin_attrs_bin_attr;
};
unsignedints_flags;
ino_ts_ino;
umode_ts_mode;
structiattr*s_iattr;
在上面的kobject对象中可以看到有向sysfs_dirent的指针,因此在sysfs中是用同一种structsysfs_dirent来统一设备模型中的kset/kobject/attr/attr_group.
具体在数据结构成员上,sysfs_dirent上有一个union共用体包含四种不同的结构,分别是目录、符号链接文件、属性文件、二进制属性文件;
其中目录类型可以对应kobject,在相应的s_dir中也有对kobject的指针,因此在内核数据结构,kobject与sysfs_dirent是互相引用的;
有了这些概念,再来回头看图1.sysfs目录层次图所表达的/sys目录结构就是非常清晰明了:
∙在/sys根目录之下的都是kset,它们组织了/sys的顶层目录视图;
∙在部分kset下有二级或更深层次的kset;
∙每个kset目录下再包含着一个或多个kobject,这表示一个集合所包含的kobject结构体;
∙在kobject下有属性(attrs)文件和属性组(attr_group),属性组就是组织属性的一个目录,它们一起向用户层提供了表示和操作这个kobject的属性特征的接口;
∙在kobject下还有一些符号链接文件,指向其它的kobject,这些符号链接文件用于组织上面所说的device,driver,bus_type,class,module之间的关系;
∙不同类型如设备类型的、设备驱动类型的kobject都有不同的属性,不同驱动程序支持的sysfs接口也有不同的属性文件;
而相同类型的设备上有很多相同的属性文件;
注意,此表内容是按照最新开发中的2.6.28内核的更新组织的,在附录资源如LDD3等位置中有提到sysfs中曾有一种管理对象称为subsys(子系统对象),在最新的内核中经过重构认为它是不需要的,它的功能完全可以由kset代替,也就是说sysfs中只需要一种管理结构是kset,一种代表具体对象的结构是kobject,在kobject下再用属性文件表示这个对象所具有的属性;
常见sysfs属性的功能
使用sysfs的关键就是掌握这些sysfs属性的用法,下面以一些常见的sysfs属性来展示它的用法;
使用设备(PCI)的sysfs属性文件
以一份桌面系统上的视频卡为例,列举它对应的kobject上的属性文件的对应用途;
一般来说,在Linux桌面上都有视频卡以支持Xorg软件包作为XWindow服务器来运行,因此先找到Xorg的进程号,查看这个进程所使用的所有文件(注意查看这个进程属性需要root用户权限);
#psxfa|grepXorg
2001tty1Ss+2:
24\_/usr/bin/Xorg:
0-nr-verbose-auth\
/var/run/gdm/auth-for-gdm-NPrkZK/database-nolistentcpvt1
#lsof-nP-p2001
Xorg2001rootmemREG8,3617732231033\
/usr/lib/xorg/modules/drivers/sis_drv.so
[...]
Xorg2001rootmemREG0,01342177285529\
/sys/devices/pci0000:
00.0/resource0
Xorg2001rootmemREG0,01310725531\
00.0/resource1
Xorg2001root7uREG0,02565504\
00.0/config
Xorg2001root8uunix0xdbe660000t08756socket
Xorg2001root9uREG0,02565528\
注意到此Xorg服务器是以内存映射(mem)的形式打开了"
00.0/resource0"
和"
00.0/re
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用 sysfs 文件系统访问 Linux 内核 文件系统 访问
![提示](https://static.bdocx.com/images/bang_tan.gif)