有時候我們需要寫一些"小的驅動程式",而早期的UNIX/Linux需要註冊major/minor number,即便可能只需要1個minor number,往往卻佔住major number底下的所有minor number,於是在Linux 2.0有了miscellaneous character drivers的誕生,misc driver使用major number 10,然後使用者如果需要這樣的"小驅動程式",便可以指明minor number即可。
使用misc device必須include <linux/miscdevice.h>,裡面包含了許多的官方的minor number,您可以挑選您適合的minor number,裡面也包含了兩個API,misc_register()/misc_deregister()。
一般您只要填好struct miscdevice的內容,再使用misc_register()進行註冊,或者使用misc_deregister()進行移除即可。
struct miscdevice {
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
const char *devnode;
};
minor:就是您要註冊的minor number。
name:device的name。
fops:file operations。
其他的就不用理會了。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
MODULE_LICENSE("GPL");
#define DEV_BUFSIZE 1024
static int dev_open(struct inode*, struct file*);
static int dev_release(struct inode*, struct file*);
static ssize_t dev_read(struct file*, char __user*, size_t, loff_t*);
static ssize_t dev_write(struct file*, const char __user *, size_t, loff_t*);
static void __exit exit_modules(void);
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = dev_open,
.release = dev_release,
.read = dev_read,
.write = dev_write,
};
static struct miscdevice brook_miscdev = {
.minor = 11,
.name = "brook_dev",
.fops = &dev_fops,
};
static int
dev_open(struct inode *inode, struct file *filp)
{
printk("%s():\n", __FUNCTION__);
return 0;
}
static int
dev_release(struct inode *inode, struct file *filp)
{
printk("%s():\n", __FUNCTION__);
return 0;
}
static ssize_t
dev_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
printk("%s():\n", __FUNCTION__);
*pos = 0;
return 0;
}
static ssize_t
dev_write(struct file *filp, const char __user *buf,
size_t count, loff_t *pos)
{
printk("%s():\n", __FUNCTION__);
return count;
}
static int __init init_modules(void)
{
int ret;
ret = misc_register(&brook_miscdev);
if (ret != 0) {
printk("cannot register miscdev on minor=11 (err=%d)\n",ret);
}
return 0;
}
static void __exit exit_modules(void)
{
misc_deregister(&brook_miscdev);
}
module_init(init_modules);
module_exit(exit_modules);