尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

VitualDisk 驱动

VitualDisk 驱动
📅 发布时间:2026/6/19 19:13:51
VitualDisk 驱动

驱动代码

#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");

相关新闻

  • 2025年智能家居品牌新推荐排行榜白皮书,稳定的智能家居品牌有什么
  • CSPJ2024游记-小LYF的OI之路(1)
  • 2025 年 11 月多功能塑料粉碎机,小型粉碎机,塑料瓶粉碎机厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读!

最新新闻

  • ComfyUI TTP Toolset:3步掌握8K超分辨率图像分块处理技术,普通电脑也能轻松实现AI图像增强
  • LPC3130/3131 ARM9微控制器:多层AHB总线与引脚复用的嵌入式设计精要
  • 2026衡水2026正规漏水检测维修公司精选口碑榜TOP5权威推荐-精准定位检测漏水点-专业防水补漏堵漏维修、卫生间/厨房/屋顶/天沟/地下室/阳台防水漏水检测维修 - 安佳防水
  • 3种智能编排策略重构AI工作流创作效率
  • PPO算法在大语言模型RLHF训练中的工程实践与调参指南
  • 武汉南华光电职业技术学校2026年最新招生简章 - 武汉中职最新信息发布

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号