sys和proc文件系统

本文介绍了Linux中的proc和sysfs文件系统,强调了sysfs在设计上的优势,如清晰性和每个属性文件仅做一件事。proc文件系统包括创建目录、文件、删除操作,以及读写回调函数的详细说明。sysfs文件系统用于设备驱动管理,展示了设备、驱动和总线的注册接口,以及/dev、/sys/devices和/sys/dev目录之间的关系。重点讨论了device_register、driver_register和bus_register的功能,并解释了如何通过sysfs和proc文件系统进行设备管理和交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

proc文件系统

创建目录

创建proc文件

删除proc文件/目录 

proc文件读回调函数

proc文件写回调函数

实例代码

sysfs文件系统

sysfs设备驱动管理简介

sysfs设备驱动管理相关注册接口

device_register主要功能

driver_register都做了些什么?

bus_register都做了些什么?

常用目录

/dev

/sys/devices 

/sys/dev

/dev和/sys/devices的关系


sysfs 与 proc 相比有很多优点,最重要的莫过于设计上的清晰。一个 proc 虚拟文件可能有内部格式,如 /proc/scsi/scsi ,它是可读可写的,(其文件权限被错误地标记为了 0444 !,这是内核的一个BUG),并且读写格式不一样,代表不同的操作,应用程序中读到了这个文件的内容一般还需要进行字符串解析,而在写入时需要先用字符串格式化按指定的格式写入字符串进行操作;相比而言, sysfs 的设计原则是一个属性文件只做一件事情, sysfs 属性文件一般只有一个值,直接读取或写入。整个 /proc/scsi 目录在2.6内核中已被标记为过时(LEGACY),它的功能已经被相应的 /sys 属性文件所完全取代。新设计的内核机制应该尽量使用 sysfs 机制,而将 proc 保留给纯净的“进程文件系统”。

proc文件系统

调用接口如下。

创建目录

struct proc_dir_entry *proc_mkdir(const char *name,  
                struct proc_dir_entry *parent); 

创建proc文件

struct proc_dir_entry *create_proc_entry( const char *name,  mode_t mode,  
                struct proc_dir_entry *parent );  

create_proc_entry函数用于创建一个一般的proc文件,其中name是文件名,比如“hello”,mode是文件模式,parent是要创建的proc文件的父目录(若parent = NULL则创建在/proc目录下)。create_proc_entry 的返回值是一个 proc_dir_entry 指针(或者为 NULL,说明在 create 时发生了错误)。然后就可以使用这个返回的指针来配置这个虚拟文件的其他参数,例如在对该文件执行读操作时应该调用的函数。

struct proc_dir_entry {  
    ......  
    const struct file_operations *proc_fops;    <==文件操作结构体  
    struct proc_dir_entry *next, *parent, *subdir;  
    void *data;  
    read_proc_t *read_proc;                    <==读回调  
    write_proc_t *write_proc;                  <==写回调  
    ......  
}; 

删除proc文件/目录 

void remove_dir_entry(const char *name, struct proc_dir_entry *parent);  

要从 /proc 中删除一个文件,可以使用 remove_proc_entry 函数。要使用这个函数,我们需要提供文件名字符串,以及这个文件在 /proc 文件系统中的位置(parent)。

proc文件读回调函数

static int (*proc_read)(char *page, char **start, off_t off, int count, int *eof, void *data);

我们可以使用 read_proc 函数从一个 /proc 项中读取数据(从内核空间到用户空间)。这个函数的原型如下:

int mod_read( char *page, char **start, off_t off,
int count, int *eof, void *data );

page参数是这些数据写入到的位置,其中count定义了可以写入的最大字符数。在返回多页数据(通常一页是4KB)时,我们需要使用start和off参数。当所有数据全部写入之后,就需要设置eof(文件结束参数)。与write类似,data表示的也是私有数据。此处提供的page缓存区在内核空间。因此我们可以直接写入,而不用调用copy_to_user。

proc文件写回调函数

static int proc_write_foobar(struct file *file, const char *buffer, unsigned long count, void *data);

proc文件实际上是一个叫做proc_dir_entry的struct(定义在proc_fs.h),该struct中有int read_proc和int write_proc两个元素,要实现proc的文件的读写就要给这两个元素赋值。但这里不是简单地将一个整数赋值过去就行了,需要实现两个回调函数。在用户或应用程序访问该proc文件时,就会调用这个函数,实现这个函数时只需将想要让用户看到的内容放入page即可。在用户或应用程序试图写入该proc文件时,就会调用这个函数,实现这个函数时需要接收用户写入的数据(buff参数)。

我们可以使用write_proc函数向/proc中写入一项。这个函数的原型如下:

int mod_write( struct file *filp, const char __user *buff,
unsigned long len, void *data );

 filp参数实际上是一个打开文件结构(我们可以忽略这个参数)。buf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李小白20200202

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值