从内核分配用户空间内存

Posted

技术标签:

【中文标题】从内核分配用户空间内存【英文标题】:allocate user-space memory from kernel 【发布时间】:2011-11-29 13:23:47 【问题描述】:

我正在打电话

sys_readlink(const char __user *path, char __user *buf, int bufsiz)

直接,但获取 EFAULT 错误代码。出现此错误是因为 buf 指向内核空间的内存。

那么,有没有办法?

kmalloc(size, GFP_USER) 类似于 kmalloc(size, GFP_KERNEL) 并返回指向内核内存的指针。

【问题讨论】:

为什么需要在内核中做如此高级别的事情? 你已经在内核空间了;您应该直接调用 VFS 而不是使用系统调用。 我正在使用 readlink("/proc/PID/exe") 来获取当前进程映像文件的完整路径,还有其他方法可以获取吗?我不能使用 d_path(),因为它使用了一个已经被我钩住的系统调用,所以它返回 NULL GFP_USER 表示您可以允许用户访问的内核空间内存(通常用作共享内核/用户页面的标记)。 Readlink 需要一个用户空间虚拟内存区域和该区域中的地址。我建议您采纳 Ignacio 的建议或重新考虑在内核中编写此代码。 【参考方案1】:

您可以使用set_fs暂时禁用内存地址有效性检查

mm_segment_t old_fs;

old_fs = get_fs();
set_fs(KERNEL_DS);
/* Your syscall here */
set_fs(old_fs);

【讨论】:

非常感谢,这正是我需要的。 嗨,我遇到了类似的问题。在我的情况下,我想要做的系统调用是预先准备好的。所以我直接调用了vfs_read。我验证了这个 set_fs(KERNEL_DS) 正在完成这项工作。但是,后来当我使用 O_DIRECT 标志打开文件并执行 vfs_read 时,我再次得到 -EFAULT。你能解释一下 O_DIRECT 问题吗? @ErbenMo: IIRC O_DIRECT 带有一些严格的对齐要求(实际要求因文件系统和内核版本而异),这可能是您的问题的原因。 我认为对齐要求是磁盘上数据的大小/地址,而不是读取后存储数据的缓冲区的大小/地址...所以我不确定是否是这样问题是因为我在磁盘上读取的数据是 4kb 对齐的。似乎问题在于存储数据的内存缓冲区。 @ErbenMo:如果我没记错的话,这些要求也在用户缓冲区上。未对齐的缓冲区可能不起作用。

以上是关于从内核分配用户空间内存的主要内容,如果未能解决你的问题,请参考以下文章

linux内存地址分配

CMA连续物理内存用户空间映射---

虚拟地址空间:用户空间和内核空间 物理内存管理:伙伴系统以及slab分配器

Linux的内核空间和用户空间是如何划分的(以32位系统为例)?

Linux内核之进程地址空间

内存管理(上)