VitualDisk 驱动

news/2025/11/4 15:11:25/文章来源:https://www.cnblogs.com/caoshikui/p/19189540

驱动代码

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define VIRTUALDISK_SIZE	0X2000	// 全局内存最大8K字节
#define MEM_CLEAR       0x1		// 全局内存清零
#define PORT1_SET       0x2		// 将 port1 端口清零
#define PORT2_SET       0x3		// 将 port1 端口清零
#define VIRTUALDISK_MAJOR   200		// 预设的 VirtualDisk 的主设备号为 200struct VirtualDisk{struct cdev cdev;			// cdev 结构体unsigned char mem[VIRTUALDISK_SIZE];	// 全局内存8Kint port1;				// 两个不同类型的端口long port2;long count;				// 记录设备目前被多少设备打开
}static int VirtualDisk_major = VIRTUALDISK_MAJOR;
static struct VirtualDisk *Virtualdisk_devp;/*设备驱动模块加载函数*/
int VirtualDisk_init(void){int result;dev_t devno = MKDEV(VirtualDisk_major, 0); // 构建设备号/*申请设备号*/if (VirtualDisk_major) {		// 如果不为0,则静态申请result = register_chrdev_region(devno, 1, "VirtualDisk");} else {result = alloc_chrdev_region(&devno, 0, 1, "VirtualDisk");	// 动态申请设备号VirtualDisk_major = MAJOR(devno); //从申请设备号中得到主设备号}if (result < 0)return result;/*动态申请设备结构体的内存*/Virtualdisk_devp =kmalloc(sizeof(struct VirtualDisk), GFP_KERNEL);if (!Virtualdisk_devp) {		// 申请失败result = -ENOMEM;goto fail_kmalloc;}memset(Virtualdisk_devp, 0, sizeof(struct VirtualDisk));	//将内存清零/*初始化并且添加 cdev 结构体*/VirtualDisk_setup_cdev(Virtualdisk_devp, 0);return 0;fail_kmalloc:unregister_chrdev_region(devno, 1);return result;
}/*初始化并注册 cdev*/
static void VirtualDisk_setup_cdev(struct VirtualDisk *dev, int minor) {int err;devno = MKDEV(VirtualDisk_major, minor);	// 构造设备号cdev_init(&dev->cdev, &VirtualDisk_fops);	// 初始化 cdev 设备dev->cdev.owner = THIS_MODULE;			// 使驱动属于该模块dev->cdev.ops = &VirtualDisk_fops;		// cdev 连接 file_operations 指针err = cdev_add(&dev->dev, devno, 1);	// 将 cdev 注册到系统if(err)printk(KERN_NOTICE "Error in cdev_add()\n");
}/*文件操作结构体*/
static struct file_operations VirtualDisk_fops = 
{.owner = THIS_MODULE,.llseek = VirtualDisk_llseek,		// 定位偏移量函数.read = VirtualDisk_read,			// 读设备函数.write = VirtualDisk_write,			// 写设备函数.ioctl = VirtualDisk_ioctl,			// 控制函数.open = VirtualDisk_open,			// 打开设备函数.release = VirtualDisk_release,		// 释放设备函数
};/*文件打开函数*/
static int VirtualDisk_open(struct inode *inode, struct file *filp)
{/*将设备结构体指针赋值给文件私有数据指针*/filp->private_data = Virtualdisk_devp;Struct VirtualDisk *devp = filp->private_data;	// 获得设备结构体指针devp->count++;					// 增加设备打开次数return 0;
}/*文件释放函数*/
int VirtualDisk_release(struct inode *inode, struct file *filp) {struct VirtualDisk *devp = filp->private_data;devp->count--;return 0;
}/*读函数*/
static ssize_t VirtualDisk_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) {unsigned long p = *ppos;		// 记录文件指针偏移位置unsigned int count = size;		// 记录需要读取的字节数int ret = 0;				// 返回值struct VirtualDisk *devp = filp->private_data; // 获得设备结构体指针/*分析和获取有效的读长度*/if (p >= VIRTUALDISK_SIZE) {		// 要读取的偏移大于设备的内存空间return count ? -ENXIO :0;	// 读取地址错误}if(count > VIRTUALDISK_SIZE - p){	// 要读取的字节大于设备的内存空间count = VIRTUALDISK_SIZE - p;	// 将要读取的字节数设为剩余的字节数}/*内核空间 --> 用户空间交换数据*/if(copy_to_user(buf, (void *)(devp->mem + p), count)){ret = -EFAULT;}else{*loff += count;ret = count;//printk("read %x\r\n",count);}return ret;
}/*写函数*/
static ssize_t VirtualDisk_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos){unsigned long p = *ppos;						// 记录文件指针偏移位置int ret = 0;									// 返回值unsigned int count = size;						// 记录需要写入的字节数struct VirtualDisk *devp = filp->private_data;	// 获得设备结构体指针/*分析和获取有效的写长度*/if (p >= VIRTUALDISK_SIZE)						// 要写入的偏移大于设备的内存空间return count ? - ENXIO : 0;					// 写入地址错误}if (count > VIRTUALDIS_SIZE - p) {				// 要写入的字节大于设备的内存空间count = VIRTUALDIS_SIZE - p;				// 将要写入的字节数设为剩余的字节数}/*用户空间 --> 内核空间*/if (copy_from_user(devp->mem + p, buf, count)) {ret = - EFAULT;} else {*ppos += count;								/// 增加偏移位置ret = count;								// 返回实际的写入字节数printk(KERN_INFO "written %d bytes(s) from %d\n", count, p);}return ret;
}/*seek 文件定位函数*/
static loff_t VirtualDisk_llseek(struct file *filp, loff_t offset, int orig) {loff_t ret = 0;											// 返回的位置偏移switch (orig) {case SEEK_SET:										// 相对文件开始位置偏移if (offset < 0) {								// offset 不合法ret = - EINVAL;								// 无效的指针break;}if ((unsigned int)offset > VIRTUALDISK_SIZE) {	// 偏移大于设备内存ret = - EINVAL;								// 无效的指针break;}filp->f_pos = (unsigned int)offset;				// 更新文件指针位置ret = filp->f_pos;								// 返回的位置偏移break;case SEEK_CUR:										// 相对文件当前位置偏移if ((filp->f_pos + offset) > VIRTUALDISK_SIZE) {// 偏移大于设备内存ret = -EINVAL;								// 无效的指针break;}if ((filp->f_pos + offset) < 0) {				// 指针不合法ret = -EINVAL;								// 无效的指针break;}filp->f_pos += offset;							// 更新文件指针位置ret = filp->f_pos;								// 返回的位置偏移break;default:ret = - EINVAL;									// 无效的指针break;}return ret;
}/*ioctl() 设备控制函数*/
static int VirtualDisk_ioctl(struct inode *inodep, struct file * filp, unsigned int cmd, unsigned long arg) {struct VirtualDisk *devp = filp->private_data;				// 获得设备结构体指针switch (cmd) {case MEM_CLEAR:memset(devp->mem, 0, VIRTUALDISK_SIZE);				// 设备内存清零printk(KERN_INFO "VirtualDisk is set to zero\n");break;case PORT1_SET:											// 端口1置为0devp->port1 = 0;break;case PORT2_SET:											// 端口2置为0devp->port2 = 0;break;default:return - EINVAL;}return 0;
}/*模块卸载函数*/
void VirtualDisk_exit(void){cdev_del(&Virtualdisk_devp->cdev);	// 注销 cdevkfree(Virtualdisk_devp);	// 释放设备结构体内存unregister_chrdev_region(MEDEV(VirtualDisk_major, 0), 1);	// 释放设备号
}module_init(VirtualDisk_init);
module_exit(VirtualDisk_exit);
MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/955729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年智能家居品牌新推荐排行榜白皮书,稳定的智能家居品牌有什么

