硬盘dma读写过程

pci初始化时,遍历pci上的设置,如果BaseClassCode==1,则为大容量存储控制器,包括硬盘控制器、固态硬盘控制器、光盘驱动控制器、RAID控制器等。

BaseAdder4为DMA控制器基地址,包含两个控制器,主控制器,次控制器,每个占8字节。

dma只能使用物理地址,最好开启硬盘状态中断。

具体过程见代码

//主控制器占8位,次控制器占用8字节,意义相同
#define DMA_COMMAND_REG     0            // dma主控命令寄存器的偏移 1字节,第1、3字节保留,没有用途
//第3位置为0时,表示读扇区,DMA传送方向为从IDE设备到内存;为1时,表示写扇区,方向为从内存到IDE设备。
//第0位置为0时,表示停止DMA传输;为1时表示启动DMA传输
//
#define DMA_STATUS_REG      2            // dma主控状态寄存器的偏移
//第0位置为1时,正在进行DMA传输;第1位置为1时,表示DMA传送出现了一个错误;
//第2位置为1时,IDE设备已产生一个中断请求(DMA传输已完成);
//第5位置为1时,表示设备0(主盘)能够执行DMA操作;
//第6位置为1时,表示设备1(从盘)能够执行DMA操作;
//第7位置为1时,表示设备0和设备1不能同时执行DMA操作。#define DMA_PRD_ADDR_REG     4            // 物理区域描述符指针寄存器的偏移
//物理区域描述符表,连续排列,每个项占8字节,typedef struct {DWORD addr; //前4位为缓存区物理地址,WORD len; 	//当前块长度,WORD EOT; 	//只使用最高位
}__attribute__((packed)) PRD_ADD;
#define pio_base_addr1      0x01F0        // 主ATA设备控制块寄存器基地址
#define pio_base_addr2      0x03F0        // 主ATA命令命令块寄存器基地址
void dma_read_sectors(DWORD bmcr_base_addr, DWORD lbaSector, PVOID buf,WORD len) {PRD_ADD prdBufAddr;             //物理区域描述符地址//	bufferaddr               // 内存缓冲区地址// Start/Stop=0, 停止以前的DMA传输WritePortByte(bmcr_base_addr + DMA_COMMAND_REG, 0x00);// 清除主控状态寄存器的Interrupt和Error位WritePortByte(bmcr_base_addr + DMA_STATUS_REG, 6);//物理区域描述符表,连续排列	EOT=1 表示为最后一个prdBufAddr.addr = (DWORD) buf;	//这里应为物理地址prdBufAddr.len= len; //len应小于或等于0x200prdBufAddr.EOT = 0x8000; //最高位为EOT// 物理区域描述符的地址写入PRDTRWritePortDword(bmcr_base_addr + DMA_PRD_ADDR_REG,MiGetPhysics(&prdBufAddr));// 主控命令寄存器的R/W=1, 表示写入内存(读取硬盘)WritePortByte(bmcr_base_addr + DMA_COMMAND_REG, 8);// 等待硬盘BSY=0和DRQ=0//busy_wait();// 设置设备/磁头寄存器的DEV=0WritePortByte( pio_base_addr1 + 6, 00);// 等待硬盘BSY=0和DRQ=0//busy_wait();// 设备控制寄存器的nIEN=0, 允许中断WritePortByte( pio_base_addr2 + 6, 00);// 设置ATA寄存器WritePortByte( pio_base_addr1 + 1, 00);	// =00WritePortByte( pio_base_addr1 + 2, 1);	// numSect扇区数量WritePortByte( pio_base_addr1 + 3, lbaSector >> 0);	// LBA第7~0位WritePortByte( pio_base_addr1 + 4, lbaSector >> 8);	// LBA第15~8位WritePortByte( pio_base_addr1 + 5, lbaSector >> 16);	// LBA第23~16位// 设备/磁头寄存器:LBA=1, DEV=0, LBA第27~24位WritePortByte( pio_base_addr1 + 6, 0x40 | (lbaSector >> 24));// 设置ATA命令寄存器WritePortByte( pio_base_addr1 + 7, 0x0C8);	// 0C8h=Read DMA// 读取主控命令寄存器和主控状态寄存器ReadPortByte(bmcr_base_addr + DMA_COMMAND_REG);ReadPortByte(bmcr_base_addr + DMA_STATUS_REG);// 主控命令寄存器的R/W=1,Start/Stop=1, 启动DMA传输WritePortByte(bmcr_base_addr + DMA_COMMAND_REG, 9);// 现在开始DMA数据传送// 检查主控状态寄存器, Interrupt=1时,传送结束//mov 	ecx, 4000hnotAsserted: while (!(ReadPortByte(bmcr_base_addr + DMA_STATUS_REG) & 4)) {hlt();};// 清除主控状态寄存器的Interrupt位WritePortByte(bmcr_base_addr + DMA_STATUS_REG, 4);// 读取主控状态寄存器ReadPortByte(bmcr_base_addr + DMA_STATUS_REG);// 主控命令寄存器的Start/Stop=0, 结束DMA传输WritePortByte(bmcr_base_addr + DMA_COMMAND_REG, 00);
}

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

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

