sysfs--kobject
程序员文章站
2022-06-03 22:58:24
...
写再前面:
sysfs就是所说的虚拟虚拟文件系统。道行太浅,原理性的东西自己都说不太清,就不瞎写误人子弟了。
可以看下搜寻的几篇帖子,讲的还不错,看完你应该有所收获吧。
https://blog.csdn.net/u010743406/article/details/107694951
对于这些东西直接干示例,理解最直观了。不论是kobject还是kset的示例都是参考内核的示例。
自己会下载内核代码吧,下了后搜索kobject-example.c文件,就是我学习的示例。
理解:
忍不住讲下自己的理解。哈哈。
对于内核态的代码,用户态访问不到。内核提供了IOCtl和sysfs两种方案。个人感觉sysfs更灵活。
sysfs就是在/sys/xxx路径下创建一个文件夹,并在文件夹下创建若干个文件。
在用户态我们可以使用cat、echo读写文件,从而读写内核态的数据。
示例:
在/sys/kernel路径下挂在一个叫做“kobject_example”的文件夹,并在其下创建baz的文件。
通过在/sys/kernel/kobject_example读写baz文件,来达到读写内核态的数据目的。
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/init.h>
/*这几个变量用于读写文件的打印;用于文件名*/
static int baz;
/*函数的参数这几个必须有,不然编译不过*/
static ssize_t b_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
int var;
printk("%s[%d]\n", __func__, __LINE__);
if(strcmp(attr->attr.name, "baz") == 0)
{
var = baz;
}
return sprintf(buf, "%d\n", var);
}
/*函数的参数这几个必须有,不然编译不过*/
static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int var,ret;
printk("%s[%d]\n", __func__, __LINE__);
/*将字符串转化为int*/
ret = kstrtoint(buf, 10, &var);
if(ret < 0)
{
return ret;
}
if(strcmp(attr->attr.name, "baz") == 0)
{
baz = var;
}
return count;
}
/*初始化baz_attribute
__ATTR(name, mode, show, store);
__ATTR里有个巧妙的用法,__stringify(_name)将int型变量名转化为字符串,变成文件名
*/
static struct kobj_attribute baz_attribute =
__ATTR(baz, 0664, b_show, b_store);
/*属性组成员*/
static struct attribute *attrs[] = {
&baz_attribute.attr,
NULL,
};
static struct attribute_group attr_group ={
//.attrs是二级指针
.attrs = attrs,
};
static struct kobject *kobj;
static int __init kboject_init(void)
{
int retval;
printk("%s[%d]\n", __func__, __LINE__);
/*执行完kobject_create_and_add,会在/sys/kernel路径下创建kboject_example文件夹*/
kobj = kobject_create_and_add("kboject_example",kernel_kobj);
if(!kobj)
{
return -ENOMEM;
}
/*执行完sysfs_create_group,会在/sys/kernel/kboject_example创建属性组中定义的文件*/
retval = sysfs_create_group(kobj, &attr_group);
if(retval)
kobject_put(kobj);
return retval;
}
static void __exit kboject_exit(void)
{
printk("%s[%d]\n", __func__, __LINE__);
kobject_put(kobj);
}
module_init(kboject_init);
module_exit(kboject_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Greg Kroah-Hartman <[email protected]>");
Makefiel
ifneq ($(KERNELRELEASE),)
obj-m:=kobject.o
else
KDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.ko *.o *.symvers *.cmd *.cmd.o *.mod.c *.order *.cmd
endif
读写baz文件测试
[email protected]:/sys/kernel$ ls
boot_params debug irq kexec_crash_size mm rcu_expedited slab uevent_seqnum
cgroup fscaps kboject_example kexec_loaded notes rcu_normal tracing vmcoreinfo
config iommu_groups kexec_crash_loaded livepatch profiling security uevent_helper
[email protected]:/sys/kernel$ cd ./kboject_example/
[email protected]:/sys/kernel/kboject_example$ ls
baz
[email protected]:/sys/kernel/kboject_example$ cat baz
0
[email protected]:/sys/kernel/kboject_example$ echo 2 > baz
-bash: baz: Permission denied
[email protected]:/sys/kernel/kboject_example$ su
Password:
[email protected]:/sys/kernel/kboject_example# echo 2 > baz
[email protected]:/sys/kernel/kboject_example# cat baz
2
dmesg打印:
我在每个函数中加入了printk打印,便于理解函数执行。
执行下面命令监控dmesg
watch "dmesg|tail -n 20"
监控结果:
[143666.698254] kboject_init[10]
[143703.990046] kboject_exit[16]
[146363.153040] kboject_init[73]
[146402.610407] b_show[19]
[146418.206658] b_store[34]
[146481.251760] b_show[19]
上一篇: Access应用笔记<二>
下一篇: 表单$_post[]的有关问题
推荐阅读