读取内存映射 IO 寄存器如何来自数据表并在 mmap 中使用它们

如何解决读取内存映射 IO 寄存器如何来自数据表并在 mmap 中使用它们

我有 Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection (Lewisville) (rev 04) 的英特尔系统。我已经下载了数据表,如 Intel ® 82579 Gigabit Ethernet PHY

的数据表

现在我正在读取 pci 以太网设备的资源 0,例如

    if((fd = open("/sys/bus/pci/devices/0000:00:19.0/resource1",O_RDWR | O_SYNC)) == -1) {
        perror("Error: open error");
    }

    int map_size = 4096UL;
    ...
    map_base = mmap(0,4096UL,PROT_READ,MAP_SHARED,fd,Register_Values_From_Datasheet);

我有 x86-64 位系统。卡利 Linux 5.7。 所以我将上面的 Register_Values_From_Datasheet 替换为来自数据表的寄存器偏移值,例如 0x00008 代替 STATUS:Device Status Register=from datasheet

但是 mmap() 的 errno 在 mmap 调用后具有值 22:EINVAL。意味着无效的论点。也许我从数据表中读取的偏移值可能需要以其他方式解释。

我在以太网设备的sys/bus/pci/devices/0000:00:19.0中的资源文件是这样的

        0x00000000fe400000 0x00000000fe41ffff 0x0000000000040200
        0x00000000fe427000 0x00000000fe427fff 0x0000000000040200
        0x000000000000f060 0x000000000000f07f 0x0000000000040101
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000

从上面的资源文本文件 (resource0) 转储显示,我的内存映射 IO 从 0x00000000fe400000 开始。所以我认为应该是 mmap 的返回地址 (return (void*)=&0x00000000fe400000)= 但我得到了类似 0xffffffff 的东西,而 errno 是 22。任何人都可以指导我正确的方向如何偏移量需要从数据表中解释。此外,通常需要访问哪些寄存器以获取 pci 以太网设备的数据包。因为我是设备编程的新手。

解决方法

Resource0 是资源列表,剩下的 Resource1 .. ResourceN 是寄存器所在的实际内存区域。 (参考:https://techpubs.jurassic.nl/manuals/linux/developer/REACTLINUX_PG/sgi_html/ch07.html

偏移量是一个区域内的偏移量,而不是该区域的偏移量。

因此,您通常会映射 region1 的整个空间 - 在您的情况下为 128KB,因为:0x00000000fe41ffff - 0x00000000fe400000 。 (您也可以检查 /proc/iomem 进行确认)

map_base = mmap(0,32*4096UL,PROT_READ,MAP_SHARED,fd,0); 

编辑: mmap 的签名是:

void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);

如果您指定的长度或偏移量超过文件大小,则会得到 EINVAL: 来自 Linux 手册页:

EINVAL We don't like addr,length,or offset (e.g.,they are too large,or not aligned on a page boundary).

您可能最终将 map_base 转换为 uint32_t 数组(如果所有寄存器都是 32 位)并使用:map_base_as_int[8/4] 索引到寄存器空间。

第一个障碍是获取只读数据(例如 MAC 地址等)。

一旦你真的想要发送和接收数据包,你就需要物理地址——DPDK代码处理这个(以一种相当复杂的方式),但你可以用GRUB参数切出物理内存并安全地使用它......


另一种方法是使用上面的偏移量在“/dev/mem”上使用 mmap fe400000) 无论如何,稍后您将需要它来访问物理内存(并且您需要确保编译内核以供访问 - 一些锁定的内核不是)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?