zoukankan      html  css  js  c++  java
  • 在linux内核中读写文件2

    1,内核代码

    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/types.h>
    #include <linux/spinlock.h>
    #include <linux/blkdev.h>
    #include <linux/module.h>  
    #include <linux/fs.h>  
    #include <linux/errno.h>  
    #include <linux/mm.h>  
    #include <linux/cdev.h>  
    #include <linux/sched.h>
    
    #define IO_CMD_LEN      1024  
    #define CHAR_DEV_NAME   "klog"
    
    typedef struct 
    {
        int file_id; //todo
        int rw_pos;  //todo
        int cmd_type;
        int buff_len;
        char io_buff[IO_CMD_LEN - 16];
    }KLOG_CMD_INFO;
    
    #if 1
    
    struct file *klog_fp = NULL;
    loff_t klog_pos = 0;
    
    static int user_cmd_proc(char *user_cmd, char *out_str)
    {
        KLOG_CMD_INFO *klog_cmd = (KLOG_CMD_INFO *)user_cmd;
        KLOG_CMD_INFO *klog_ack = (KLOG_CMD_INFO *)out_str;
        
        if(klog_cmd->cmd_type == 1) { //open file
            if (klog_fp != NULL)  filp_close(klog_fp, NULL);
                
            klog_fp = filp_open(klog_cmd->io_buff, O_RDWR | O_CREAT | O_TRUNC, 0644);
            if (IS_ERR(klog_fp)){
                printk("filp_open error 
    ");
                return -1;
            }
            klog_pos = 0;
            sprintf(klog_ack->io_buff, "filp_open ok
    ");
        }
        
        if(klog_cmd->cmd_type == 2) { //write file
            mm_segment_t old_fs;
            old_fs = get_fs();
            set_fs(KERNEL_DS); //to check why
            klog_pos += vfs_write(klog_fp, klog_cmd->io_buff, klog_cmd->buff_len, &klog_pos);
            set_fs(old_fs);
            sprintf(klog_ack->io_buff, "vfs_write ok
    ");
        }
    
        if(klog_cmd->cmd_type == 3) { //close file
            filp_close(klog_fp, NULL);
            klog_fp = NULL;
            sprintf(klog_ack->io_buff, "filp_close ok
    ");
        }
        
        return 0;
    }
    #endif
    
    #if 1
      
    int mem_open(struct inode *inode, struct file *filp)  
    {  
        return 0;   
    }  
      
    int mem_release(struct inode *inode, struct file *filp)  
    {  
        return 0;  
    }  
    
    char user_cmd[IO_CMD_LEN] = {0};
    char out_str[IO_CMD_LEN] = {0};
    
    int mem_ioctl( struct file *file, unsigned int cmd, unsigned long arg)
    {    
        printk("mem_ioctl: %d 
    ", cmd);    
        
        if(copy_from_user(user_cmd,  (int *)arg, IO_CMD_LEN)) 
            return -EFAULT;
        
        user_cmd_proc(user_cmd, out_str);
        
        if(copy_to_user( (int *)arg, out_str, IO_CMD_LEN)) 
            return -EFAULT;
    
        return 0;
    }
    
    static int mem_major = 0;
    struct class *pclass = NULL;  
    struct cdev my_dev;   
    
    static const struct file_operations mem_fops =  
    {  
        .owner = THIS_MODULE,  
        .unlocked_ioctl = mem_ioctl,
        .open = mem_open,  
        .release = mem_release,  
    };  
    
    static int memdev_init(void)  
    {  
        int result;  
    
        dev_t devno = MKDEV(mem_major, 0);  
    
        if (mem_major) { /* 静态申请设备号*/  
            result = register_chrdev_region(devno, 2, CHAR_DEV_NAME);  
        } else { /* 动态分配设备号 */  
            result = alloc_chrdev_region(&devno, 0, 2, CHAR_DEV_NAME);  
            mem_major = MAJOR(devno);  
        }   
    
        if (result < 0)  {  
            printk("alloc_chrdev failed!
    ");  
            return result;  
        }  
    
        cdev_init(&my_dev, &mem_fops);  
        my_dev.owner = THIS_MODULE;  
        my_dev.ops = &mem_fops;  
        cdev_add(&my_dev, MKDEV(mem_major, 0), 2);   /*设备数2*/  
    
        pclass = class_create(THIS_MODULE, CHAR_DEV_NAME);  
        if (IS_ERR(pclass))  {  
            printk("class_create failed!
    ");  
            goto failed;  
        }  
    
        device_create(pclass, NULL, devno, NULL, CHAR_DEV_NAME);  
        return 0;  
    
    failed:   
        cdev_del(&my_dev);
        unregister_chrdev_region(devno, 1);  
        return result;  
    }  
      
    static void memdev_exit(void)  
    {  
        device_destroy(pclass, MKDEV(mem_major, 0));  
        class_destroy(pclass);
        
        cdev_del(&my_dev);
        unregister_chrdev_region(MKDEV(mem_major, 0), 2); 
    }  
    #endif
      
    MODULE_AUTHOR("derek yi");  
    MODULE_LICENSE("GPL");  
      
    module_init(memdev_init);  
    module_exit(memdev_exit);  

    2,测试代码

    #include <stdio.h>  
    #include <fcntl.h>  
    #include <stdlib.h>  
    #include <string.h>  
    #include <sys/types.h>  
    #include <sys/stat.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <signal.h>
    #include <sys/syscall.h>
    
    #define IO_CMD_LEN      1024  
    
    typedef struct 
    {
        int file_id; //todo
        int rw_pos;  //todo
        int cmd_type;
        int buff_len;
        char io_buff[IO_CMD_LEN - 16];
    }KLOG_CMD_INFO;
    
    KLOG_CMD_INFO cmd_info;
    
    int main()
    {
        int fd;
        int ret = 0;
    
        fd = open("/dev/klog", O_RDWR);
        if( fd < 0 ) {
            printf("open memdev WRONG!
    ");
            return 0;
        }
    
        sprintf(cmd_info.io_buff, "/home/derek/klog.txt");
        cmd_info.cmd_type = 1;
        ret = ioctl(fd, 0, &cmd_info);
        printf("open: ret=%d rdata:%s
    ", ret, cmd_info.io_buff);
    
        for(int i = 0; i < 10; i++) {
            sprintf(cmd_info.io_buff, "%d: ==============================
    ", i);
            cmd_info.buff_len = strlen(cmd_info.io_buff);
            cmd_info.cmd_type = 2;
            ret = ioctl(fd, 0, &cmd_info);
            printf("read: ret=%d rdata:%s
    ", ret, cmd_info.io_buff);
        }
    
        cmd_info.cmd_type = 3;
        ret = ioctl(fd, 0, &cmd_info);
        printf("close: ret=%d rdata:%s
    ", ret, cmd_info.io_buff);
       
        close(fd);
        return 0;
    }
  • 相关阅读:
    sql server 2008 express 使用ip登陆 error:40 错误:2
    C#将Enum枚举映射到文本字符串
    Qt 自定义事件
    constexpr-C++11
    C++11 Lambda表达式(匿名函数)
    Qt5-调试器安装
    Qt5之坐标系统
    八大排序算法总结
    Qt之类反射机制
    Qt5之反射机制(内省)
  • 原文地址:https://www.cnblogs.com/soul-stone/p/6719868.html
Copyright © 2011-2022 走看看