【问题标题】:mapping a memory region from kernel从内核映射内存区域
【发布时间】:2018-11-25 15:53:19
【问题描述】:

我有一个需要从多个驱动程序访问的寄存器。 它是驻留在 FPGA 空间中的全局只读寄存器 寄存器地址通过设备树导出。 第一次调用“request_mem_region”没问题,但任何连续调用都会失败。

有没有办法在驱动程序之间共享一个寄存器?

Linux 内核版本是 4.14 ,使用 petalinux

谢谢, 然

【问题讨论】:

  • 例如制作“父”驱动程序,该驱动程序调用request_mem_region 并提供一个函数,该函数公开该调用的结果地址。然后让你的驱动程序使用这个功能。
  • 使用面向对象的编程,即数据封装。拥有一个映射寄存器的驱动程序,然后创建一个读取该寄存器的函数。
  • 谢谢,所以使用 export 我可以访问 set\get 全局寄存器的功能。我唯一的问题是如何获取在探测函数中分配的设备驱动程序上下文。 @Tsyvarev - 你是什么意思“父母”司机?也许这是关键
  • “父”驱动程序是指其他驱动程序,您的驱动程序需要这些驱动程序。 (也就是说,“父”驱动程序应该在您的驱动程序之前加载。)在该父驱动程序中,您可以根据需要定义任意数量的函数。例如,返回设备驱动程序上下文的函数可以是“父”驱动程序导出的函数之一。请注意,您甚至可以导出 变量(嗯,这不是推荐的方法,但它可以简化很多事情。)
  • 如果它是只读寄存器,您可以根据需要多次重新映射其地址,而无需请求区域。但请注意:这是相当骇人听闻的。

标签: linux-kernel linux-device-driver memory-mapping petalinux


【解决方案1】:

您需要在请求后使用 ioremap() 之类的方法重新映射内存区域。

然后,正如 Tsyvarev 和其他人所提到的,在您的“父”驱动程序中创建并导出一个返回映射内存的函数。

这是一些粗略的代码:

void * mapped_mem;

void * map_addr(unsigned int phy_addr, char * name) {

    struct resource * resource;
    void * mapped_mem;

    resource = request_mem_region(phy_addr, page_size * 4, name);
    // check for errors

    mapped_mem= ioremap_nocache(phy_addr, page_size * 4);
    // check for errors
    return mappedMem;

    //handle errors
}


void * get_mapped_addr(void) {
    return mapped_mem
}

EXPORT_SYMBOL( get_mapped_addr);

现在,mapped_mem 实际上应该作为您设备私人信息的一部分进行跟踪,但我认为这超出了问题的范围。此外,请务必检查所有可能的错误。确保 request_mem_region() 返回 >0 而不是 Null。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多