zoukankan      html  css  js  c++  java
  • mmap PROT_READ | PROT_WRITE

    *
     * 用于映射 resource 资源,并获取 PCI BAR
     * @param dev:DPDK 中关于某一个 PCI 设备的抽象实例
     * @param res_id:说明要获取第几个 BAR
     * @param uio_res:用来存放 PCI BAR 资源的结构
     * @param map_idx、uio_res:数组的计数器
    */
    
    int
    pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
            struct mapped_pci_resource *uio_res, int map_idx)
    {
        ..... // 省略
        // 打开 /dev/bus/pci/devices/{pci_addr}/resource0..N 文件
        if (!wc_activate || fd < 0) {
            snprintf(devname, sizeof(devname),
                "%s/" PCI_PRI_FMT "/resource%d",
                rte_pci_get_sysfs_path(),
                loc->domain, loc->bus, loc->devid,
                loc->function, res_idx);
    
            /* then try to map resource file */
            fd = open(devname, O_RDWR);
            if (fd < 0) {
                RTE_LOG(ERR, EAL, "Cannot open %s: %s
    ",
                    devname, strerror(errno));
                goto error;
            }
        }
    
        /* try mapping somewhere close to the end of hugepages */
        if (pci_map_addr == NULL)
            pci_map_addr = pci_find_max_end_va();
        // 进行 mmap() 映射,拿到 PCI BAR 在进程虚拟空间下的地址
        mapaddr = pci_map_resource(pci_map_addr, fd, 0,
                (size_t)dev->mem_resource[res_idx].len, 0);
        close(fd);
        if (mapaddr == MAP_FAILED)
            goto error;
    
        pci_map_addr = RTE_PTR_ADD(mapaddr,
                (size_t)dev->mem_resource[res_idx].len);
            // 将拿到的 PCI BAR 映射至进程虚拟空间内的地址存起来
        maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
        maps[map_idx].size = dev->mem_resource[res_idx].len;
        maps[map_idx].addr = mapaddr;
        maps[map_idx].offset = 0;
        strcpy(maps[map_idx].path, devname);
        dev->mem_resource[res_idx].addr = mapaddr;
    
        return 0;
    
    error:
        rte_free(maps[map_idx].path);
        return -1;
    }
    
    
    /*
     * 对 pci/resource0..N 进行 mmap(),将 PCI BAR 空间通过 mmap 的方式映射到进程内部的虚拟空间,供用户态应用来操作设备
    */
    void *
    pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
             int additional_flags)
    {
        void *mapaddr;
    
        // 核心便是这句 mmap,其中要注意的是 offset 必须为 0
        mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
                MAP_SHARED | additional_flags, fd, offset);
        if (mapaddr == MAP_FAILED) {
            RTE_LOG(ERR, EAL,
                "%s(): cannot mmap(%d, %p, 0x%zx, 0x%llx): %s (%p)
    ",
                __func__, fd, requested_addr, size,
                (unsigned long long)offset,
                strerror(errno), mapaddr);
        } else
            RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p
    ", mapaddr);
    
        return mapaddr;
    }
  • 相关阅读:
    Android中Context具体解释 ---- 你所不知道的Context
    JDK6、Oracle11g、Weblogic10 For Linux64Bit安装部署说明
    matplotlib 可视化 —— 定制 matplotlib
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    指数函数的研究
    指数函数的研究
    指数分布的研究
  • 原文地址:https://www.cnblogs.com/dream397/p/13658987.html
Copyright © 2011-2022 走看看