linux 宏 DEVICE_ATTR

理解 DEVICE_ATTR

DEVICE_ATTR 是 Linux 内核中用于创建设备属性的宏,通常用于 sysfs 文件系统。通过 sysfs,用户空间的程序可以读取或修改内核中的设备属性。DEVICE_ATTR 宏定义在 <linux/device.h> 头文件中,用于声明和定义一个设备属性。

基本语法

DEVICE_ATTR 宏的基本语法如下:

c 复制代码
DEVICE_ATTR(_name, _mode, _show, _store);
  • _name:属性的名称,会在 /sys/ 下生成对应的文件。
  • _mode:文件的访问权限,例如 0644 表示用户可读写,组和其他用户只读。
  • _show:当用户读取该属性时调用的函数。
  • _store:当用户写入该属性时调用的函数。

使用示例

以下是一个简单的示例,展示如何使用 DEVICE_ATTR

c 复制代码
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

static char my_value[100] = "default";

static ssize_t show_my_value(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", my_value);
}

static ssize_t store_my_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    strncpy(my_value, buf, sizeof(my_value) - 1);
    my_value[sizeof(my_value) - 1] = '\0';
    return count;
}

static DEVICE_ATTR(my_value, 0644, show_my_value, store_my_value);

static struct device *my_device;

static int __init my_module_init(void)
{
    int ret;
    my_device = &(some_device); // 需要替换为实际的设备结构体
    ret = device_create_file(my_device, &dev_attr_my_value);
    if (ret) {
        printk(KERN_ERR "Failed to create device file\n");
        return ret;
    }
    return 0;
}

static void __exit my_module_exit(void)
{
    device_remove_file(my_device, &dev_attr_my_value);
}

module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");

关键点

  • showstore 函数是必须的,分别用于读取和写入属性。如果不需要写入功能,可以将 _mode 设置为只读(如 0444),并将 _store 设置为 NULL
  • DEVICE_ATTR 宏会生成一个名为 dev_attr_my_value 的结构体变量,其中 my_value 是属性的名称。
  • 使用 device_create_filedevice_remove_file 来创建和删除属性文件。

访问属性

在用户空间,可以通过以下方式访问该属性:

bash 复制代码
# 读取属性
cat /sys/.../my_value

# 写入属性
echo "new_value" > /sys/.../my_value

注意事项

  • 确保设备的 struct device 结构体已经正确初始化并注册到内核中。
  • store 函数中,必须对用户传入的数据进行验证,防止缓冲区溢出或其他安全问题。
  • 如果设备被卸载或移除,务必删除所有创建的属性文件,否则可能导致内核崩溃。

其他变体

除了 DEVICE_ATTR,Linux 内核还提供了其他类似的宏,例如:

  • DEVICE_ATTR_RO:只读属性,无需提供 store 函数。
  • DEVICE_ATTR_WO:只写属性,无需提供 show 函数。
  • DEVICE_ATTR_RW:读写属性,需要提供 showstore 函数。

这些宏的使用方式与 DEVICE_ATTR 类似,但更加简洁。

相关推荐
hhcgchpspk17 小时前
一次msf免杀渗透入门实践
linux·经验分享·网络安全·系统安全·渗透·msf
小白勇闯网安圈17 小时前
Vmware的Ubuntu构建极简版Linux发行版
linux
刘某的Cloud17 小时前
shell脚本-read-输入
linux·运维·bash·shell·read
broad-sky17 小时前
Ubuntu上查看USB相机连接的是哪个口,如何查看
linux·数码相机·ubuntu
秋深枫叶红17 小时前
嵌入式第三十七篇——linux系统编程——线程控制
linux·学习·线程·系统编程
shaohui97318 小时前
ARMv7 linux中断路由以及处理
linux·gic·cpsr·armv7
三小尛18 小时前
linux的开发工具vim
linux·运维·vim
陈陈爱java18 小时前
Conda 常用命令行
linux·windows·conda
twdnote18 小时前
dokcer 环境中集成LibreOffice
linux
ChristXlx18 小时前
Linux安装redis(虚拟机适用)
linux·运维·redis