Linux/Device Driver

[source] copy_from_user, copy_to_user testing

aucd29 2013. 9. 26. 17:22
[code]copy_from_user, copy_to_user testing

유저 메모리를 커널 메모리로 그리고 그걸 다시 유저 메모리로
이동 할 수 있는지를 테스트 하기 위한 디바이스 드라이버

result : success[/code]

//-------------------------------------------------
// user app
//-------------------------------------------------

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#define DEVNAME "/dev/ofddev"

int main()
{
    int dev;
    char buf[128];
    int loop, out;

    strcpy(buf,"hello world");

    // device open
    dev = open(DEVNAME, O_RDWR|O_NDELAY);
    if(dev >= 0)
    {
        printf("writing \n");
        write(dev, buf, 11);
    
        memset(buf, 0, sizeof(buf));
        
        printf("init buf : %s \n", buf);
        
        printf("reading \n");
        out = read(dev, buf, 11);
        printf("read buf : %s \n", buf);
    }
    else
    {
            printf("open fail\n");
    }


    return 0;
}

//-------------------------------------------------
// user device driver
//-------------------------------------------------

#include <linux/module.h>
#include <linux/kernel.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <asm/io.h>

#define RDWR_DEV_NAME    "ofddev"
#define RDWR_DEV_MAJOR    250
#define RDWR_WRITE_ADDR    0x378
#define RDWR_READ_ADDR    0x379

char *buff;

int ofd_open(struct inode* inode, struct file* filp)
{
    MOD_INC_USE_COUNT;
    return 0;
}

ssize_t ofd_read(struct file* filp, char* ubuf, size_t count, loff_t* f_pos)
{
    int err;

    if(err = copy_to_user(ubuf, buff, count)< 0) return err;

    kfree(buff);
}

ssize_t ofd_write(struct file* filp, const char* buf, size_t count, loff_t* f_pos)
{
    int err;

    buff = (char*)kmalloc(count, GFP_KERNEL);

    // copy_from_user : userbuff > kernelbuff copied
    if(err = copy_from_user(buff, buf, count) < 0) return err;
    printk(KERN_DEBUG"[ccd] cfu Userbuff : %s(%p), Kernelbuff : %s(%p)\n", buf, buf, buff, buff);


//    kfree(buff);
}

int ofd_release(struct inode* inode, struct file* filp)
{
    MOD_DEC_USE_COUNT;
    return 0;
}


struct file_operations ofd_fops =
{
    read: ofd_read,
    write: ofd_write,
    open: ofd_open,
    release: ofd_release,
};

//int init_moudule(void)

static int start_m(void)
{
    int result;
    
    printk("reg ofddev\n");
//    result = register_chrdev(RDWR_DEV_MAJOR, RDWR_DEV_NAME, &ofd_fops);
    result = register_chrdev(0, RDWR_DEV_NAME, &ofd_fops);

    printk("register num: %d , return:%d \n", RDWR_DEV_MAJOR, result);

    if(result < 0)
    {
            printk("error register \n");
            return result;
    }

    return 0;
}

//void cleanup_module(void)
static void end_m(void)
{
    unregister_chrdev(RDWR_DEV_MAJOR, RDWR_DEV_NAME);
}

module_init(start_m);
module_exit(end_m);