Johannes 《Linux内核模块与设备驱动开发:编写Linux驱动程序》 (9)manual_cdev

视频教程:Lecture 9 - 手动创建字符设备_哔哩哔哩_bilibili

代码:anGitHub - Johannes4Linux/Linux_Driver_Tutorial: My new Tutorial how to get started with Linux Kernel Modules and Linux Drivers. Smtarted in 2024 · GitHub

复制代码
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>

static dev_t dev_nr;
static struct cdev my_cdev;

static ssize_t my_read(struct file *f, char __user *u, size_t l, loff_t *o)
{
	pr_info("hello_cdev - Read is called\n");
	return 0;
}


static struct file_operations fops = {
	.read = my_read
};

static int __init my_init(void)
{
	int status;
#ifdef STATIC_DEVNR
	dev_nr = STATIC_DEVNR;
	status = register_chrdev_region(dev_nr, MINORMASK + 1, "hello_cdev");
#else
	status = alloc_chrdev_region(&dev_nr, 0, MINORMASK + 1, "hello_cdev");
#endif
	if (status) {
		pr_err("hello_cdev - Error reserving the region of device numbers\n");
		return status;
	}

	cdev_init(&my_cdev, &fops);
	my_cdev.owner = THIS_MODULE;

	status = cdev_add(&my_cdev, dev_nr, MINORMASK + 1);
	if (status) {
		pr_err("hello_cdev - Error adding cdev\n");
		goto free_devnr;
	}

	pr_info("hello_cdev - Registered a character device for Major %d starting with Minor %d\n", MAJOR(dev_nr), MINOR(dev_nr));
	return 0;

free_devnr:
	unregister_chrdev_region(dev_nr, MINORMASK + 1);
	return status;
}

static void __exit my_exit(void)
{
	cdev_del(&my_cdev);
	unregister_chrdev_region(dev_nr, MINORMASK + 1);
}

module_init(my_init);
module_exit(my_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Johannes 4Linux");
MODULE_DESCRIPTION("A sample driver for manually registering a character device");

添加了头文件<linux/cdev.h>,

程序中调用的宏 :STATIC_DEVNR ,MINORMASK

手动注册字符设备:

status = register_chrdev_region(dev_nr, MINORMASK + 1, "hello_cdev");

register_chrdev_region 需要配置主/副设备号,这里用的 STATIC_DEVNR ,MINORMASK+1 来注册字符设备 hello_cdev

动态注册字符设备:

status = alloc_chrdev_region(&dev_nr, 0, MINORMASK + 1, "hello_cdev");

不需要手动配置,自动配置字符设备 hello_cdev

创建并添加字符设备:

cdev_init(&my_cdev, &fops);

&my_cdev 指向全局变量里这个指针,fops就将字符设备和读写操作结合起来

全局变量my_cdev 的所有者是这个模块,这样就将hello_cdev 接上了

my_cdev.owner = THIS_MODULE;

这样系统内核就添加字符设备,在 /proc/dev/中可以看到字符设备 hello_cdev,主设备号是dev_nr

status = cdev_add(&my_cdev, dev_nr, MINORMASK + 1);

不过这节系统内核添加hello_cdev这个设备驱动之后还是要mknod 创建字符设备 mknod /dev/hello0 c 236 0

相关推荐
whyutianict_vv17 分钟前
云计算 HCIE 认证体系解析:HCIA/HCIP/HCIE 三级科目与知识边界
linux·运维·云计算
0+1117 小时前
Linux --从 poll 到 epoll多路转接
linux·服务器·1024程序员节
青瓦梦滋7 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
桌面运维家8 小时前
旧电脑跑不动课程软件,VDI云桌面怎样接着用?
运维·服务器·虚拟化·pve·vdi·云桌面
zhang133830890758 小时前
传统机械三杯式风速传感器易磨损冻堵?CG-88金属超声波风速风向传感器给出免运维方案
运维·服务器·网络·人工智能·自动化
知已难寻8 小时前
第 2 篇 · 云的地基:服务器、存储、网络三大基础设施
运维·服务器·网络·云原生·云计算·负载均衡·1024程序员节
2601_9498477510 小时前
bcrypt.js 跨端三方库仓颉适配全流程
linux·运维·ubuntu
m0_6399069410 小时前
Linux 操作系统入门:目录结构、服务排查常用命令、Shell 脚本基础
linux·运维·后端
今天重构了吗11 小时前
Linux 上 rm -rf 删错了能找回吗
运维·服务器
KaiwuDB11 小时前
KaiwuDB 分布式集群扩缩容,从原理到完整操作踩坑总结
运维·数据库·分布式