4

我有一个 android 设备 - 内核版本为 2.6.35.14 (arm cortex a9) 的三星 Galaxy s2

我试图找到异常向量表的物理地址。我知道它位于 0xffff0000 虚拟地址。(我可以通过内核模块打印它的值)

我也知道大多数内核虚拟地址(到物理地址)的转换是由值 0x8000000 的变电站完成的。

我有一个可以直接从设备内存读取数据的设备,我想获取异常向量表。

当我构建内核模块并尝试使用宏 virt_to_phys(0xffff0000) 时,我得到了一些地址,但表不存在。我以这种方式成功找到了系统调用表,但这里的宏给了我错误的地址。

有谁知道为什么会这样?异常向量表的地址是否位于特殊的物理地址中?内核是否以某种特殊方式转换其地址?

谢谢你!!

4

2 回答 2

6

从 2.6.35 到最新的 mainline ,异常向量表在 Linux 中一直保持相当稳定。它在引导阶段很早就被分配并涉及memblock引导分配器。涉及的文件是内核目录中的entry-armv.Straps.cvmlinux.lds.S(链接描述文件)以及mm(或内存管理ARM目录)中的init.cmmu.c 。此外,向量表必须一直被映射并且它可以被用户进程读取。这由内核用户帮助程序使用; 帮助程序也映射到此页面。

一个解释

vmlinux.lds.S

向量和存根是可重定位的代码,唯一重要的是它们的相对偏移量

__vectors_start表示向量页面中的代码,可在entry-armv.S中找到。但是,该函数被重新定位在traps.c中。引导分配器为虚拟0xffff000地址保留一个页面(如果配置了高向量)。在您的 2.6.35 内核中,在init.c中使用了memblock分配器。这里mmu.c通过调用来分配一个页面。这个页面不遵循正常的内核地址空间规则,不能作为虚拟地址被强制使用。 devicemaps_init()early_alloc()virt_to_phys

但是,内核地址确实存在原始memblock_alloc()返回地址。这是vector;devicemaps_init()中的指针 此地址可与virt_to_physand一起使用phys_to_virt

entry-armv.S__vectors_start中的等的物理地址可以很容易的找到并计算出物理地址;但是,它在初始化阶段结束时被丢弃,我认为您对此不感兴趣。

一个答案

您可以调用、memblock_dump_all(void)查看dmesg并使用这些指针来尝试定位vector页面。它将是 4k 大小。您可以更改devicemaps_init()以导出vector值。未修改内核的唯一方法是遍历ARM mmu 表;那是另一个故事。

于 2013-10-09T18:23:55.977 回答
2

也可以直接使用 MMU(寄存器 ATS1Cxx 和 PAR)来执行 V=>P 转换。有关详细信息,请参阅ARM ARM的B4.2.4 部分。

如果您以这种方式使用 MMU 寄存器,您可能需要防止与寄存器的其他用途发生竞争。

这可以使用以下代码从任何内核驱动程序访问,

 unsigned int pa;
 asm("\t mcr p15, 0, %0, c7, c8, 2\n"
     "\t isb\n"
     "\t mrc p15, 0, %0, c7, c4, 0\n" : "=r" (pa) : "0" (0xffff0000));
 printk("Vector is %x\n", pa & 0xfffff000);

常数是正确的。

  • 0xffff0000 是高向量虚拟地址。
  • 0xfffff000 是 4k 页的掩码。

这仅适用于后来的系列 ARM 处理器,例如Cortex系列。

于 2013-10-10T08:17:23.750 回答