当前位置 博文首页 > lyndon:proc 文件的创建和读写

    lyndon:proc 文件的创建和读写

    作者:[db:作者] 时间:2021-06-26 12:15

    内核版本

    Linux version 5.8.0-44-generic
    

    mydev.c

    #include <linux/module.h>
    #include <linux/moduleparam.h>
    #include <linux/init.h>
    #include <linux/kernel.h>   
    #include <linux/proc_fs.h>
    #include <asm/uaccess.h>
    
    #define BUFSIZE 100
    static int irq = 20;
    static int mode = 1;
    static struct proc_dir_entry *ent;
    
    static ssize_t mywrite(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
    {
    	int num, c, i, m;
    	char buf[BUFSIZE] = {0};
    
    	if (*ppos > 0 || count > BUFSIZE)
    		return -EFAULT;
    	if (copy_from_user(buf, ubuf, count))
    		return -EFAULT;
    	num = sscanf(buf, "%d %d", &i, &m);
    	if (num != 2)
    		return -EFAULT;
    	irq = i;
    	mode = m;
    	c = strlen(buf);
    	*ppos = c;
    	return c;
    }
    
    static ssize_t myread(struct file *file, char __user *ubuf, size_t count, loff_t *ppos)
    {
    	char buf[BUFSIZE] = {0};
    	int len = 0;
    
    	if (*ppos > 0 || count < BUFSIZE)
    		return 0;
    	len += sprintf(buf, "irq = %d\n", irq);
    	len += sprintf(buf + len, "mode = %d\n", mode);
    
    	if (copy_to_user(ubuf, buf, len))
    		return -EFAULT;
    	*ppos = len;
    	return len;
    }
    
    static struct file_operations myops = {
    	.owner = THIS_MODULE,
    	.read = myread,
    	.write = mywrite,
    };
    
    static int simple_init(void)
    {
    	ent = proc_create("mydev", 0666, NULL, (struct proc_ops *)&myops);
    	printk(KERN_ALERT "hello...\n");
    	return 0;
    }
    
    static void simple_cleanup(void)
    {
    	proc_remove(ent);
    	printk(KERN_WARNING "bye ...\n");
    }
    
    module_param(irq, int, 0660);
    module_param(mode, int, 0660);
    
    module_init(simple_init);
    module_exit(simple_cleanup);
    
    MODULE_LICENSE("Dual BSD/GPL");
    MODULE_AUTHOR("Liran B.H");
    

    Makefile

    obj-m:=mydev.o  
      
    CURRENT_PATH:=$(shell pwd)  
    VERSION_NUM:=$(shell uname -r)  
    LINUX_PATH:=/usr/src/linux-headers-$(VERSION_NUM)  
      
      
    all :  
    	make -C $(LINUX_PATH) M=$(CURRENT_PATH) modules  
    clean:  
    	make -C $(LINUX_PATH) M=$(CURRENT_PATH) clean 
    

    make && install

    $ make
    make -C /usr/src/linux-headers-5.8.0-44-generic     M=/home/liyongjun/project/c/study/kernel/proc   modules  
    make[1]: 进入目录“/usr/src/linux-headers-5.8.0-44-generic”
      CC [M]  /home/liyongjun/project/c/study/kernel/proc/mydev.o
      MODPOST /home/liyongjun/project/c/study/kernel/proc/Module.symvers
      CC [M]  /home/liyongjun/project/c/study/kernel/proc/mydev.mod.o
      LD [M]  /home/liyongjun/project/c/study/kernel/proc/mydev.ko
    make[1]: 离开目录“/usr/src/linux-headers-5.8.0-44-generic”
    

    insmod

    $ sudo insmod mydev.ko 
    

    read

    $ cat /proc/mydev 
    irq = 20
    mode = 1
    

    write

    $ echo 55 6 > /proc/mydev 
    $ cat /proc/mydev 
    irq = 55
    mode = 6
    

    user_app.c

    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    
    void main(void)
    {
    	char buf[100] = {0};
    
    	int fd = open("/proc/mydev", O_RDWR);
    	read(fd, buf, 100);
    	puts(buf);
    
    	lseek(fd, 0, SEEK_SET);
    	write(fd, "33 4", 5);
    
    	lseek(fd, 0, SEEK_SET);
    	read(fd, buf, 100);
    	puts(buf);
    }
    

    编译

    $ gcc user_app.c -o user_app.out
    

    运行

    $ ./user_app.out 
    irq = 55
    mode = 6
    
    irq = 33
    mode = 4
    

    rmmod

    $ sudo rmmod mydev
    

    参考

    如何使用内核API函数 proc_create?

    下一篇:没有了