zoukankan      html  css  js  c++  java
  • ubuntu/linux mint 创建proc文件的三种方法(四)

    在做内核驱动开发的时候,能够使用/proc下的文件,获取对应的信息,以便调试。

    大多数/proc下的文件是仅仅读的,但为了演示样例的完整性,都提供了写方法。


    方法一使用create_proc_entry创建proc文件(简单,但写操作有缓冲区溢出的危急)

    方法二使用proc_create和seq_file创建proc文件(较方法三简洁)

    方法三使用proc_create_data和seq_file创建proc文件(较麻烦,但比較完整)

    演示样例四在proc文件里使用内核链表的一个演示样例(用的方法三)

    --------------------------------------------------------------------------------------------------------------------

    四、

    proc_test04.c 源代码

    #include <linux/module.h>
    #include <linux/sched.h>
    #include <linux/proc_fs.h>
    #include <linux/seq_file.h>
    #include <linux/uaccess.h>
    #include <linux/slab.h>
    
    struct proc_head
    {
    	struct list_head lhead;
    	int item_count;
    	int str_count;
    };
    
    struct proc_item
    {
    	struct list_head litem;
    	char *buf;
    	int num;
    };
    
    struct proc_head *gp_head;
    
    // linux/seq_file.h
    // void * (*start) (struct seq_file *m, loff_t *pos);
    // void (*stop) (struct seq_file *m, void *v);
    // void * (*next) (struct seq_file *m, void *v, loff_t *pos);
    // int (*show) (struct seq_file *m, void *v);
    
    /**
    * author:  aran
    * fuction: seq_operations -> start
    */
    static void *my_seq_start(struct seq_file *m, loff_t *pos)
    {
    	struct proc_item *entry;
    
    	if (0 == *pos)
    	{
    		seq_printf(m, "List has %d items, total %d bytes
    ", gp_head->item_count, gp_head->str_count);
    	}
    
    	// get first item
    	++*pos;
    	list_for_each_entry(entry, &gp_head->lhead, litem)
    	{
    		if (*pos == entry->num)
    		{
    			return entry;
    		}
    	}
    	return NULL;
    }
    
    /**
    * author:  aran
    * fuction: seq_operations -> next
    */
    static void *my_seq_next(struct seq_file *m, void *v, loff_t *pos)
    {
    	struct proc_item *entry;
    
    	// get next item
    	++*pos;
    	list_for_each_entry(entry, &gp_head->lhead, litem)
    	{
    		if (*pos == entry->num)
    		{
    			return entry;
    		}
    	}
    	return NULL;
    }
    
    /**
    * author:  aran
    * fuction: seq_operations -> stop
    */
    static void my_seq_stop(struct seq_file *m, void *v)
    {
    	// clean sth.
    	// nothing to do
    }
    
    /**
    * author:  aran
    * fuction: seq_operations -> show
    */
    static int my_seq_show(struct seq_file *m, void *v)
    {
    	struct proc_item *tmp = v;
    	seq_printf(m, "%s", tmp->buf);
    
    	return 0;
    }
    
    // global var
    static struct seq_operations my_seq_fops = 
    {
    	.start	= my_seq_start,
    	.next	= my_seq_next,
    	.stop	= my_seq_stop,
    	.show	= my_seq_show,
    };
    
    // file_operations
    // int (*open) (struct inode *, struct file *)
    // ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *)
    
    /**
    * author:  aran
    * fuction: file_operations -> open
    */
    static int proc_seq_open(struct inode *inode, struct file *file)
    {
    	return seq_open(file, &my_seq_fops);
    }
    
    /**
    * author:  aran
    * fuction: file_operations -> write
    */
    static ssize_t proc_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *f_pos)
    {
    	struct proc_item *tmp;
    	int ret;
    
    	// allocate proc_item
    	tmp = (struct proc_item *)kzalloc(sizeof(*tmp), GFP_KERNEL);
    	if (NULL == tmp)
    	{
    		ret = -ENOMEM;
    		goto err_kzalloc1;
    	}
    	INIT_LIST_HEAD(&tmp->litem);
    
    	// allocate str buf
    	tmp->buf = (char *)kzalloc(count, GFP_KERNEL);
    	if (NULL == tmp->buf)
    	{
    		ret = -ENOMEM;
    		goto err_kzalloc2;
    	}
    
    	if (0 != copy_from_user(tmp->buf, buffer, count))
    	{
    		ret = -1;
    		goto err_copy;
    	}
    
    	list_add(&tmp->litem, &gp_head->lhead);
    	gp_head->item_count++;
    	gp_head->str_count += count;
    	tmp->num = gp_head->item_count; 
    
    	return count;
    
    err_copy:
    	kfree(tmp->buf);
    err_kzalloc2:
    	kfree(tmp);
    err_kzalloc1:
    	return ret;
    }
    
    // global var
    static struct file_operations proc_seq_fops = 
    {
    	.owner		= THIS_MODULE,
    	.open		= proc_seq_open,
    	.read		= seq_read,
    	.write		= proc_seq_write,
    	.llseek		= seq_lseek,
    	.release	= seq_release,
    };
    
    static int __init my_init(void)
    {
    	struct proc_dir_entry *file;
    	int ret;
    
    	// allocate & init proc_head
    	gp_head = (struct proc_head *)kzalloc(sizeof(*gp_head), GFP_KERNEL);
    	if (NULL == gp_head)
    	{
    		ret = -ENOMEM;
    		goto err_kzalloc;
    	}
    	gp_head->item_count = 0;
    	gp_head->str_count = 0;
    	INIT_LIST_HEAD(&gp_head->lhead);
    
    	// create "/proc/proc_seq" file
    	file = proc_create_data(
    		"proc_seq",	// name
    		0666,		// mode
    		NULL,		// parent dir_entry
    		&proc_seq_fops,	// file_operations
    		NULL		// data
    		);
    	if (NULL == file)
    	{
    		printk("Count not create /proc/proc_seq file!
    ");
    		ret = -1;
    		goto err_proc_create_data;
    	}
    
    	return 0;
    
    err_proc_create_data:
    	kfree(gp_head);
    err_kzalloc:
    	return ret;
    }
    
    static void __exit my_exit(void)
    {
    	struct proc_item *tmp1, *tmp2;
    
    	remove_proc_entry("proc_seq", NULL);
    	list_for_each_entry_safe(tmp1, tmp2, &gp_head->lhead,litem)
    	{
    		list_del(&tmp1->litem);
    		kfree(tmp1->buf);
    		kfree(tmp1);
    	}
    	kfree(gp_head);
    }
    
    module_init(my_init);
    module_exit(my_exit);
    
    MODULE_AUTHOR("aran");
    MODULE_LICENSE("GPL");
    Makefile文件:

    obj-m	:= proc_test04.o
    KERNEL	:= /lib/modules/`uname -r`/build #for mint/ubuntu
    #KERNEL	:= /lib/modules/`uname -r`/source #for redhat
    
    all:
    	make -C $(KERNEL) M=`pwd` modules
    
    install:
    	make -C $(KERNEL) M=`pwd` modules_install
    	depmod -A
    
    clean:
    	make -C $(KERNEL) M=`pwd` clean
    測试结果:


  • 相关阅读:
    Java核心技术 卷一 笔记四 库类的直接使用
    Java核心技术 卷一 笔记三 大数值及数组
    Java核心技术 卷一 笔记2 字符串的复制
    Java核心技术 卷一 笔记1
    修改css 样式后, hover事件 不生效
    修改 element ui input 输入框 样式不生效问题
    css3 计算属性
    Vue3 改动系列
    浏览器实现,向下滑动 鼠标滚轮,页面横向移动
    linux ceont0s7 vue 打包压缩图片 一直报错
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3933585.html
Copyright © 2011-2022 走看看