- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
假设我有一些物理地址(这是我的 DMA 源外设的总线位置):
phys_addr = 0xffff0000;
我这样做:
virt_addr = ioremap(phys_addr, PAGE_SIZE);
在这样做之后,我不再直接访问 phys_addr
(在我的例子中,我没有访问权限,因为我正在编写的驱动程序只通过了 virt_addr
) .
我第一次失败的尝试:
wrong_phys_addr = virt_to_dma(dev,virt_addr);
顺便说一句,我不知道为什么设备 dev
在这个查找中是相关的......
这当然是行不通的,因为 virt_addr
不是直接映射的内核内存。 DMA-API似乎暗示所有类似 virt_to_bus
的翻译都已弃用,每个人都应该使用 dma_map_single
等来获取 DMA 总线地址。所以我接下来尝试了这个:
wrong_phys_addr = dma_map_single(dev, virt_addr, size, DMA_FROM_DEVICE);
同样,这仍然不起作用。当然,如果我直接使用 0xffff0000
作为 device_prep_dma_memcpy
的源 DMA 地址,一切都很好——但我还是不能这样做,因为我无法直接访问它。我能想到的获得它的唯一可能方法是遍历内核的页表……我真的不想手动执行此操作。有没有更好的办法?
更新
struct page *kmap_to_page(void * vaddr)
看起来很有前途。我不确定从 ioremap 返回的虚拟地址是否适用于此。另一种可能是
struct page* vmalloc_to_page(void* vmalloc_addr)
我需要进一步调查。
最佳答案
看起来 vmalloc_to_page
正是我要找的。如果我这样做:
phys_addr = page_to_phys(vmalloc_to_page(virt_addr)))
这会产生,phys_addr == 0xffff0000
。
按照 CL. 的建议,我还尝试执行以下所有操作:
wrong_phy_addr1 = dma_map_single(dev, 0xffff0000, size, DMA_FROM_DEVICE);
wrong_phy_addr2 = dma_map_single(dev, virt_addr, size, DMA_FROM_DEVICE);
correct_phy_addr = phys_to_dma(dev, 0xffff0000);
运行后我得到:
wrong_phy_addr1 == 7fff0000
wrong_phy_addr2 == 4091e000
correct_phy_addr == ffff0000
因此,看起来 phys_to_dma()
在这里胜出。使用此方法比使用原始物理地址更可取,因为(如 CL. 建议的那样)物理地址不一定是 DMA 地址——在我的板上它们恰好是相同的。
总而言之,这是我最初问题的答案:
dma_addr = phys_to_dma(dev, page_to_phys(vmalloc_to_page(virt_addr));
话虽这么说,但如果 phys_addr (0xffff0000) 对我的驱动程序可用,则这种额外的查找成本很高,可以避免——我会考虑更改接口(interface)。
在接受我自己的答案之前,我会给其他人一些时间来提供他们自己的(更好的?)答案。
关于c - Linux:如何确定与 ioremap 返回的内容对应的 DMA 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28597417/
我正在开发一个 Linux 内核驱动程序,它为用户空间提供一块物理内存。我有驱动程序的工作版本,但目前速度很慢。所以,我退回了几步,尝试制作一个小巧、简单的驱动程序来重现问题。 我在启动时使用内核参数
我有一个 ARM 目标。 我需要读出一个物理地址。该地址是并行 NOR 闪存中的一个位置。ROM直接在地址总线上。 如果我创建一个模块: if ((rmap = ioremap(ROM_BASE
我正在尝试为 Raspberry PI 创建自定义 UART 驱动程序。我尝试重新映射 MMIO。但是ioremap总是返回NULL。 #define UART_REG_BASE_ADDR 0x7E
在 Linux 内核中,为什么不建议取消引用通过使用 ioremap 映射 I/O 物理地址获得的内核线性地址?为什么要使用 readl/writel 等函数取消引用那些映射的线性地址? 最佳答案 某
我正在尝试访问 Linux 中 am335x 处理器上的给定内存区域。这个想法是首先指定物理地址,然后使用 ioremap 访问所述地址。我已经在谷歌上搜索这个问题一段时间了,但似乎找不到任何好的解决
有什么方法可以对 ioremap 返回的虚拟地址进行 DMA 最佳答案 仅当系统有一个 IOMMU ,一个仅用于 I/O 的内存管理单元(这并不常见)。 由于驱动程序提供了物理内存地址来执行 iore
Ioremap 是在内核模式下完成的。ioremap 是否在页表中创建条目 ioremap的调用还是访问地址的时候? 最佳答案 对于ioremap,页表是立即更新的。由于该函数旨在将物理“I/O”地址
我正在为 Linux 开发一个简单的驱动程序,它将通过 SPI 与设备通信。在我使用 request_mem_region 和 ioremap 之后,我可以从返回的地址读取的所有内容都是 0即使我给它
所以,对于内核驱动程序,我是一个新手,并且对 ioremap 函数有疑问。 我正在编写一个驱动程序,用于访问在具有 ARM Cortex-M3 和 FPGA 结构的 SoC 上的自定义 VHDL 模块
我需要从内核中保留一个大的物理连续 RAM 缓冲区,并能够保证该缓冲区将始终使用特定的硬编码物理地址。该缓冲区应在内核的整个生命周期内保留。我已经编写了一个 chardev 驱动程序作为在用户空间中访
我正在为运行 Linux 2.6.37 的 ARM 设备开发。我正在尝试尽快切换 IO 引脚。我制作了一个小内核模块和一个用户空间应用程序。我尝试了两件事: 使用 ioremap 直接从内核空间操作
我使用 memmap=8G$4G Linux 内核启动参数保留内存块。 是否需要ioremap此内存? ioremap 手册页说: ioremap performs a platform specif
假设我有一些物理地址(这是我的 DMA 源外设的总线位置): phys_addr = 0xffff0000; 我这样做: virt_addr = ioremap(phys_addr, PAGE_SIZ
我是内核编程新手,现在尝试将一些值写入设备驱动程序中的 32 位 GPIO 寄存器。 I/O 为ioremap() -ed 到内存地址。问题是,我不知道怎么办writel()/writeb()/wri
我正在更改 linux 内核调度程序以在已知物理内存位置打印下一个进程的 pid。 mmap 用于用户空间程序,而我读到 ioremap 将页面标记为不可缓存,这会减慢程序的执行速度。我想要一种快速写
我正在尝试编写一个在 RPI3 上读取 GPIO 的内核驱动程序(模块) 我使用 ioremap 访问 GPIO 的内存,但显然它崩溃了。 我在/var/log/messages 日志文件中得到一个异
我正在编写一个示例应用程序,用于读取寄存器并在给定的 SPI 设备地址上写入特定值。 我使用 altera spi 1.0 驱动程序,在注册 spi 设备时获得基地址为 0xE5002460。 我想使
我是一名优秀的程序员,十分优秀!