2025年智能家居行业进入体验为王的深度竞争阶段,用户对设备的稳定感需求愈发凸显——既要求日常使用中零卡顿、少故障的基础体验,也期待售后响应及时、长期耐用的品质保障。然而当前市场中,部分品牌存在三大核心痛点…

CSPJ2024游记-小LYF的OI之路(1)

去年的懒得写了 省流:初赛92.5 复赛100+100+100+0=300 1=

2025 年 11 月多功能塑料粉碎机,小型粉碎机,塑料瓶粉碎机厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读!

引言 在塑料加工与回收产业持续发展的背景下,多功能塑料粉碎机、小型粉碎机、塑料瓶粉碎机作为核心处理设备,其品质直接关系到企业生产效率与资源回收效益。为帮助行业筛选优质设备供应商,本次测评联合行业协会,依…

2025 年 11 月强力塑料粉碎机,工业塑料粉碎机,多功能塑料粉碎机厂家最新推荐,实力品牌深度解析采购无忧之选!

引言 当前塑料加工与回收领域对强力塑料粉碎机、工业塑料粉碎机、多功能塑料粉碎机的需求持续攀升,设备品质直接关系到生产效率与资源利用率。为帮助企业精准筛选优质供应商,行业协会联合专业测评机构开展专项测评,…

二、基于直接策略搜索的强化学习方法详细解释

直接策略搜索(Direct Policy Search)是强化学习的三大核心分支之一,与“基于值函数的方法”最大区别在于:不通过价值函数间接推导策略,而是直接将策略参数化,通过优化参数最大化长期累积奖励。其核心逻辑是“定义…

2025年智能天窗十大品牌推荐,前景智能天窗操作方便吗

