如何访问内核空间中的物理地址

时间:2016-06-05 06:22:15

标签: linux memory linux-kernel

如何使用内核直接修改内存块地址中的数据

我想修改(读取和写入)内核空间中用户进程虚拟地址空间中的数据,现在我已将转换的进程虚拟地址转换为物理地址,但是如何修改内核空间中的数据。 linux-3.14 arm64

在旧版本(x86_64)中我使用mmap来映射/ dev / mem,但它在arm64中不起作用

#ifdef MMAP_INVALID_ARGUMENT /*    invalid argument    when mmap   */
    mapStart = (void volatile *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE,     MAP_SHARED | MAP_LOCKED, memfd, 0xF000);

#else
    mapStart = (void volatile *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, memfd, pa_base);

#endif

我发现如果pa_bae大于1M,我会得到invalid argument

1 个答案:

答案 0 :(得分:1)

由于您要修改内核中用户空间地址中的数据,因此您需要内核API get_user_pages()。使用get_user_pages()可以读取或修改内核中的用户空间数据。这是描述 -

  

get_user_pages():

     

返回固定的页数。这可能少于数量   请求。如果nr_pages为0或负数,则返回0.如果没有页面   固定,返回-errno。返回的每个页面必须与a一起发布   完成后put_page调用。 vmas只会保持有效   而mmap_sem被保留。必须使用mmap_sem调用以进行读取或   写。 get_user_pages遍历进程的页表并获取   引用每个用户地址对应的每个结构页面   给定的瞬间。也就是说,它会占用将要访问的页面   用户线程在该时刻访问给定的用户虚拟地址。   这并不能保证页面存在于用户映射时   get_user_pages返回,甚至可能完全不同   在某些情况下页面(例如,如果mmapped pagecache已经存在)   失效,随后再次出现故障)。但它确实保证   该页面将不会被完全释放。而且主要是来电者   注意页面包含有时有效的数据   时间。通常,IO或类似操作不能保证任何事情   无论如何更强,因为锁不能保持在系统调用边界上。

     

get_user_pages()通常用于执行较少复制的IO操作   通过除了通过访问之外的其他方式获取内存的句柄   用户虚拟地址。

您可以参考以下链接: LWN LDD3