實現/dev/null的字符設備驅動

/dev/null是個黑洞設備,它丟棄一切寫入其中的數據,空設備通常被用於丟棄不需要的輸出流。任何寫入該設備數據都會被丟棄掉。從這個裏面讀取數據返回空(也有人認爲是讀該空設備,直接讀到文件尾,那就是返回-1)。將一些不用內容經常發送給這個設備,丟棄不需要的數據。代碼實現如下:

#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_null_open(struct inode *inode, struct file *filp);
static int mydev_null_release(struct inode *inode, struct file* filp);
static ssize_t mydev_null_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos);
static ssize_t mydev_null_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_null_read,
	.write = mydev_null_write,
	.open = mydev_null_open,
	.release = mydev_null_release, 
};

static int mydev_null_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_null_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
{
	return -1;
}

static ssize_t mydev_null_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos)
{
	printk("write success\n");
	return 1;
}

static int mydev_null_release(struct inode *inode, struct file* filp)
{
	-- openNum;
	printk("The device is released!\n");
	return 0;
}

static int __init mydev_null_init(void)
{
	int temp;
	printk(KERN_ALERT "Begin to init Char Device!\n");
	temp = register_chrdev(DEVICE_NUM, "mydev_null", &mydev_file_operations);
	if (temp < 0) {
		printk(KERN_WARNING "mydev_null: register failure\n");
		return -1;
	}else {
		printk("mydev_null: register success!\n");
		dev_num = temp;
		return 0;
	}
}

static void __exit mydev_null_exit(void)
{
	printk(KERN_ALERT "Unloading...\n");
	unregister_chrdev(dev_num, "mydev_null");
	printk("unregister success!\n");
}

MODULE_AUTHOR("Fang Xieyun");
MODULE_LICENSE("GPL");

module_init(mydev_null_init);
module_exit(mydev_null_exit);









發佈了15 篇原創文章 · 獲贊 14 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章