c_cpp B3_A_カーネルハック课题4キャラクタデバイス

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp B3_A_カーネルハック课题4キャラクタデバイス相关的知识,希望对你有一定的参考价值。

// simple_chardev_test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>     //strlen
#include <sys/ioctl.h>  //ioctl
#include <unistd.h>     //write
#include <fcntl.h>      //O_RDWR
#include <errno.h>      //errono

#include "ioctl_simple_chardev.h"
#define DEVFILE "simple_chardev0"
#define BUF_SIZE 10

int open_file(char *filename)
{
    int fd;

    fd = open(filename, O_RDWR);
    if (fd == -1) {
        perror("open");
    }
    return (fd);
}

void close_file(int fd)
{
    if (close(fd) != 0) {
        perror("close");
    }
}

void read_file(int fd, int count)
{
    unsigned char buf[count], *p;
    ssize_t ret;

    ret = read(fd, buf, sizeof(buf));
    if (ret > 0) {
        p = buf;
        while (ret--)
            printf("%c", *p++);
    } else {
        perror("read");
    }

    printf("\n");
}

void write_file(int fd, char *str)
{
    ssize_t ret;

    ret = write(fd, str, strlen(str));
    if (ret <= 0) {
        perror("write");
    }
}
void ioctl_file(int fd, unsigned long query, struct data_t* q){
    if (ioctl(fd, query, (unsigned long)q) == -1){
        printf("errno %d\n", errno);
    }else{
        if (query == QUERY_GET) {
            printf("return : %d\n", q->val);
        }
    }
}


int main(void)
{
    int fd;
    struct data_t q;

    fd = open_file(DEVFILE);

    read_file(fd, BUF_SIZE);
    write_file(fd, "testttyy");
    read_file(fd, 10);

    write_file(fd, "abcdefg");
    read_file(fd, 10);

    ioctl_file(fd, QUERY_GET, &q);
    q.val = 1100;
    ioctl_file(fd, QUERY_SET, &q);
    ioctl_file(fd, QUERY_GET, &q);


    close_file(fd);

    return 0;
}
#ifndef QUERY_IOCTL_H
#define QUERY_IOCTL_H
#define IOC_MAGIC 'q'
#include <linux/ioctl.h>

struct data_t
{
        int val;
};

#define QUERY_GET _IOR(IOC_MAGIC, 1, struct data_t)
#define QUERY_SET _IOW(IOC_MAGIC, 2, struct data_t)
#define QUERY_PRINTK _IO(IOC_MAGIC, 3)

#endif
/*
 * simple_chardev.c
 *
 */
#include <linux/init.h>		
#include <linux/module.h>	/* MODULE macro, THIS_MODULE */	
#include <linux/kernel.h>	/* printk() */
#include <linux/types.h>	/* dev_t */	
#include <linux/fs.h>		/* alloc_chrdev_region(), ... */
#include <linux/cdev.h>     /* cdev_*() */

#include <linux/sched.h>        /* current */
#include <linux/errno.h>	    /* error codes */
#include <linux/slab.h>         /* kmalloc() */
#include <linux/uaccess.h>      /* copy_to_user, copy_from_user */

#include "ioctl_simple_chardev.h"

MODULE_LICENSE("Dual BSD/GPL");
#define DRIVER_NAME "simple_chardev"
#ifndef SIMPLE_CHARDEV_BUFSIZE
#define SIMPLE_CHARDEV_BUFSIZE 10
#endif

static int simple_chardev_devs = 1;        /* device count */
static int simple_chardev_major = 0;       /* dynamic allocation */
static struct cdev simple_chardev_cdev;  

struct simple_chardev_data {
	char buf[SIMPLE_CHARDEV_BUFSIZE];
	size_t write_size;
	unsigned int val;
	rwlock_t lock;
};	

static long simple_chardev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){
		struct simple_chardev_data *p = filp->private_data;
		unsigned int val;
		struct data_t data;
		int retval = 0;


		if (_IOC_TYPE(cmd) != IOC_MAGIC ) {
			printk("%s: Magic number is %d\n", __func__,  IOC_MAGIC);
			retval = -ENOTTY;
			goto out;
		}
		memset(&data, 0, sizeof(data));
        printk("called myioctrl. argument is %lu\n", arg);

        switch(cmd){
			case QUERY_GET:
				if (!access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd))) {
					retval = -EFAULT;
					goto out;
				}
				read_lock(&p->lock);
				val = p->val;
				read_unlock(&p->lock);
				data.val = val;
				if (copy_to_user((void __user *)arg, &data, sizeof(data))){
					retval = -EFAULT;
					goto out;
				}
				printk("QUERY_GET val: %d", val);
				break;

			case QUERY_SET:
				if (!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))) {
					retval = -EFAULT;
					goto out;
				}				
				if (copy_from_user(&data, (void __user *)arg, sizeof(data))){
					retval = -EFAULT;
					goto out;
				}
				write_lock(&p->lock);
				p->val = data.val;
				write_unlock(&p->lock);
				printk("QUERY_SET val: %d", data.val);
				break;
			case QUERY_PRINTK:
				printk("QUERY_PRINTK");
				break;

			default:
				printk("%s: Invalid query\n", __func__);
				retval = -ENOTTY;
        }
