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

3
我正在编写一段代码,需要在SOC关闭之前存储位于特定物理地址的10K内存。我的问题是这个物理地址不属于内核空间,所以我必须创建一个特定的内存映射才能访问这段内存空间。我尝试使用io-remap,但它似乎不能在非内核空间使用。是否有任何API可以解决这个问题?我应该使用kmap吗?感谢您提前的帮助。

1
你能否在启动期间(在U-Boot函数中)确定要保留哪些内存区域,将这些区域从(有效的)内存列表中排除,然后编写一个驱动程序来实际映射和使用那个“特殊”的内存?https://dev59.com/Vmgu5IYBdhLWcg3wGjZF#12137511 - sawdust
我可以在启动时从ATAGs中排除内存,但如何映射这些区域?之前的ioremap似乎不起作用。也许是因为该区域属于不同的内存空间? - Strudle
"io-remap ... doesn't ... work on non-kernel space" - "Kernel"和"user"内存空间是指虚拟内存。ioremap()必须提供一个物理地址范围。请注意,如果没有虚拟或物理限定符,使用“memory”一词可能会产生歧义或混淆。也许您需要重新审视和分析为什么ioremap()似乎没有“工作”。这里有另一个问答,涉及为内核驱动程序使用划分物理内存:https://dev59.com/N2jWa4cB1Zd3GeqPs61l#12557974 - sawdust
@JonathanLeffler - 你的编辑,尤其是“这个物理地址在用户空间内”的部分,毫无意义,很可能误述了问题。 - sawdust
@sawdust:好的,请修复它。没关系,我会回滚并让其他人来尝试。 - Jonathan Leffler
2个回答

2
听起来像是内存映射外设。为了紧密绑定到您的内核,需要将条目添加到initdata中,并进入iotable_init()。例如,在arch / arm / mach-vexpress / ct-ca9x4.c中,ct_ca9x4_io_desc[]创建虚拟到物理的映射。然后,内核代码可以使用虚拟地址写入其中的数据,保留HTML标签。

实际上,地址空间是每个DRAM芯片选择器的前10k,这些可能会根据板子设置而改变。因此,我必须在运行时执行此操作。我无法在编译时告诉地址空间位置。 - Strudle
https://dev59.com/UWsz5IYBdhLWcg3wcnZb 这里有一些很好的信息。但请注意,“这是一个非常复杂的编程领域,你不太可能在如此有限的空间内得到你需要的答案...” - Joe Kul

1
找到答案了。
关键是使用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);

你是在用户空间还是内核模块中完成的这个操作? - Joe C
希望这篇文章还没有过时需要编辑。my_page = phys_to_page(phys_addr_ptr); 应该改为 *my_page = phys_to_page(phys_addr_ptr);,因为 phys_to_page() 的返回值是一个 struct page * - d4r3llo5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接