static void __init devicemaps_init(const struct machine_desc *mdesc)
{
……
vectors = early_alloc(PAGE_SIZE * 2); -----分配两个page的物理页帧
early_trap_init(vectors); -------copy向量表以及相关help function到该区域
……
map.pfn = __phys_to_pfn(virt_to_phys(vectors));
map.virtual = 0xffff0000;
map.length = PAGE_SIZE;
#ifdef CONFIG_KUSER_HELPERS
map.type = MT_HIGH_VECTORS;
#else
map.type = MT_LOW_VECTORS;
#endif
create_mapping(&map); ----------映射0xffff0000的那个page frame
if (!vectors_high()) {---如果SCTLR.V的值设定为low vectors,那么还要映射0地址开始的memory
map.virtual = 0;
map.length = PAGE_SIZE * 2;
map.type = MT_LOW_VECTORS;
create_mapping(&map);
}
map.pfn += 1;
map.virtual = 0xffff0000 + PAGE_SIZE;
map.length = PAGE_SIZE;
map.type = MT_LOW_VECTORS;
create_mapping(&map); ----------映射high vecotr开始的第二个page frame
……
}
为什么要分配两个page frame呢?这里vectors table和kuser helper函数(内核空间提供的函数,但是用户空间使用)占用了一个page frame,另外异常处理的stub函数占用了另外一个page frame。为什么会有stub函数呢?稍后会讲到。
在early_trap_init函数中会初始化异常向量表,具体代码如下:
void __init early_trap_init(void *vectors_base)
{
unsigned long vectors = (unsigned long)vectors_base;
extern char __stubs_start[], __stubs_end[];
extern char __vectors_start[], __vectors_end[];
unsigned i;
vectors_page = vectors_base;
将整个vector table那个page frame填充成未定义的指令。起始vector table加上kuser helper函数并不能完全的充满这个page,有些缝隙。如果不这么处理,当极端情况下(程序错误或者HW的issue),CPU可能从这些缝隙中取指执行,从而导致不可知的后果。如果将这些缝隙填充未定义指令,那么CPU可以捕获这种异常。
for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)
((u32 *)vectors_base)[i] = 0xe7fddef1;
拷贝vector table,拷贝stub function
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-76601-4.html
挺好