增加字符设备参考(未完成).

Signed-off-by: ithink.chan <chenyang@autoai.com>
This commit is contained in:
ithink.chan 2020-04-27 11:45:57 +08:00
parent 80093e080e
commit cdd4e95da0
2 changed files with 148 additions and 0 deletions

View File

@ -0,0 +1,14 @@
obj-m:= \
demochar.o
demochar-objs:= \
demo_char.o
EXTRA_CFLAGS += \
-I$(PWD)
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

View File

@ -0,0 +1,134 @@
/**
* @file demo_char.c
* @author Rick Chan (cy187lion@sina.com)
* @brief Linux char driver demo.
* @version 0.1.0
* @date 2020-04-27
*
* @copyright Copyright (c) 2020
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
MODULE_AUTHOR("Rick Chan");
MODULE_LICENSE("GPL");
#define DEMO_MAGIC 'R'
#define DEMO_IOC_SIZE 8
#define DEMO_CTL_IOC _IOC(_IOC_READ|_IOC_WRITE, DEMO_MAGIC, 0, DEMO_IOC_SIZE)
#define DEMO_CTL_IO _IO(DEMO_MAGIC, 1)
#define DEMO_CTL_IOR _IOR(DEMO_MAGIC, 2, uint16_t)
#define DEMO_CTL_IOW _IOW(DEMO_MAGIC, 3, int32_t)
#define DEMO_CTL_IOWR _IOWR(DEMO_MAGIC, 4, uint32_t)
#define DEMO_CTL_MAX 5
static int demo_open(struct inode *inode, struct file* filp)
{
return 0;
}
static int demo_release(struct inode *inode, struct file* filp)
{
return 0;
}
static loff_t demo_llseek(struct file *filp, loff_t offset, int origin)
{
return filp->f_pos;
}
static ssize_t demo_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset)
{
const char __user *p = buffer;
return p-buffer;
}
static ssize_t demo_write(struct file *filp, const char __user *buffer, size_t count, loff_t *offset)
{
const char __user *p = buffer;
return p-buffer;
}
static long demo_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
// 检测 cmd 合法性
if (DEMO_MAGIC!=_IOC_TYPE(cmd))
return -EINVAL;
if (DEMO_CTL_MAX<_IOC_NR(cmd))
return -EINVAL;
switch(cmd)
{
case DEMO_CTL_IOC:
{
uint8_t tmp[DEMO_IOC_SIZE];
copy_from_user(&tmp, (void*)arg, _IOC_SIZE(cmd));
copy_to_user((void*)arg, &tmp, _IOC_SIZE(cmd));
}
break;
case DEMO_CTL_IO:
break;
case DEMO_CTL_IOR:
{
uint16_t tmp = 0x55AA;
copy_to_user((void*)arg, &tmp, _IOC_SIZE(cmd));
}
break;
case DEMO_CTL_IOW:
{
int32_t tmp = 0;
copy_from_user(&tmp, (void*)arg, _IOC_SIZE(cmd));
}
break;
case DEMO_CTL_IOWR:
{
uint32_t tmp = 0;
copy_from_user(&tmp, (void*)arg, _IOC_SIZE(cmd));
copy_to_user((void*)arg, &tmp, _IOC_SIZE(cmd));
}
break;
default:
return -ENOIOCTLCMD;
}
return 0;
}
static int demo_mmap(struct file* filp, struct vm_area_struct* vma)
{
return 0;
}
static struct file_operations demo_fops = {
.owner = THIS_MODULE,
.open = demo_open,
.release = demo_release,
.llseek = demo_llseek,
.read = demo_read,
.write = demo_write,
.unlocked_ioctl = demo_ioctl,
.mmap = demo_mmap
};
static struct miscdevice demo_dev = {
.minor = MISC_DYNAMIC_MINOR, // Dynamically allocate minor.
.name = "demo_char",
.fops = &demo_fops,
};
static int __init demo_init(void)
{
misc_register(&demo_dev);
return 0;
}
static void __exit demo_exit(void)
{
misc_deregister(&demo_dev);
}
module_init(demo_init);
module_exit(demo_exit);