我正在尝试使用 gdb(远程连接)读取(希望也可以写入)qemu 虚拟机中的内存映射硬件寄存器。但是它不起作用:
(gdb) p *0x2000000
Cannot access memory at address 0x20000000
但是如果我登录到机器上并执行
# devmem 0x2000000
0xE321F0D3
这很好用。显然 gdb 没有从中获取信息/dev/mem
。我已经启用了我能想到的所有编译时调试标志,我可以放置断点、单步执行代码以及取消引用与符号关联的指针。但大多数原始指针取消引用都会失败。
作为记录,这就是我启动 qemu 的方式:
qemu-system-arm -M versatilepb -kernel output/images/zImage \
-dtb output/images/versatile-pb.dtb \
-drive file=output/images/rootfs.ext2,if=scsi \
-append "root=/dev/sda console=ttyAMA0,115200 nokaslr norandmaps printk.devkmsg=on printk.time=y" \
-nographic -s
我在其中添加了nokaslr
等,因为我认为这会有所作为。显然没有。有人知道这是怎么回事吗?
答案1
gdb
并devmem
正在研究两件不同的事情。gdb
正在查看0x20000000
位置映射的进入你的进程地址空间,这在进程与进程之间是不同的(它必须是,否则交换文件和页表基本上是无用的。)devmem
正在查看文件/dev/mem
,它直接查看物理内存。
为什么进程地址空间不向进程公开所有物理地址位置?主要原因是这将是一个巨大的安全漏洞:您不希望随机进程能够从它们不拥有的内存中读取和写入数据(否则它们可以轻松绕过安全性。)此外,该devmem
页面放置了它,“某些物理地址是硬件寄存器;写入甚至读取它们可能会导致您的计算机/设备崩溃、熔化或爆炸。我们已警告您!”