android linux 内核中虚拟地址到物理地址的反向

Virtual address to physical address and reverse in android linux kernel

我正在尝试将虚拟地址转换为物理地址,并使用 android linux 内核环境将此物理地址映射到虚拟地址。

我可以修改内核代码。所以我尝试了下一个流程。

  1. malloc() 在 android 用户中 space 本机二进制文件不是应用程序
  2. 使用指南将 vamalloc() 转换为 pa Is there any API for determining the physical address from virtual address in Linux?
  3. pa传递给我创建的系统调用函数。
  4. 使用 ioremap()
  5. pa 重新映射到 linux 内核 space 中的 va
  6. 使用readl()ioread32()
  7. 读取值

但是现在不行了。

  1. vapa的逻辑在上面link;在我的本机二进制文件中,下面是伪代码。
    int main(){
        char *va=malloc(100);
        memset(va, "ttttt", ...)
        uintptr_t paddr;
        vir_to_phys_user(&paddr, getpid(), va);
        syscall(sys_readpa, (unsigned long)paddr);
    }
  1. 系统调用函数
    void sys_readpa(unsigned long pa){
        void __iomem* mapped_add = ioremap(pa);
        printk("%c", readl(mapped_add));
        printk("%c", ioread32(mapped_add));
    }

我的代码有类似的逻辑:

我不知道 vapa 的逻辑是否正确。但它 returns 一个地址而不是失败。

但是当调用系统调用时,会发生内核崩溃 - 例如"dereference for 0000000 address",以及其他类型的错误。我检查了系统调用中的 pa 与用户 space.

中的相同

我这次尝试的目的是学习。我只是想知道如果我也可以修改内核代码,这个实现是可能的,但我遇到了障碍。

请告诉我有什么问题或不可能吗?如果需要,我会更新更多详细代码或具体错误消息。


我添加了详细错误和我的调试日志。

我的用户space登录

: vitrual address : 0xf079c000
: 0xf079c000 -> 0xa4a8a000

我将 0xa4a8a000 传递给系统调用。

dmesg

[   96.794448] accepted pa : 00000000a4a8a000
[   96.794473] ------------[ cut here ]------------
[   96.794500] WARNING: CPU: 6 PID: 11644 at arch/arm64/mm/ioremap.c:58 __ioremap_caller+0xc0/0xcc
[   96.794519] Modules linked in:
[   96.794552] CPU: 6 PID: 11644 Comm: mt Not tainted 4.14.113 #1
[   96.794590] Call trace:
[   96.794611] [<0000000000000000>] dump_backtrace+0x0/0x2b8
[   96.794632] [<0000000000000000>] show_stack+0x18/0x24
[   96.794655] [<0000000000000000>] dump_stack+0xa0/0xdc
[   96.794676] [<0000000000000000>] __warn+0xbc/0x164
[   96.794695] [<0000000000000000>] report_bug+0xac/0xdc
[   96.794713] [<0000000000000000>] bug_handler+0x30/0x8c
[   96.794732] [<0000000000000000>] brk_handler+0x94/0x150
[   96.794751] [<0000000000000000>] do_debug_exception+0xd4/0x170
[   96.794769] Exception stack(0xffffff8010fdbc10 to 0xffffff8010fdbd50)
[   96.794787] bc00:                                   0000000000000000 0000000000000004
[   96.794805] bc20: 00e8000000000f07 ffffff8008358714 000000000000000c 0000000000002d7c
[   96.794822] bc40: ffffffc0119630e7 5b20205d38343434 0000000000000000 0000000000000001
[   96.794839] bc60: 0000000000000001 00000000bab00000 0000000000000000 0000000080000000
[   96.794856] bc80: ffffff800b18d000 0000000000000082 00000000000564c8 0000000000000074
[   96.794873] bca0: 0000000000000074 00e8000000000f07 00000000a4a8a000 0000000000001000
[   96.794890] bcc0: ffffff8008358714 0000000000000000 0000000000000011 000000000000018f
[   96.794908] bce0: 000000000000018e ffffff8009316000 ffffffc8767edf80 ffffff8010fdbe80
[   96.794926] bd00: ffffff80081fe124 ffffff8010fdbe50 ffffff80081fe188 0000000020400145
[   96.794943] bd20: 0000000000000034 7cebe7b2cf849500 0000007fffffffff ffffff8009316000
[   96.794961] bd40: ffffff8010fdbe80 ffffff80081fe188
[   96.794978] [<0000000000000000>] el1_dbg+0x18/0x74
[   96.794995] [<0000000000000000>] __ioremap_caller+0xc0/0xcc
[   96.795014] [<0000000000000000>] __ioremap+0x10/0x1c
[   96.795035] [<0000000000000000>] sys_readpa+0x78/0xfc
[   96.795055] Exception stack(0xffffff8010fdbec0 to 0xffffff8010fdc000)
[   96.795072] bec0: 00000000a4a8a000 0000000028bf4d08 0000000000000003 00000000f079c000
[   96.795090] bee0: 0000000000000000 00000000a4a8a000 0000000000000000 000000000000018e
[   96.795107] bf00: 00000000f09afd94 00000000f09d2b99 00000000ae6c9e84 00000000ae6a261e
[   96.795124] bf20: 00000000ff921bf0 00000000ff921be0 00000000ae5f7b27 0000000000000000
[   96.795142] bf40: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[   96.795159] bf60: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[   96.795176] bf80: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[   96.795195] bfa0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[   96.795212] bfc0: 00000000f091ce20 0000000060000010 00000000a4a8a000 000000000000018e
[   96.795229] bfe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[   96.795247] [<0000000000000000>] __sys_trace_return+0x0/0x4
[   96.795265] ---[ end trace 91e76f3be7c0b9bd ]---
[   96.795418] ioremap return null

我找到了修复。 ioremap 有一个地址验证的检查逻辑。 此函数用于保留地址,但它试图映射已经映射到进程的地址。 所以,我修改了ioreamp中的校验逻辑,效果很好。