在建筑智能化浪潮下,智能天窗已成为提升空间舒适度与节能效率的关键产品。面对市场上功能各异的智能天窗品牌,消费者往往困惑于前景智能天窗操作方便吗、前景智能天窗智能控制灵敏吗、前景智能天窗透光性如何等核心问…

DeepCode:把论文和想法变成代码的 AI 工具

DeepCode 是香港大学开源的 AI 编码工具,通过多智能体协作实现论文转代码、需求转网站、描述转后端三大功能。采用 MIT 协议,已获 7900+ 星标。适合科研人员、独立开发者和技术学习者使用,能有效提升开发效率。看论…

2025年哈尔滨家装行业口碑榜:为尚装饰的安全保障如何

在哈尔滨装修市场套路多、水太深的痛点下,业主挑选靠谱家装公司时,往往围绕为尚装饰的安全保障如何、市场口碑如何、性价比怎么样这三大核心疑问展开。2025年,我们结合业主真实评价、工程质量抽检数据与服务履约率,…

从零开始学Flink:事件驱动

本文系统讲解 Apache Flink 的事件驱动编程模型,涵盖 ProcessFunction、定时器与状态、事件时间与 Watermark、与窗口的对比以及最佳实践。在实时计算领域,很多业务逻辑天然适合“事件驱动”模式:当事件到达时触发处…

Combo-box Control - ComboExo example

Combo-box Control - ComboExo exampleCreate a new ComboExo using VS2013MFC Application Wizard design dialog eventComboExo example - visualc The original example was written using VC6.0; now we will rewr…

吴恩达深度学习课程二: 改善深层神经网络 第一周:深度学习的实践(六)梯度现象和梯度检验

此分类用于记录吴恩达深度学习课程的学习笔记。 课程相关信息链接如下:原课程视频链接:[双语字幕]吴恩达深度学习deeplearning.ai github课程资料,含课件与笔记:吴恩达深度学习教学资料 课程配套练习(中英)与答案…

终端里的 AI 编程助手:OpenCode 使用指南

OpenCode 是开源的终端 AI 编码助手,支持 Claude、GPT-4 等模型,可在命令行完成代码编写、Bug 修复、项目重构。提供原生终端界面和上下文感知能力,适合全栈开发者和终端用户使用。写代码时遇到过这种情况吗? 想问…

P3209 [HNOI2010] 平面图判定

之前写 \(O(n^2)\) 图省事,结果考试考了单 \(\log\),把自己给坑害了(又不想写代码)。 首先发现这个过程本质上在干什么,钦定一些区间不能相同列车,那么可以 2-SAT,也可以二分图染色,这里选择二分图染色好做些。…

Tita项目管理:中小型企业的最佳选择

在中小企业探寻合适项目管理工具的征程中,Tita项目管理以其独特优势脱颖而出,为企业项目全流程管理难题提供了优质解法。 契合多样需求,精准适配项目类型与规模 中小企业的项目或简单灵活,或复杂多元,Tita皆能应对…

2025年卷绕铁心定制厂家权威推荐榜单:卷铁心/开口卷铁芯/卷铁芯源头厂家精选

在电力设备与电子元器件能效要求日益提升的今天,一款高精度的卷绕铁心已成为决定变压器性能与效率的核心部件。 卷绕铁心作为变压器、互感器等电磁元件的核心导磁部件,其材料性能与加工精度直接影响着设备的能效与稳…

2025年柔性门制造商权威推荐榜单:柔性堆积门/柔性提升门/工业柔性门源头厂家精选

随着工业建筑标准升级和物流效率需求提升,柔性门作为关键工业设施组成部分,市场规模持续扩大。行业数据显示,2024年我国工业门类产品年产值突破120亿元,其中柔性门类产品年均增长率达15%,在冷链物流、洁净车间等应…

WPF根本布局容器与控件

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

强化学习基础概括

强化学习基础知识(含公式与详细解释) 强化学习(Reinforcement Learning, RL)的核心是“智能体(Agent)在与环境(Environment)的交互中,通过试错学习最优策略(Policy),以最大化长期累积奖励(Reward)”。以…

uni-app x开发商城系统,资讯详情页面数据渲染

一、概述 上一篇文章,已经实现了资讯列表跳转详情并传递id 接下来实现,资讯详情页面数据渲染 效果如下:二、资讯详情页面结构 修改 pages/news/news-detail文件,固定一行数据<template><view><!-- …

2025 成都律师咨询最新推荐榜权威发布:聚焦刑事辩护与民商事领域,资深团队与新锐品牌全景解析

引言 随着法律服务需求的持续增长,市场上服务质量参差不齐的问题日益凸显,部分机构专业能力不足、流程透明度低,导致当事人权益难以得到充分保障。为破解选择难题,行业协会联合第三方评估机构开展专项测评,形成最…