相关文章

Python-基于Pygame的小游戏(贪吃蛇)(一)

前言:贪吃蛇是一款经典的电子游戏,最早可以追溯到1976年的街机游戏Blockade。随着诺基亚手机的普及,贪吃蛇游戏在1990年代变得广为人知。它是一款休闲益智类游戏,适合所有年龄段的玩家,其最初为单机模式,后来随着技术发…

使用k6进行MongoDB负载测试

1.安装环境 安装xk6-mongo扩展 ./xk6 build --with github.com/itsparser/xk6-mongo 2.安装MongoDB 参考Docker安装MongoDB服务-CSDN博客 连接成功后新建test数据库和sample集合 3.编写脚本 test_mongo.js import xk6_mongo from k6/x/mongo;const client xk6_mongo.new…

solon 集成 activemq-client (sdk)

原始状态的 activemq-client sdk 集成非常方便&#xff0c;也更适合定制。就是有些同学&#xff0c;可能对原始接口会比较陌生&#xff0c;会希望有个具体的示例。 <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-client&l…

2024 年最新前端ES-Module模块化、webpack打包工具详细教程(更新中)

模块化概述 什么是模块&#xff1f;模块是一个封装了特定功能的代码块&#xff0c;可以独立开发、测试和维护。模块通过导出&#xff08;export&#xff09;和导入&#xff08;import&#xff09;与其他模块通信&#xff0c;保持内部细节的封装。 前端 JavaScript 模块化是指…

uni-app商品搜索页面

目录 一:功能概述 二:功能实现 一:功能概述 商品搜索页面,可以根据商品品牌,商品分类,商品价格等信息实现商品搜索和列表展示。 二:功能实现 1:商品搜索数据 <view class="search-map padding-main bg-base"> <view class…

最小堆及添加元素操作

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 最小堆及添加元素操作 [太阳]选择题 以下代码执行的结果为&#xff1f; import heapq heap [] heapq.heappush(heap, 5) heapq.heappush(heap, 3) heapq.heappush(heap, 2) heapq.…

10. 考勤信息

题目描述 公司用一个字符串来表示员工的出勤信息 absent:缺勤late: 迟到leaveearly: 早退present: 正常上班 现需根据员工出勤信息&#xff0c;判断本次是否能获得出勤奖&#xff0c;能获得出勤奖的条件如下: 缺勤不超过一次&#xff0c;没有连续的迟到/早退:任意连续7次考勤&a…

【计算机网络】期末考试预习复习|中

作业讲解 转发器、网桥、路由器和网关(4-6) 作为中间设备&#xff0c;转发器、网桥、路由器和网关有何区别&#xff1f; (1) 物理层使用的中间设备叫做转发器(repeater)。 (2) 数据链路层使用的中间设备叫做网桥或桥接器(bridge)。 (3) 网络层使用的中间设备叫做路…

前端工程化-Vue脚手架安装

在现代前端开发中&#xff0c;Vue.js已成为一个流行的框架&#xff0c;而Vue CLI&#xff08;脚手架&#xff09;则为开发者提供了一个方便的工具&#xff0c;用于快速创建和管理Vue项目。本文将详细介绍如何安装Vue脚手架&#xff0c;创建新项目以及常见问题的解决方法。 什么…

