linux-device-driver - 在 Qemu 上编写用于 DMA 传输的 PCI 驱动程序
问题描述
我正在客户操作系统中的 Qemu 和驱动程序(LKM)上编写 PCI 设备。虽然 Qemu 提供了一个示例 PCI 设备edu(edu.txt和edu.c)及其发行版,但我在编写内核模块以进行 DMA 传输时遇到了麻烦。此处介绍了一个基本驱动程序,但它不支持 DMA。
我正在关注链接和这个的实现。我试图从 IRQ 处理程序将缓冲区传输到 PCI 设备。该设备可以读取数据(pci_dma_read),但我没有得到我应该接收的正确数据。这是进行 DMA 传输的代码段:
static int write_to_HyPerf(void *dev, void* addr, uint32_t size)
{
/* ----------------------------------------------------------------------------
* PCI address 'addr':
* addr -> DMA source address
* 0x40000 -> DMA destination address
* 100 -> DMA transfer count
* 1 -> DMA command register
* while (DMA command register & 1)
*--------------------------------------------------------------------------------
*/
iowrite32((u32 *)dma_handle_to_device, mmio + IO_DMA_SRC);
iowrite32(DMA_START, mmio + IO_DMA_DST);
iowrite32((u32 *)size, mmio + IO_DMA_XCNT);
iowrite32(DMA_CMD | DMA_IRQ, mmio + IO_DMA_CMD);
}
我还使用dma_alloc_coherent设置了相干映射。
vaddr_to_device = dma_alloc_coherent(&(dev->dev), DMA_SIZE, &dma_handle_to_device, GFP_ATOMIC);
完整的代码可在此处获得。我究竟做错了什么?
解决方案
可能是您的驱动程序有问题。
在这种情况下,您可以使用: https ://github.com/cirosantilli/linux-kernel-module-cheat/blob/master/kernel_modules/qemu_edu.c
并且您可以像在此脚本中一样使用 dd 命令从您的设备写入和读取: https ://github.com/cirosantilli/linux-kernel-module-cheat/blob/master/rootfs_overlay/lkmc/qemu_edu.sh
然后,您只需将所需的 dma 值写入 edu.c 代码中的正确地址即可:
case 0x80:
dma_rw(edu, false, &val, &edu->dma.src, false);
break;
case 0x88:
dma_rw(edu, false, &val, &edu->dma.dst, false);
break;
case 0x90:
dma_rw(edu, false, &val, &edu->dma.cnt, false);
break;
case 0x98:
dma_rw(edu, false, &val, &edu->dma.cmd, false);
break;
推荐阅读
- c# - 如何在c#中从没有SPLIT的字符串中获取单词
- java - Mac上有_JAVA_OPTIONS吗?
- python - fromkeys 方法的意外结果
- swift - SwiftUI - 数组中只有一个对象属性为真
- c++ - Qt Quick2 为单例类类型创建 qmlRegisterSingletonType
- python - 使用 pandas 对行进行子集化
- android - 如果 edittext 在 TextInputlayout 内,将 drawableLeft 添加到 EditText 会使提示向右移动。当 proguard 启用时
- python - 用户存在但无法使用 simpleJWT 和 Django Admin 进行身份验证
- python - 计算 df 的平均值,但如果 =>1 的值与该平均值相差 >20%,则平均值设置为 NaN
- c# - 如何为 ASP.NET Core API 设置 OAuth2 不记名令牌?