gpt4 book ai didi

c - mmap 实际上返回什么?

转载 作者:太空宇宙 更新时间:2023-11-04 02:45:37 25 4
gpt4 key购买 nike

我对如何定义 mmap 调用实际返回的地址感到有点困惑,这可能是因为我看到一段代码,其中该地址被转换为 uint64_t 并用裁剪理地址。如果它是一个虚拟地址,而我们需要一个物理地址,可以在打开 proc/self/map 后使用涉及页面大小等模数的公式找到它。只是对其进行抽象。

无论是否使用大页面,我们如何处理这个地址都重要吗?

另外,什么样的地址适合归类为DMA-ABLE地址。通过代码示例,在内核中我们使用 pci_alloc_consistentpci_map_single 来查找 dma 地址。假设在用户空间应用程序中,我希望 dma TO/FROM 设备并通过 malloc 或 mmap 为其 tx 和 rx 环分配一部分内存,并且我想要与该地址关联的物理地址。我应该只使用类型转换 uint64_t(addr) 还是编写一个函数将此虚拟地址转换为物理地址,相当于 pci alloc 返回的 dma 句柄一致。

从开源 DPDK 代码中添加示例

    mcfg = rte_eal_get_configuration()->mem_config;

/* hugetlbfs can be disabled */
if (internal_config.no_hugetlbfs) {
addr = mmap(NULL, internal_config.memory, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (addr == MAP_FAILED) {
RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n", __func__,
strerror(errno));
return -1;
}
mcfg->memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr; -----???
mcfg->memseg[0].addr = addr;
mcfg->memseg[0].len = internal_config.memory;
mcfg->memseg[0].socket_id = SOCKET_ID_ANY;
return 0;
}

在另一种情况下,它会通过此将从大页面映射的地址转换为物理地址。

    /*
* Get physical address of any mapped virtual address in the current process.
*/
phys_addr_t
rte_mem_virt2phy(const void *virtaddr)
{
int fd;
uint64_t page, physaddr;
unsigned long virt_pfn;
int page_size;
off_t offset;

/* standard page size */
page_size = getpagesize();

fd = open("/proc/self/pagemap", O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "%s(): cannot open /proc/self/pagemap: %s\n",
__func__, strerror(errno));
return RTE_BAD_PHYS_ADDR;
}

virt_pfn = (unsigned long)virtaddr / page_size;
offset = sizeof(uint64_t) * virt_pfn;
if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
RTE_LOG(ERR, EAL, "%s(): seek error in /proc/self/pagemap: %s\n",
__func__, strerror(errno));
close(fd);
return RTE_BAD_PHYS_ADDR;
}
if (read(fd, &page, sizeof(uint64_t)) < 0) {
RTE_LOG(ERR, EAL, "%s(): cannot read /proc/self/pagemap: %s\n",
__func__, strerror(errno));
close(fd);
return RTE_BAD_PHYS_ADDR;
}

/*
* the pfn (page frame number) are bits 0-54 (see
* pagemap.txt in linux Documentation)
*/
physaddr = ((page & 0x7fffffffffffffULL) * page_size)
+ ((unsigned long)virtaddr % page_size);
close(fd);
return physaddr;
}

最佳答案

mmap() 返回指向新映射内存的指针。该指针指向程序看到的地址空间,可以像任何其他 void* 类型的指针一样使用。失败时,mmap() 返回 MAP_FAILED,这是一个常量,通常具有值 (void*)-1

关于c - mmap 实际上返回什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27759379/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com