【问题标题】:how to unmap the memory which is mapped using remap_pfn_range()如何取消映射使用 remap_pfn_range() 映射的内存
【发布时间】:2015-12-03 07:33:16
【问题描述】:

有多种方法可以将内核内存映射到用户空间。 有人说使用splice()mmap()等。

我正在调用mmap(),并使用我们自己的伪字符设备文件的描述符,例如“/dev/mem”。

当用我们自己的伪字符设备文件调用mmap()时,在mmap内部注册了file_operation函数指针,我们可以调用remap_pfn_range()来映射内存..

现在该进程可能已经终止/杀死/干净的 exit()。 如何从内核空间中删除这些映射。我正在研究 ARMv7-A。

谁能解释当进程被杀死/终止时这些内存映射会发生什么?内核是自己删除映射还是我们需要明确地unmap

【问题讨论】:

  • 您能否简明扼要地说明您在说什么。您想了解 /dev/mem 还是如何编写自己的? 这些映射等有点模糊。你从splice()(避免映射内存)和mmap()开始,它们是用户空间调用。稍后您将讨论内核 API 调用。您的问题目前尚不清楚。
  • 自定义驱动程序/设备的生命周期取决于该设备的用例;因此内核提供了多种方法来确保释放映射。它是系统全局的还是每个进程的映射或其他一些生命周期?
  • 主要要求是了解 remap_pfn_range() 的功能。假设它在内核空间中维护一些映射,我们如何删除它们。

标签: c linux-kernel arm


【解决方案1】:

当最后一个副本退出时,您可以通过release 处理它。

struct file_operations {
  ...
  int (*release) (struct inode *, struct file *);
  ...
}

来自LDD

在释放文件结构时调用此操作。 像 open 一样,release 可能会丢失。[请注意,不会调用 release 每次进程调用关闭。每当共享文件结构时 (例如,在 fork 或 dup 之后),直到发布才会被调用 所有副本都已关闭。如果您需要在任何复制时刷新待处理数据 关闭了,你应该实现flush方法。

【讨论】:

    【解决方案2】:

    mmap 将外部(进程)内存空间映射到调用它的进程的虚拟地址空间。内存可能是一个共享内存段,一个文件......与它映射到的物理内存段不同,mmap 只是创建一个到该段的“链接”,并返回一个可以从调用进程中看到和使用的地址。

    mmap 调用进程终止(自然而然地,被杀死..)时,它创建的映射将自动取消映射。

    但是,已映射且可能被其他进程使用(或不使用)的物理内存区域仍然可用。

    man mmap

    您可以在程序死亡之前关闭该程序的映射,

    int munmap(void *addr, size_t length);
    

    【讨论】:

    • 这不是 OP 所要求的。他有自己的设备,所以他需要实现“自动”执行的部分。
    • @artlessnoise 我严重怀疑“mmap() 是否可以使用 '/dev/mem' 的描述符或我们自己的伪字符设备文件调用。当使用我们自己的伪字符设备调用 mmap() 时文件”
    • 啊,好点子。我刚刚阅读了/dev/mem。他应该像 /dev/mem 这样使用。
    • munmap() 在进程空间中进行清理。在内核空间中调用 remap_pfn_range() 时,除了映射到用户空间之外,它的功能是什么。它是否在内核空间中维护任何东西?
    • remap_pfn_range() 执行实际映射(驱动程序端)并使用分配给用户端的数据(通过 mmap())。因此,在调用 remap_pfn_range() 之后,驱动程序端没有要释放的特定数据,这将通过显式调用 munmap() 从用户端完成或当用户进程死亡时自动执行。
    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 2011-02-27
    • 2020-06-25
    • 2015-08-09
    • 1970-01-01
    • 2013-07-31
    • 2017-06-28
    • 2013-08-30
    相关资源
    最近更新 更多