arm如何在内核空间直接读写某个物理地址(或者进程的虚拟地址)

新手上路,请多包涵

想要修改一个进程的虚拟地址中某个数据的

之前是mmap /dev/mmap来实现的

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

在x86_64上运行好好的,但是在arm上提示

Failed to mmap /dev/mem [0xffffffc2eef70000], errno : [22, Invalid argument]

问题1 ===发现pa_base超过1M的就会报这个错,不知道为什么?===

然后我决定用驱动来完成修改工作,pa是物理地址,不是很懂,但是写了下面的代码,也不知道对不对

    unsigned long   data = FAIL;
    unsigned long   pa_base = pa << PAGE_SHIFT;
    unsigned long   pa_offset = pa - pa_base;
    struct page     *pa_page = mem_map + pa_base;
    void volatile *mapStart = (void volatile *)kmap(pa_page);
    dbginfo("physical address 0x%lx to kernel address 0x%lx\n", pa, va, data);
    if(mapStart == NULL)
    {
        dbginfo("kmap error\n");
    }
    else
    {
        memcpy(&data, mapStart + pa_offset, sizeof(unsigned long));
        dbginfo("physical address 0x%lx to kernel address 0x%lx, data 0x%lx\n", pa, va, data);
    }

问题2==发现驱动内部,kmap映射出的地址是NULL

我该怎么解决,怎么在内核空间直接读写某个地址,怎么映射呢

阅读 7.7k
2 个回答
新手上路,请多包涵

memfd 有问题吧。

不是很清楚具体情况,猜测可以检查的点:

  1. memfd 对应的文件有多大?PAGE_SIZE + pa_base 是不是大于文件大小了?

  2. memfd 是不是一个普通的文件,是不是用类似POSIX_TYPED_MEM_ALLOCATEPOSIX_TYPED_MEM_ALLOCATE_CONTIG的特殊内存对象?如果是的话,这种在各种平台上表现是会有差异的,man里是这么讲的:

If fildes represents a typed memory object opened with either the POSIX_TYPED_MEM_ALLOCATE flag or the POSIX_TYPED_MEM_ALLOCATE_CONTIG flag, the memory object to be mapped shall be that portion of the typed memory object allocated by the implementation as specified below. In this case, if off is non-zero, the behavior of mmap() is undefined. If fildes refers to a valid typed memory object that is not accessible from the calling process, mmap() shall fail.

再看了下题,题主的问题可能是2吧。

如果验证是第2种造成,可能只能改代码了,最后一个参数只是个偏移量,可以设置为0,并增加映射区域的长度,然后自己访问的时候加上偏移就好。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