Linux字符设备就是一个虚拟的文件,当你读写这个文件的时候感觉就像一个真实的文件。为此,需要实现文件的读写方法。
创建misc设备。misc是Linux中的杂项设备,主设备号是10,次设备号会自动分配,这样编程会简单不少。比较重要的地方就是misc_register,他会注册一个misc设备。
static int __init simple_char_init(void)
{
// register a misc
int ret = misc_register(&my_misc_device);
if(ret){
printk("failed to register misc device\n");
return ret;
}
my_device = my_misc_device.this_device;
printk("succeeded register char device: %s\n", DEV_NAME);
// alloc a memory space
buffer = kmalloc(4096, GFP_KERNEL);
memset(buffer, 0, 4096);
return 0;
}
销毁的时候需要dereigster
static void __exit simple_char_exit(void)
{
printk("removing device\n");
misc_deregister(&my_misc_device);
kfree(buffer);
}
然后的话需要实现open, release, read和write的函数
static int mydev_open(struct inode *inode, struct file *file)
{
int major = MAJOR(inode->i_rdev);
int minor = MINOR(inode->i_rdev);
printk("%s: major=%d, minor=%d\n", __func__, major, minor);
return 0;
}
static int mydev_release(struct inode *inode, struct file *file)
{
return 0;
}
static ssize_t
mydev_read(struct file*file, char __user *buf, size_t lbuf, loff_t *ppos)
{
int max_free = MAX_DEVICE_BUFFER_SIZE - *ppos;
int need_read = max_free > lbuf ? lbuf : max_free;
int ret = copy_to_user(buf, buffer + *ppos, need_read);
int actual_read = need_read - ret;
*ppos += actual_read;
return actual_read;
}
static ssize_t
mydev_write(struct file* file, const char __user *buf, size_t count, loff_t *f_pos)
{
int max_free = MAX_DEVICE_BUFFER_SIZE - *f_pos;
int need_write = max_free > count ? count : max_free;
int ret = copy_from_user(buffer + *f_pos, buf, need_write);
int actual_write = need_write - ret;
*f_pos += actual_write;
return actual_write;
}
static const struct file_operations mydev_fops = {
.owner = THIS_MODULE,
.open = mydev_open,
.release = mydev_release,
.read = mydev_read,
.write = mydev_write,
.mmap = mydev_mmap,
};
static struct miscdevice my_misc_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEV_NAME,
.fops = &mydev_fops
};
简单测试可以用echo和cat。也可以编写测试程序来测试。