9

我正在研究一个小型嵌入式系统。当我的 linux 启动到用户空间时,我知道我的设备在物理内存中的位置。我想将它们映射到用户空间虚拟地址。目前,我正在通过内核模块进行操作。我使用 vmalloc/kmalloc(取决于大小),然后在返回的虚拟地址上使用 ioremap_page_range 来映射我的物理地址。我不认为这是正确的做法。首先我正在分配内存,然后我要求内核将该虚拟地址空间重新映射到一些不同的物理地址空间。(最初在 vmcall/kmalloc 中映射的物理->虚拟有点没用,因为我不关心那些物理页面。这绝对不好。)

取而代之的是一种将已知物理内存映射到用户空间进程的更好方法。(我知道除了我的用户空间进程之外,没有人会碰那个内存。)

谢谢

4

3 回答 3

6

您要做的是访问所谓的IO memory。我只能鼓励您阅读Linux 设备驱动程序(LDD) 书,更具体地说是第 9 章。

要“分配”这样一个区域,您需要调用

struct resource *request_mem_region(unsigned long start, unsigned long len, char *name)

. 在您的驱动程序可以访问它之前,您必须为其分配一个虚拟地址,这是通过调用

void *ioremap(unsigned long phys_addr, unsigned long size)

为确保您的驱动程序将在不同的架构/平台上工作,请务必对这些区域使用一些访问器函数(ioread8/16/32 或 iowrite8/16/32 及其所有变体)。

于 2012-07-25T06:45:43.050 回答
4

在内核模块中,remap_pfn_range()可用于将物理地址转换为虚拟地址。以下链接会有所帮助。

remap_pfn_range 如何将内核内存重新映射到用户空间?

于 2012-07-24T05:22:38.270 回答
0

在 Kernel 模块中, remap_pfn_range() 可用于将物理地址转换为虚拟地址。当您没有实际设备时,您可以:1)创建一个虚拟设备,2)使用这些虚拟设备的 mmap 通过该进程的 remap_pfn_range 虚拟映射访问相同的内核内存。3)通常在专用环境中,您可能还希望固定这些物理页面,以免它们从您的进程中被带走。4)您还与不同的进程共享这些物理地址,但需要通过其他 IPC 机制独立处理同步,因为每个进程看起来是不同的地址。

于 2015-05-14T07:22:17.987 回答