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 interfaceの明示的実装の例(プレイヤーキャラクターのアニメーション切り替え)