实现 PCIe Linux 设备驱动程序(想要从内核驱动程序访问我的卡寄存器)

2023-12-15

我正在编写一个设备驱动程序来访问 PCIe 卡上 FPGA 中的内存。
该卡启动并被探测/发现:-

/proc/iomem

80000000-840fffff : PCI Bus #03
  80000000-83ffffff : 0000:03:00.0
  84000000-840fffff : 0000:03:00.0

所以阅读 ldd/etc 我编写了一个调用request_mem_region at the 80000000,并通过请求指向它的指针ioremap_nocache

1)我需要吗request_mem_region以及ASAioremap_nocache,我可以只使用后者吗?

/proc/iomem 之后insmod我的设备驱动程序:-

80000000-840fffff : PCI Bus #03
  80000000-83ffffff : 0000:03:00.0
    80000000-8003ffff : fp2
  84000000-840fffff : 0000:03:00.0

2)我觉得不太合适……?

无论如何,读书是不行的(它的编码不像下面这样,它有检查等):-

#define BAR_ADDR 0x80000000
void *base = ioremap_nocache(BAR_ADDR, 0x40000);
void *address = base + KNOWN_REG_LOCATION;
int data = ioread32(address);
printk("fp2: address:0x%08x, data:0x%08x\n", address, data);

输出:-

address:0xfd500000, data:0xffffffff

我可以阅读x80000000+KNOWN_REG_LOCATION来自 mmap 用户空间。

3)我已经尝试过了__raw_readl/readl也没有运气。

4)我可以只读取当前映射的地址吗x80000000?


Ian,

我为一个设备编写了一个 PCI 驱动程序(完整源码)。不过,寄存器空间的映射应该是相同的。我是这样做的。

dm7820_device->pci[region].virt_addr = ioremap_nocache(address, length);
if (dm7820_device->pci[region].virt_addr == NULL) {
    printk(KERN_ERR "%s: ERROR: BAR%u remapping FAILED\n",
        &((dm7820_device->device_name)[0]), region);
    dm7820_release_resources();
    return -ENOMEM;
}

if (request_mem_region(address, length, &((dm7820_device->device_name)[0])) == NULL) {
    printk(KERN_ERR "%s: ERROR: I/O memory range %#lx-%#lx allocation FAILED\n",
        &((dm7820_device->device_name)[0]), address, (address + length - 1));
    dm7820_release_resources();
    return -EBUSY;
}

地址和长度值从返回pci_resource_start() and pci_resource_length() calls.

然后你可以使用它访问它ioread32() using dm7820_device->pci[region].virt_addr + <register offset>

