【问题标题】:Virtual address to physical address and reverse in android linux kernel虚拟地址到物理地址并在android linux内核中反转
【发布时间】:2019-12-06 23:22:32
【问题描述】:

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

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

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

但是现在不行了。

  1. vapa 的逻辑在上面的链接中;在我的原生二进制文件中,下面是伪代码。
    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));
    }

我的代码有类似的逻辑:

  • 我在用户空间定义了va,并从va计算pa
  • 我将va 设置为“tttt”。
  • 使用系统调用将pa 传递到Linux 内核空间。
  • 在内核空间中将此pa 重新映射为va
  • 在内核空间中读取va 并期望值为“ttttt”

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

但是当调用 syscall 时,会发生内核恐慌——例如“取消引用 0000000 地址”和其他类型的错误。我检查了系统调用中的pa 与用户空间中的相同。

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

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


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

我的用户空间日志

: 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

【问题讨论】:

  • 您好,为了便于阅读,我已重新格式化并更正了拼写错误;如果您可以添加可以帮助您获得问题答案的特定错误消息。我添加了代码格式化标记以更好地格式化代码/伪代码示例 - 有关更多详细信息,请参阅 editing help。祝你好运:)

标签: linux memory kernel virtual


【解决方案1】:

我找到了解决办法。 ioremap 具有用于验证地址的检查逻辑。 此函数用于保留地址,但它会映射已经映射到进程的地址。 于是,我修改了ioreamp中的校验逻辑,效果很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 2013-10-29
    • 2017-07-07
    • 1970-01-01
    相关资源
    最近更新 更多