字符设备节点(二)-手动创建字符设备节点文件

通过字符设备节点一,知道了如何创建一个最简单的内核模块,这章展示了怎么去真正写一个字符设备节点,手动创建字符设备文件

在Linux内核中,使用cdev结构体描述一个字符设备,cdev结构体如下:

struct cdev{
		struct kobject kobj;				内嵌的kobject对象
		struct moudle *owener;				所属模块
		const struct file_operations * ops;	操作方法结构体
		struct list_head list;				与cdev对应的字符设备文件inode->i_devices的链表头
		dev_t dev;							起始设备编号
		unsigned int count;					连续注册的次设备编号个数
	};

file_operations定义了字符设备驱动提供给虚拟文件系统的接口函数。Linux内核提供一些函数用于操作cdev结构体:

cdev_init()初始化cdev结构体,并将file_operations结构体放入到cdev->fops里
	void cdev_init(struct cdev *cdev,const struct file_operations *fops)
		*cdev:cdev结构体
		*fops:函数操作集
cdev_add()添加cdev到内核,让内核能把它管理起来,将cdev结构体添加到系统中,并将dev(注册好的设备编号)
放入cdev->dev里,count(次设备编号个数)放入cdev->cont里
	int cdev_add(struct cdev *cdev,dev_t dev,unsigned count)
		*cdev:cdev结构体
		*dev:注册好的设备编号
		*count:连续注册的次设备编号个数
		*当返回值小于0,表示添加失败

dev_tc成员定义了设备号,为32位,12位为主设备号,20位为次设备号。使用下列宏可以从dev_t中得到主次设备号

major = MAJOR(dev_t dev);
minor = MINOR(dev_t dev);

已知主次设备号,得到设备号

dev_t dev = MKDEV(major,minor);

设备号注册分为静态注册和动态注册,当已经已知设备号时,使用静态注册register_chrdev_region(),当如果设备号已经被其他驱动注册,在挂载时会报错。动态注册,自己设定一个次设备号,可以动态生成一个设备号,主设备号由MAJOR(dev_t dev)可得。

int  register_chardev_regsion(dev_t from,unsigned count,const char *name);
		*from:注册的制定其实设备编号
		*count:连续注册的次设备编号个数
		*name:字符设备编号
		*returnvalue:
		*	当返回值小于0,表示注册失败
int  alloc_chardev_regsion(dev_t *dev,unsigned baseminor,unsigned count,const char *name);
		*(*dev):存放起始设备编号的指针,当注册成功,*dev就会等于分配到的起始设备编号,
		*baseminor:次设备号基地址,也就是起始次设备号
		*count:连续注册的次设备编号个数
		*name:字符设备编号
		*returnvalue:
		*当返回值小于0,表示注册失败

当取消挂载后,我们需要释放掉我们的设备号unregister_chardev_region()和cdev结构体cdev_del()

void unregister_chardev_regsion(dev_t from,unsigned count);
	*from:注册的制定其实设备编号
	*count:连续注册的次设备编号个数
void cdev_del(struct cdev *p)
	*cdev:cdev结构体
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>  
#include <linux/cdev.h> 

#define CHARDEVICE_NUM_COUNT 1

dev_t devno = 0;//设备号
dev_t devno_major = 0;//主设备号
dev_t devno_minor = 0;//次设备号


struct cdev chardevice_cdev;

struct file_operations * chardevice_fops = {
	.owner = THIS_MODULE,
};

static int __init chardevice_init(void)
{
	int ret;
	if(devno){
		devno = MKDEV(devno_major,devno_minor);
		ret = register_chrdev_region(devno,CHARDEVICE_NUM_COUNT,"chardevice01");
	}eles{
		ret = alloc_chrdev_region(&devno,devno_minor,CHARDEVICE_NUM_COUNT,"chardevice01");
	}
	
	if(ret<0){
		printk(KERN_ALERT"fialed to register_chrdev\n");
		goto failure_register_chardev;
	}
	
	cdev_init(&chardevice_cdev,&chardevice_fops);
	
	
	ret = cdev_add(&chardevice_cdev,devno,CHARDEVICE_NUM_COUNT);
	
	if(ret<0){
		printk(KERN_ALERT"fialed to cdev_init\n");
		goto failure_cdev_init;
	}
	
	return 0;
failure_cdev_init:
	unregister_chardev_region(devno,CHARDEVICE_NUM_COUNT);
failure_register_chardev:
	return ret;
}

static void __exit chardevice_exit(void)
{
	cdev_del(&chardevice_cdev);
	unregister_chardev_region(devno,CHARDEVICE_NUM_COUNT);
}

module_init(chardevice_init);
module_exit(chardevice_exit);
MODULE_LICENSE("GPL v2");

编译成功后,通过insmod/modprobe挂载成功后,手动创建字符设备文件

手动创建节点()

1)查看字符设备字节是否创建成功

cat /proc/devices

如果成功 注册成功,你会看到创建的字符设备结点的名字 和 主设备号

Character devices:
238 chardevices
...

然后使用mknod命令创建一个字符设备文件,b代表块设备,c代表字符设备

mknod Name (b|c) Major Minnor
eg  mknod /dev/chardevice c 238 0

查看设备结点是否创建创建成功

ls -l /dev
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值