如果您有任何疑问,请告诉我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实现 PCIe Linux 设备驱动程序(想要从内核驱动程序访问我的卡寄存器) 的相关文章

  • ARM架构中不同处理器模式下如何使用内核堆栈?

    据我了解 每个进程都有一个用户堆栈和内核堆栈 除此之外 ARM 架构中的每种模式都有一个堆栈 所以我想知道不同的堆栈和堆栈指针在 ARM 模式下如何工作 另外 何时会使用与进程关联的内核堆栈 何时会使用与进程关联的内核堆栈 当您进行系统调用
  • 内核编程中如何执行shell命令?

    我想用system 的函数stdlib h在我的c代码中 我实际上正在从事内核编程 每当我想使用system 其中 它给出了错误stdlib h说没有找到这样的文件 这很简单 include
  • 使用 gdb 在指定的可执行文件之外单步执行汇编代码会导致错误“无法找到当前函数的边界”

    我在 gdb 的目标可执行文件之外 甚至没有与该目标对应的堆栈 无论如何 我想单步执行 以便我可以验证汇编代码中发生了什么 因为我不是 x86 汇编方面的专家 不幸的是 gdb 拒绝进行这种简单的汇编级调试 它允许我设置并停止在适当的断点上
  • 尝试将 GCC 特定的 asm goto 移植到 Clang

    我一直在尝试将一些 GNU 扩展转换为实际的标准 C 这样它就可以在 clang 上运行 知道标准 C 而不是 GNU 扩展 我有点不知所措 asm goto 1 STATIC KEY INITIAL NOP pushsection jum
  • 加载内核模块时出现未知符号

    我需要帮助理解为什么在插入模块时出现错误 我努力了this http www linuxforums org forum kernel 56497 unkown symbol module error while insmodding bu
  • fork() & 内存分配行为

    我在一个禁用交换和禁用内存过量使用的系统上工作 假设我的进程当前消耗 100 MB 内存 而系统可用内存小于 100 MB 如果我执行 fork 它会失败 因为内核也尝试为子进程分配 100 MB 的空间吗 我读过 Linux 在分叉时使用
  • 使用 GCC 为 Linux 设备驱动程序编译 Intel AVX 内联

    我在 corei7 上的 ubuntu 上运行 gcc 版本 4 8 2 从谷歌搜索中找到了有关 AVX 内在函数的信息 但我不确定这组内在函数是否可以用于 Linux 设备驱动程序并进行编译 如果可以的话 这里的任何人都可以告诉我 mak
  • dmesg 和 /var/log/kern.log 之间的区别

    我正在修改kvm模块 并在内核代码中添加了printk语句 运行虚拟机后 printk为我提供了错误地址和有关客户操作系统的其他信息 我需要根据此信息生成统计信息 当我使用 dmesg 时 我只能看到错误地址 在内核空间中 即它们的地址高于
  • 在执行期间访问.eh_frame数据

    我正在尝试访问以下内容 eh frame正在运行的程序的一部分 具体来说 该程序是 Linux 内核 2 6 34 8 这 eh frame包含用于异常处理的有用数据 我想在内核代码内部使用它 该部分已经由以下人员编写gcc readelf
  • 如何在 Linux 内核空间使用 ioctl()?

    可以打电话吗ioctl来自 Linux 内核模块 谁能提供一个如何使用它的例子吗 您可以尝试拨打电话sys ioctl 如果内核是用以下命令编译的 则它会被导出CONFIG COMPAT 或者 如果您有设备驱动程序struct file o
  • 使用Linux虚拟鼠标驱动

    我正在尝试实施一个虚拟鼠标驱动程序根据基本 Linux 设备驱动程序书 有一个用户空间应用程序 它生成坐标以及内核模块 See 虚拟鼠标驱动程序和用户空间应用程序代码 http www embeddedlinux org cn Essent
  • 如何获取uinput创建的设备的名称(路径)

    我已经成功设置了一个小程序来创建uinput questions tagged uinput我计划使用它来自动测试接收键盘输入事件的应用程序 我已关注both http thiemonge org getting started with
  • 是否可以将 CFLAGS 设置为 Linux 内核模块 Makefile?

    例如 常见设备模块的Makefile obj m jc o default MAKE C lib modules shell uname r build M shell pwd modules clean MAKE C lib module
  • 无法访问打开的/arch/x86/syscalls/syscall_32.tbl

    当我在切换到内核后编写此命令时 当我编译它时 它没有显示任何列表 是否有其他命令可以打开列表 open arch x86 syscalls syscall 32 tbl Bug 先删除 文件路径中的字符 应该是relative http e
  • 在 /dev/input/eventX 中写入事件需要哪些命令?

    我正在开发一个android需要将触摸事件发送到 dev input eventX 的应用程序 我知道C执行此类操作的代码结构如下 struct input event struct timeval time unsigned short
  • 如何模拟ARM处理器运行环境并加载Linux内核模块?

    我尝试加载我的vmlinux into gdb并使用 ARM 内核模拟器 但我不明白为什么我会得到Undefined target command sim 这是外壳输出 arm eabi gdb vmlinux GNU gdb GDB 7
  • 内存调试:如何获取 Linux 用户空间/内核空间中的锁定页面信息

    有什么方法可以获取Linux用户空间 内核空间中的锁定页面 虚拟内存页面 信息 我想了解详细信息 例如 谁锁定了页面 有多少页被锁定 进程名称 谁锁定了页面 还让我了解内核空间和用户空间的内存调试技术 对于内存中的每个页面 都会为其分配标志
  • Linux内核container_of宏和C90中的通用容器

    是否有可能实施容器的 http lxr linux no linux tools perf util include linux kernel h L18纯C90中的宏 我不确定如何做到这一点 因为内核实现取决于海湾合作委员会黑客 http
  • 内核makefile中的$(call cmd,tags)这里的cmd指的是什么?

    在内核 Makefile 中我发现如下代码 ctags CTAGS CSCOPE HEADERS SOURCES ETAGS ETAGSFALGS HEADERS SOURCES call cmd ctags 另外 在哪里可以找到宏或函数
  • 当 mov 指令导致页面错误并且在 x86 上禁用中断时会发生什么?

    我最近在自定义 Linux 内核 2 6 31 5 x86 驱动程序中遇到一个问题 其中 copy to user 会定期不将任何字节复制到用户空间 它将返回传递给它的字节数 表明它没有复制任何内容 经过代码检查 我们发现代码在调用 cop

随机推荐