Linux-在内核代码中映射用户空间内存

Linux-在内核代码中映射用户空间内存,linux,memory-management,linux-kernel,memory-mapping,mmu,Linux,Memory Management,Linux Kernel,Memory Mapping,Mmu,我正在写一段代码,在SOC关闭之前,它需要存储位于特定物理地址的10k内存 我的问题是这个物理地址不是内核空间的一部分,所以我必须创建一个特别的内存映射,这样我才能访问这个内存空间 我尝试过使用io重新映射,但它(显然)在非内核空间上不起作用 是否有任何API用于执行此操作? 我应该用kmap吗 提前感谢听起来像是内存映射外设。对于内核中的紧密绑定,它将在initdata中添加条目,该条目将被添加到iotable_init()。例如arch/arm/mach vexpress/ct-ca9x4.

我正在写一段代码,在SOC关闭之前,它需要存储位于特定物理地址的10k内存

我的问题是这个物理地址不是内核空间的一部分,所以我必须创建一个特别的内存映射,这样我才能访问这个内存空间

我尝试过使用io重新映射,但它(显然)在非内核空间上不起作用

是否有任何API用于执行此操作? 我应该用kmap吗


提前感谢

听起来像是内存映射外设。对于内核中的紧密绑定,它将在initdata中添加条目,该条目将被添加到iotable_init()。例如arch/arm/mach vexpress/ct-ca9x4.c ct_ca9x4_io_desc[]。这将创建虚拟到物理的映射。然后内核代码可以使用带有虚拟地址的writel在那里进行写入

找到了答案

关键是使用vmap函数为给定的页面表创建映射。问题是如何将页表结构初始化为某个物理地址,但似乎也存在用于该地址的API

下面是一个分配单个页面的示例

void *virt_addr_ptr
struct page **my_page = kmalloc(sizeof (*my_page), GFP_KERNEL);
my_page = phys_to_page(phys_addr_ptr);
virt_addr_ptr = vmap(my_page, 1, VM_MAP, PAGE_KERNEL);

/*now its possible to access this space */
memcpy(store_buffer, virt_addr_ptr, store_size);

实际上,地址空间是每个DRAM芯片选择的前10k,这些地址空间可能会根据电路板设置而改变。所以,我必须在运行时执行此操作。我不能在编译时告诉地址空间的位置。里面有一些很好的信息。但是注意,“这是一个非常复杂的编程区域,在如此有限的空间内,你不可能得到你需要的答案……”你能确定在引导期间(在U-boot函数中?)保留哪些内存区域,排除(有效)内存列表中的那些区域,然后编写一个驱动程序来实际映射和使用那个“特殊”内存吗?我可以在引导期间从ATAG中排除内存,但是如何映射这些区域?ioremap以前似乎不起作用。可能是因为该区域是另一个内存空间的一部分?“io重新映射…不…在非内核空间上工作”-“内核”和“用户”内存空间指的是虚拟内存
ioremap()
必须提供一个物理地址范围。请注意,在没有虚拟或物理限定符的情况下使用“内存”一词可能会产生歧义或混淆。也许您需要重新审视并分析为什么
ioremap()
似乎不起作用。这里还有一个问答,涉及到为内核驱动程序使用而划分物理内存:@JonathanLeffler-您的编辑,尤其是“这个物理地址在用户空间中”,毫无意义,而且可能会误述问题。@sawdust:OK;那就修好它吧。没关系,我会把它回滚,让其他人试试。你是在用户区还是在内核模块中做的?希望这篇文章不会太死板,不适合编辑<代码>我的页面=物理页面到物理页面(物理页面地址)应该是
*my_page=phys_to_page(phys_addr_ptr)由于
phys\u返回到
struct page*