linux 用户态和内核态通信proc系统

1、proc系统是一个虚拟的系统机器在一启动的时候就已经挂在上了,其原理我们不在分析。之后我们只管用proc系统就ok了。

内核提供了一些api来操作proc系统。这里主要就是创建目录proc_mkdir ,创建文件proc_create 和create_proc_entry,删除remove_proc_entry

2、proc_create 和create_proc_entry 都说有区别实质是一样的。区别在于proc_create 参数传入了file_operations *proc_fops,file_openrationes 结构是对文件的操作(不懂的可以查这里不做解释)其实内部也是一个指向pde->proc_fops = proc_fops;  pde就是proc_create 和 create_proc_entry的返回值。如果我们用create_proc_entry可以后续自己给赋值。个人感觉不要太纠结这个。就是内核给你了不同的封装。实现的结果是一样的。不过人们现在都用proc_create,那么咱们也用这样显得高大上。

3、说完上面的创建了我们来看怎们对proc文件进行读写操作。

说道打开读写操作就用到了我们上面说的那个file_operations结构了。这里对其中的成员不做过多的解释只说我们用到的。结构及赋值如下

static const struct file_operations whitelist_proc_fops = { 
        .owner      = THIS_MODULE,
        .open       = whitelist_proc_open,
        .read       = seq_read,
        .llseek     = seq_lseek,
        .release    = seq_release,
        .write      = cciss_proc_write,
};

4、文件的读其实就是用户态从内核态获取数据,因为我们的proc系统是内存的系统,就是所有的数据都在内存了存着,无论你是用链表还是数组,当用户调用读的时候我们就会copy_to_user 我们的数据。当用户写的时候我们就会copy_from_user 到我们的内核的数组或者链表存储。

5、咱们自己维护一套内存的系统管理很麻烦,尤其是多个page的读的时候,那么内核自己实现了一套接口是 seq_file .所以我们就直接调用就行了。但是seq_write好像没有用好,只有seq_read。还有就是在open的时候咱们可以给proc文件初始化内容,说白了就是在分配的内存中提前写点东西。

6、到此写完,总结一点咱们用proc文件其实就是操作一块内存,用户写的数据你写到你定义的内存,用户读你就从你内存中拷贝给用户。其实就这么简单。proc一般是内核给用户显示内容。或者用户简单的写一点内容。

自己写了一个例子

#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>

#define PORC_ROOTDIR  "security"
#define PORC_WHITELIST  "whitelist"

struct proc_dir_entry *security_dir = NULL;
struct proc_dir_entry *security_whitelist = NULL;
static char *str = NULL;

static int my_proc_show(struct seq_file *m, void *v)
{ //可以在open的时候写上自己的内容就是在初始化内存的东西因为我用了seq所以建议都用他封装好的seq_printf

      seq_printf(s, "11111111\n");
        return 0;
}
static int whitelist_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, my_proc_show, NULL);
}

static ssize_t
cciss_proc_write(struct file *file, const char __user *buf,
                 size_t length, loff_t *ppos)
{
        int err;
        char *buffer;

        if (!buf || length > PAGE_SIZE - 1)
                return -EINVAL;

        buffer = (char *)__get_free_page(GFP_KERNEL);
        if (!buffer)
                return -ENOMEM;

        err = -EFAULT;
        if (copy_from_user(buffer, buf, length))
                goto out;
        buffer[length] = '\0';
        printk("%s\n",buffer);
out:
        free_page((unsigned long)buffer);
}


static int helloworld_exit(void) {
        remove_proc_entry(PORC_ROOTDIR, security_dir);
        remove_proc_entry(PORC_WHITELIST, security_dir);
        printk(KERN_INFO "see you.\n");
        return 0;
}

module_init(helloworld_init);
module_exit(helloworld_exit);
MODULE_LICENSE("GPL");
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值