在许多嵌入式系统上,通过读写软件中的内存映射I / O(MMIO)地址来完成与设备的大量通信。假设我可以访问物理设备,并且可以在IDA中加载固件的副本,那么如何确定哪些设备位于哪个地址?

到目前为止,我一直在通过查看代码,字符串引用进行猜测(例如,如果函数打印出“初始化计时器中断”,我可能会猜到其中某些地址用于配置计时器)。但是肯定可以肯定,有些东西必须知道所有设备在内存中的位置,因为有些东西负责将内存的读/写路由到正确的设备。 br />

#1 楼


但是,肯定有一些事情必须知道所有设备在内存中的位置,因为某些事情负责将内存读/写路由到正确的设备。 PCI(嗯,它可能存在,但这只是许多硬件模块之一)。因此,您不能仅扫描所有可能性以发现现有设备。代码必须知道所有内容都在哪里。

那是您可以尝试找到的一些信息源。


数据表-始终是最佳选择。即使有错别字和标准差,它仍然胜过其他任何事情。请注意,许多制造商都有单独的数据手册,以了解引脚分布,特定芯片的电气/温度特性以及用户手册(也称为软件或编程手册),这些手册在同一系列的许多芯片之间共享。您通常需要后者,尽管有时前者也可以提供一些有用的提示。
您可以找到该设备的任何源代码(操作系统,驱动程序等)。即使不是针对您感兴趣的特定硬件模块,标头也可能包含其定义。
如果找不到与您的芯片完全匹配的芯片,请寻找同一个系列的产品-通常差异只是一些模块的大小或端口数。
请参阅该制造商任何芯片中相同的硬件模块的文档。一些制造商在各种架构之间重用其IP块-例如英飞凌在其E-GOLD(C166)和S-GOLD(ARM)基带中使用了几乎相同的GPIO模块。瑞萨(Renesas)就是另一个例子-他们在其ARM芯片中重用了SuperH系列的IP块。
一些硬件在所有架构和制造商中都经过了标准化,例如:PCI,USB控制器(OHCI,EHCI,XHCI),SD主机控制器,eMMC等等。

编辑:有时,芯片外部的硬件可能通过外部总线接口(或外部存储器接口或许多其他名称)连接。通常存在于至少有一百个引脚的较大芯片中。该接口是可编程的,您可以设置将哪个地址范围分配给哪一组引脚。通常还涉及所谓的芯片选择(CS)线,这些线允许多路复用同一组引脚以访问多个设备,以便一个地址范围可以声明CS1,另一个CS2等等。如果有这样的设置,则需要找出用于初始化外部接口的代码,或者在运行时转储其配置。如果不能这样做,则可以尝试查找与外部芯片(例如以太网控制器)的寄存器布局相对应的内存访问,并在CPU地址空间中对某些基址进行模运算。

评论


没错,但同样地-知识也必须以某种方式嵌入到硬件中。例如。该软件读取的物理地址为0xdeadbeef。硬件必须知道这意味着“从Broadcom千兆位以太网控制器的寄存器0xf中读取”。是否应该有某种方法来枚举这些映射(不一定在软件中枚举,而是例如通过在板上寻找连接性或转储某些假设的地址映射芯片的配置)?

–布伦丹·多兰·加维特(Brendan Dolan-Gavitt)
2013年6月3日17:39

@ BrendanDolan-Gavitt:添加了一些有关我认为你的意思的文字

–伊戈尔·斯科钦斯基♦
13年6月3日在17:58

好吧,我想我明白了。不幸的是,我现在正在查看的SoC是由PMC为该特定公司(HP)生产的,并且没有可用的数据表或源代码。我最了解的是它基于Cortex A8,但这并没有告诉我有关内存映射的任何信息。所以,我回头盯着二进制文件...

–布伦丹·多兰·加维特(Brendan Dolan-Gavitt)
2013年6月4日19:02