out:
	return (retval);
}


ssize_t simple_chardev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
	struct simple_chardev_data *p = filp->private_data;
	int retval = 0;
	size_t write_size = (count > p->write_size) ? 
				p->write_size : count;
	printk("%s: count %lu pos %lld\n", __func__, count, *f_pos);

	read_lock(&p->lock);
	if(copy_to_user(buf, p->buf, write_size)) {
		retval = -EFAULT;
 		goto out;
	}
	read_unlock(&p->lock);
	retval = write_size;

out:
	return (retval);
}

ssize_t simple_chardev_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	struct simple_chardev_data *p = filp->private_data;
	int retval = 0;
	size_t write_size = (count > SIMPLE_CHARDEV_BUFSIZE) ? 
                SIMPLE_CHARDEV_BUFSIZE : count;
	printk("%s: count %lu pos %lld\n", __func__, count, *f_pos);

	write_lock(&p->lock);
	if(copy_from_user(p->buf, buf, write_size)) {
		retval = -EFAULT;
		goto out;
	}
	p->write_size = write_size;
	write_unlock(&p->lock);
	retval = count;

out:
	return (retval);
}



static int simple_chardev_open(struct inode *inode, struct file *file)
{
	struct simple_chardev_data *p;

	printk("%s: major %d minor %d (pid %d)\n", __func__,
			imajor(inode),
			iminor(inode),
			current->pid
		  );

	p = kmalloc(sizeof(struct simple_chardev_data), GFP_KERNEL);
	if (p == NULL) {
		printk("%s: Not memory\n", __func__);
		return -ENOMEM;
	}

	p->buf[0] = '\0';
	p->write_size = 0;
	p->val = 0xff;
	rwlock_init(&p->lock);

	file->private_data = p;

	return 0;
}

static int simple_chardev_close(struct inode *inode, struct file *file)
{
	printk("%s: major %d minor %d (pid %d)\n", __func__,
			imajor(inode),
			iminor(inode),
			current->pid
		  );

	if (file->private_data) {
		kfree(file->private_data);
		file->private_data = NULL;
	}

	return 0;
}

struct file_operations simple_chardev_fops = {
	.open = simple_chardev_open,
	.release = simple_chardev_close,
	.read = simple_chardev_read,
	.write = simple_chardev_write,
	.unlocked_ioctl = simple_chardev_ioctl,
};


static int simple_chardev_init(void)
{
	dev_t dev = MKDEV(simple_chardev_major, 0);
	int alloc_ret = 0;
	int major;
	int cdev_err = 0;

	alloc_ret = alloc_chrdev_region(&dev, 0, simple_chardev_devs, DRIVER_NAME);
	if (alloc_ret)
		goto error;
	simple_chardev_major = major = MAJOR(dev);

	cdev_init(&simple_chardev_cdev, &simple_chardev_fops);
	simple_chardev_cdev.owner = THIS_MODULE;

	cdev_err = cdev_add(&simple_chardev_cdev, MKDEV(simple_chardev_major, 0), simple_chardev_devs);
	if (cdev_err) 
		goto error;

	printk(KERN_ALERT "%s driver(major %d) installed.\n", DRIVER_NAME, major);

	return 0;

error:
	if (cdev_err == 0)
		cdev_del(&simple_chardev_cdev);

	if (alloc_ret == 0)
		unregister_chrdev_region(dev, simple_chardev_devs);

	return -1;
}

static void simple_chardev_exit(void)
{
	dev_t dev = MKDEV(simple_chardev_major, 0);

	cdev_del(&simple_chardev_cdev);
	unregister_chrdev_region(dev, simple_chardev_devs);

	printk(KERN_ALERT "%s driver removed.\n", DRIVER_NAME);
}

module_init(simple_chardev_init);
module_exit(simple_chardev_exit);

以上是关于c_cpp B3_A_カーネルハック课题4キャラクタデバイス的主要内容,如果未能解决你的问题,请参考以下文章

csharp 统一でキャラクターを移动させる

csharp interfaceの明示的実装の例(プレイヤーキャラクターのアニメーション切り替え)

text Linuxカーネルモジュール开発#memo

バイナリハックイージー / Unhappy Hacking (ABC Edit) (stack)

CV是啥意思?

中華淫夢ウィキ その二