linux proc 文件怎样传入内核的,使用 /proc 文件系统来访问 Linux 内核的内容

内核程序员可以使用的标准 API,LKM 程序员也可以使用。LKM 甚至可以导出内核使用的新变量和函数。有关 API 的完整介绍已经超出了本文的范围,因此我们在这里只是简单地介绍后面在展示一个更有用的 LKM 时所使用的几个元素。

要在 /proc 文件系统中创建一个虚拟文件,请使用 create_proc_entry 函数。这个函数可以接收一个文件名、一组权限和这个文件在 /proc 文件系统中出现的位置。create_proc_entry 的返回值是一个 proc_dir_entry 指针(或者为 NULL,说明在 create 时发生了错误)。然后就可以使用这个返回的指针来配置这个虚拟文件的其他参数,例如在对该文件执行读操作时应该调用的函数。create_proc_entry 的原型和 proc_dir_entry 结构中的一部分如清单 7 所示。

清单 7. 用来管理 /proc 文件系统项的元素

struct proc_dir_entry *create_proc_entry( const char *name, mode_t mode,

struct proc_dir_entry *parent );

struct proc_dir_entry {

const char *name;// virtual file name

mode_t mode;// mode permissions

uid_t uid;// File's user id

gid_t gid;// File's group id

struct inode_operations *proc_iops;// Inode operations functions

struct file_operations *proc_fops;// File operations functions

struct proc_dir_entry *parent;// Parent directory

...

read_proc_t *read_proc;// /proc read function

write_proc_t *write_proc;// /proc write function

void *data;// Pointer to private data

atomic_t count;// use count

...

};

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

稍后我们就可以看到如何使用 read_proc 和 write_proc 命令来插入对这个虚拟文件进行读写的函数。

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

parent 参数可以为 NULL(表示 /proc 根目录),也可以是很多其他值,这取决于我们希望将这个文件放到什么地方。表 1 列出了可以使用的其他一些父 proc_dir_entry,以及它们在这个文件系统中的位置。

表 1. proc_dir_entry 快捷变量

proc_dir_entry

在文件系统中的位置

proc_root_fs

/proc

proc_net

/proc/net

proc_bus

/proc/bus

proc_root_driver

/proc/driver

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

int mod_write( struct file *filp, const char __user *buff,

unsigned long len, void *data );

filp 参数实际上是一个打开文件结构(我们可以忽略这个参数)。buff 参数是传递给您的字符串数据。缓冲区地址实际上是一个用户空间的缓冲区,因此我们不能直接读取它。len 参数定义了在 buff 中有多少数据要被写入。data 参数是一个指向私有数据的指针(参见 清单 7)。在这个模块中,我们声明了一个这种类型的函数来处理到达的数据。

Linux 提供了一组 API 来在用户空间和内核空间之间移动数据。对于 write_proc 的情况来说,我们使用了 copy_from_user 函数来维护用户空间的数据。

我们可以使用 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_mkdir、symlinks 以及 proc_symlink 在 /proc 文件系统中创建目录。对于只需要一个 read 函数的简单 /proc 项来说,可以使用 create_proc_read_entry,这会创建一个 /proc 项,并在一个调用中对 read_proc 函数进行初始化。这些函数的原型如清单 8 所示。

清单 8. 其他有用的 /proc 函数

/* Create a directory in the proc filesystem */

struct proc_dir_entry *proc_mkdir( const char *name,

struct proc_dir_entry *parent );

/* Create a symlink in the proc filesystem */

struct proc_dir_entry *proc_symlink( const char *name,

struct proc_dir_entry *parent,

const char *dest );

/* Create a proc_dir_entry with a read_proc_t in one call */

struct proc_dir_entry *create_proc_read_entry( const char *name,

mode_t mode,

struct proc_dir_entry *base,

read_proc_t *read_proc,

void *data );

/* Copy buffer to user-space from kernel-space */

unsigned long copy_to_user( void __user *to,

const void *from,

unsigned long n );

/* Copy buffer to kernel-space from user-space */

unsigned long copy_from_user( void *to,

const void __user *from,

unsigned long n );

/* Allocate a 'virtually' contiguous block of memory */

void *vmalloc( unsigned long size );

/* Free a vmalloc'd block of memory */

void vfree( void *addr );

/* Export a symbol to the kernel (make it visible to the kernel) */

EXPORT_SYMBOL( symbol );

/* Export all symbols in a file to the kernel (declare before module.h) */

EXPORT_SYMTAB0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值