利用爬虫获取的数据能否用于商业分析?

在数字化时代&#xff0c;数据已成为企业获取竞争优势的关键资源。网络爬虫作为一种数据收集工具&#xff0c;能够从互联网上抓取大量数据&#xff0c;这些数据在商业分析中扮演着重要角色。然而&#xff0c;使用爬虫技术获取的数据是否合法、能否用于商业分析&#xff0c;是许…

罗德与施瓦茨ZN-Z129E网络分析仪校准套件具体参数

罗德与施瓦茨ZN-Z129E网络校准件ZN-Z129E网络分析仪校准套件 1&#xff0c;频率范围从9kHz到4GHz&#xff08;ZNB4&#xff09;,8.5GHz(ZNB8)&#xff0c;20GHz(ZNB20)&#xff0c;40GHz(ZNB40) 2&#xff0c;动态范围宽&#xff0c;高达140 dB 3&#xff0c;扫描时间短达4ms…

如何为IntelliJ IDEA配置JVM参数

在使用IntelliJ IDEA进行Java开发时&#xff0c;合理配置JVM参数对于优化项目性能和资源管理至关重要。IntelliJ IDEA提供了两种方便的方式来设置JVM参数&#xff0c;以确保你的应用程序能够在最佳状态下运行。本文将详细介绍这两种方法&#xff1a;通过工具栏编辑配置和通过服…

unity is running as administrator 管理员权限问题

每次打开工程弹出unity is running as administrator的窗口 unity版本2022.3.34f1&#xff0c;电脑系统是win 11系统解决方法一&#xff1a;解决方法二&#xff1a; unity版本2022.3.34f1&#xff0c;电脑系统是win 11系统 每次打开工程都会出现unity is running as administr…

回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测

回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效…

OneCode:开启高效编程新时代——企业定制出码手册

一、概述 OneCode 的 DSM&#xff08;领域特定建模&#xff09;出码模块是一个强大的工具&#xff0c;它支持多种建模方式&#xff0c;并具有强大的模型转换与集成能力&#xff0c;能够提升开发效率和代码质量&#xff0c;同时方便团队协作与知识传承&#xff0c;还具备方便的仿…

git暂存

给大家分享几个git命令&#xff1a; git stash 暂存工作目录的修改 git stash list 查看暂存列表 git stash apply 恢复暂存内容并保持最近一次暂存记录&#xff0c;如果有多个暂存记录&#xff0c;想恢复指定的暂存记录&#xff0c;可以使用git stash apply stash{}&#xf…

远程控制软件新趋势

随着数字化浪潮的推进&#xff0c;远程控制软件已经成为我们生活中的一部分&#xff0c;它们不仅改变了我们的工作方式&#xff0c;还为日常生活带来了极大的便利。现在&#xff0c;让我们来探讨远程控制软件在数字时代的发展和应用&#xff0c;以及它们如何引领新的办公趋势。…

C++如何处理对象的状态变化?

概念 处理对象的状态变化是软件开发中一个重要的课题&#xff0c;尤其是在设计过程中&#xff0c;如何有效管理对象的状态变化对于软件的可维护性、可扩展性和整体设计都至关重要。 状态模式 状态模式通过将状态封装为对象&#xff0c;允许对象在内部状态改变时改变其行为。…

在Spring中application 的配置属性(详细)

application 的配置属性。 这些属性是否生效取决于对应的组件是否声明为 Spring 应用程序上下文里的 Bean &#xff08;基本是自动配置 的&#xff09;&#xff0c;为一个不生效的组件设置属性是没有用的。 multipart multipart.enabled 开启上传支持&#xff08;默认&a…

C语言编程1.27汉诺塔

题目描述 给定一个由n个圆盘组成的塔&#xff0c;这些圆盘按照大小递减的方式套在第一根桩柱上。现要将整个塔移动到另一根桩柱上&#xff0c;每次只能移动一个圆盘&#xff0c;且较大的圆盘在移动过程中不能放置在较小的圆盘上面。 输入格式 输入由四行&#xff1a; 第一行…