如何使用内核直接修改内存块地址中的数据
我想修改(读取和写入)内核空间中用户进程虚拟地址空间中的数据,现在我已将转换的进程虚拟地址转换为物理地址,但是如何修改内核空间中的数据。
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
答案 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操作 通过除了通过访问之外的其他方式获取内存的句柄 用户虚拟地址。