linux特殊设备驱动

一. 内存设备结构体

static const struct memdev {
	const char *name;
	mode_t mode;
	const struct file_operations *fops;
	struct backing_dev_info *dev_info;
} devlist[] = {
	 [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
#ifdef CONFIG_DEVKMEM
	 [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
#endif
	 [3] = { "null", 0666, &null_fops, NULL },
#ifdef CONFIG_DEVPORT
	 [4] = { "port", 0, &port_fops, NULL },
#endif
	 [5] = { "zero", 0666, &zero_fops, &zero_bdi },
	 [7] = { "full", 0666, &full_fops, NULL },
	 [8] = { "random", 0666, &random_fops, NULL },
	 [9] = { "urandom", 0666, &urandom_fops, NULL },
	[11] = { "kmsg", 0, &kmsg_fops, NULL },
#ifdef CONFIG_CRASH_DUMP
	[12] = { "oldmem", 0, &oldmem_fops, NULL },
#endif
};

 

二.初始化

     1.内存设备初始化

static int __init chr_dev_init(void)
{
	int minor;
	int err;
	err = bdi_init(&zero_bdi);
	if (err)
		return err;
	if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))	//注册基于内存的设备,捆绑memory_fops
		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
	mem_class = class_create(THIS_MODULE, "mem");	//创建"/sys/class/mem"
	if (IS_ERR(mem_class))
		return PTR_ERR(mem_class);
	mem_class->devnode = mem_devnode;
	for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
		if (!devlist[minor].name)
			continue;
		device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),NULL, devlist[minor].name);
	}	//创建devlist数组中的设备"/sys/class/mem/xxx"

	return tty_init();
}

     2.memory_fops

static const struct file_operations memory_fops = {
	.open = memory_open,
	.llseek = noop_llseek,
};

      3.memory_open

static int memory_open(struct inode *inode, struct file *filp)
{
	int minor;
	const struct memdev *dev;

	minor = iminor(inode);	//根据节点算出次设备号
	if (minor >= ARRAY_SIZE(devlist))
		return -ENXIO;

	dev = &devlist[minor];	//根据次设备号获取内存设备
	if (!dev->fops)
		return -ENXIO;

	filp->f_op = dev->fops;	//替换操作函数集
	if (dev->dev_info)
		filp->f_mapping->backing_dev_info = dev->dev_info;	//替换memdev->dev_info

	/* Is /dev/mem or /dev/kmem ? */
	if (dev->dev_info == &directly_mappable_cdev_bdi)
		filp->f_mode |= FMODE_UNSIGNED_OFFSET;

	if (dev->fops->open)	//若存在open方法
		return dev->fops->open(inode, filp);		//则调用其open方法

	return 0;
}

三.null

static const struct file_operations null_fops = {
	.llseek		= null_lseek,
	.read		= read_null,
	.write		= write_null,
	.splice_write	= splice_write_null,
};

read_null

static ssize_t read_null(struct file *file, char __user *buf,size_t count, loff_t *ppos)
{
	return 0;
}
 

write_null

static ssize_t write_null(struct file *file, const char __user *buf,size_t count, loff_t *ppos)
{
	return count;
}


所以往/dev/null读写数据都是一去不回的,黑洞一般

其他的特殊设备差不多


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值