在類UNIX 操作系統中, /dev/zero 是一個特殊的文件,當你讀它的時候,它會提供無限的空字符(NULL, ASCII NUL, 0x00),即獲取的是一串二進制0。其中的一個典型用法是用它提供的字符流來覆蓋信息,另一個常見用法是產生一個特定大小的空白文件。具體驅動實現如下
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/uaccess.h>
#ifdef CONFIG_MODVERSIONS
#define MODVERSIONS
#include <linux/version.h>
#endif
#define DEVICE_NUM 0
static int dev_num = 0;
static int openNum = 0;
static int mydev_zero_open(struct inode *inode, struct file *filp);
static int mydev_zero_release(struct inode *inode, struct file* filp);
static ssize_t mydev_zero_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos);
static ssize_t mydev_zero_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos);
static const struct file_operations mydev_file_operations = {
.owner = THIS_MODULE,
.read = mydev_zero_read,
.write = mydev_zero_write,
.open = mydev_zero_open,
.release = mydev_zero_release,
};
static int mydev_zero_open(struct inode *inode, struct file *filp)
{
printk("\nMajor device number is %d, and the minor device number is %d\n", MAJOR(inode->i_rdev), MINOR(inode->i_rdev));
if (openNum == 0) {
++ openNum;
return 0;
}else {
printk(KERN_ALERT "Another process open the char device.\n");
return -1;
}
}
static ssize_t mydev_zero_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
{
int i=0;
while(i<count){
buf[i++] = 0;
}
return count;
}
static ssize_t mydev_zero_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos)
{
printk("write success\n");
return 1;
}
static int mydev_zero_release(struct inode *inode, struct file* filp)
{
-- openNum;
printk("The device is released!\n");
return 0;
}
static int __init mydev_zero_init(void)
{
int temp;
printk(KERN_ALERT "Begin to init Char Device!\n");
temp = register_chrdev(DEVICE_NUM, "mydev_zero", &mydev_file_operations);
if (temp < 0) {
printk(KERN_WARNING "mydev_zero: register failure\n");
return -1;
}else {
printk("mydev_zero: register success!\n");
dev_num = temp;
return 0;
}
}
static void __exit mydev_zero_exit(void)
{
printk(KERN_ALERT "Unloading...\n");
unregister_chrdev(dev_num, "mydev_zero");
printk("unregister success!\n");
}
MODULE_AUTHOR("Fang Xieyun");
MODULE_LICENSE("GPL");
module_init(mydev_zero_init);
module_exit(mydev_zero_exit);