正 文
Linux基础之内核对象和sysfs文件系统 [2](2009/10/6 17:09)
Linux中的内核对象和sysfs文件系统[2]
介绍:在Linux内核中,系统会为每一个注册的kobject在/sys下创建一个目录,前提是你配置了/sys文件系统。之所以把内核对象和sysfs文件系统分开说明,主要由于:一,这本身就是两个东西,二,两个放在一起,容易混淆,去除了sysfs文件系统的内核对象就变得异常简单。下面内容的前提是你配置了sysfs文件系统
1.Sysfs的形式
Sysfs挂接在/sys目录下,首层一般包括以下几个目录,每一个目录代表一个单独的分支,也就是子系统,子系统下的目录以首层下的目录的kset为根,通过将kset或kobject注册到这个kset上或下属的kset上,连接在一起并以树的形式显示
Fs/ //文件系统,一般不使用
Device/ //设备系统,所有设备的根,但是不是所有设备都在这下面,
bus/ //总线系统,驱动系统根目录
class/ //以类分出的设备
block/ //块设备
firmware/ //固件
net/ //
1.Sysfs文件系统的建立:
从内核启动开始,下面列出sysfs_init();函数的调用路径
--start_kernel(/init/main.c)
--vfs_caches_init(num_physpages)(/fs/dcache.c)
--mnt_init(unsignedlongmempages)(/fs/Namespace.c)
--sysfs_init()(/fs/sysfs/mount.c)
函数原型为
int__initsysfs_init(void)
这个函数首先注册了sysfs_fs_type文件系统类型,然后通过kern_mount(&sysfs_fs_type)函数来挂载这个文件系统。创建超级块sysfs_sb和挂载点sysfs_mount;从而让sys文件系统可用。
2.在文件系统中创建目录的位置
对于每个调用注册函数的kobject只要有名字都会使用下面函数在/sys下建立一个目录
intsysfs_create_dir(structkobject*kobj,structdentry*shadow_parent)
目录的位置由三步决定:
一.调用时指定了shawdow_parent,创建在次目录下,一般这个都为NULL
二.否则查找kobj的->parent是否有效,有效创建在->parent的目录下,上一章曾提过kobject注册是是不会改变初始化的->parent,即可以设置所在的kset,也可以选择所在的目录,而不需要一致
三.如果以上都无效,就选择在/sys文件系统的顶层建立一目录
如果一个内核对象没有嵌入到任何结构体中,也没有设置kset,而进行注册,那么它的目的应该就是在/sys下建立一个目录了。如
intsubsystem_register(structkset*s)
2.sysfs目录的内容
kobject注册后,会创建一个struct_sysfs_dirent结构体,并创建一个structdentry和一个structinode供用户使用来读取目录,kobject的dentry指针指向创建的dentry,dentry的d_fsdata指向创建的sysfs_dirent结构体,sysfs_dirent提供s_dentry指向dentry,s_element指向object.sysfs_dirent结构体如下。
structsysfs_dirent{
atomic_t s_count;//引用计数
struct list_head s_sibling;//通一个目录的链表上的节点
struct list_head s_children;//子目录链表的父段
void *s_element;//指向对应的kobject结构
int s_type;//类型:文件/目录/属性等
umode_t s_mode;//读写模式
ino_t s_ino;//节点号,除root为1外,其他从3开始递增
struct dentry *s_dentry;//对应创建的structdentry
struct iattr *s_iattr;//属性
atomic_t s_event;
};
Sys系统首先有一个sysfs_root作为根,然后通过s_children和s_sibling成员链接成树结构。并且数据结构中只有简单的类型和模式及节点供用户使用,实际内容只有两个指针供调用。
3.Sys系统的其他使用。
根据内核中/inlude/linux/sysfs.h中的接口函数声明,sys不仅可以创建目录,还可以创建文件,连接,bin文件,属性组等。但所有函数都必须提供kobject作为输入参数。
创建文件即是在kobject对应的目录下增加属性文件。
创建bin文件即是在kobject对应的目录下增加bin属性文件。
创建链接是创建一个连接指向对应的kobject创建的目录.
创建属性组即首先创建一个目录,然后在该目录内依次添加所有属性文件
并且这些创建都需要在kobject注册之后使用/inlude/linux/sysfs.h中定义的接口函数和kobject进行添加。
4.属性文件
Sys下的文件只能创建属性文件。属性文件的读取方式存储在kobject结构体中的ktype的sysfs_ops成员上,读取属性会首先查询kobject所在的kset的ktype,如果没有定义使用kobject自己的ktype,如果也没有定义使用sys自带的subsys_sysfs_ops中定义的函数来读取属性。
读取属性使用
ssize_t(*show)(structkobject*kobj,structattribute*attr,char*page)
存储属性使用
ssize_t(*store)(structkobject*kobj,structattribute*attr,constchar*page,size_tcount)
函数中kobj对应属性文件所在目录,即所在目录对应的kobject,attr对应打开的属性我文件。
由于page是使用get_zeroed_page(GFP_KERNEL)得到的,因此读写属性文件只能使用最多一页的字符串。并且没有指定偏移地址和读写数据长度,因此最好是一个字符串。
5.bin属性文件
Sys的bin属性文件在创建时把读取函数存储在了文件中,当读取时使用文件中的函数指针来读取所在目录的属性。
Bin属性的读写缓存是使用kmalloc(PAGE_SIZE,GFP_KERNEL)申请挂在file->private_data上因此一次最多也只能读写一页的字符串,但是bin属性文件的读写函数参数
ssize_t(*read)(structkobject*,char*,loff_t,size_t);
ssize_t(*write)(structkobject*,char*,loff_t,size_t);
含有偏移地址和读写数据大小,读写要更加灵活,并且定义了
int(*mmap)(structkobject*,structbin_attribute*attr,structvm_area_struct*vma);
函数供内存映射。
评 论
还没有网友评论,欢迎您第一个评论!