访问向量时出错 table
Error when accessing vector table
我的问题将基于 this code.
这是基于 arm 的板(rpi2)的启动代码。我最感兴趣的是与矢量 table 设置相关的部分。向量 table 如下所示:
// Vector table
.align 4
.globl vec_table
vec_table:
ldr pc,add_handler_00
ldr pc,add_handler_04
ldr pc,add_handler_08
ldr pc,add_handler_0C
ldr pc,add_handler_10
ldr pc,add_handler_14
ldr pc,add_handler_18
ldr pc,add_handler_1C
add_handler_00: .word _start
add_handler_04: .word handler_04
add_handler_08: .word handler_08
add_handler_0C: .word handler_0C
add_handler_10: .word handler_10
add_handler_14: .word handler_14
add_handler_18: .word handler_18
add_handler_1C: .word handler_1C
// Low-level vector table handlers
.macro vec_handler num
handler_\num:
mov r0,#0x\num
ldr r3,=exception_handler
bx r3
.endm
vec_handler 04
vec_handler 08
vec_handler 0C
vec_handler 10
vec_handler 14
vec_handler 18
vec_handler 1C
进一步,当启动代码会跳转到kernel_main
// Call kernel_main
ldr r3, =kernel_main
main 函数会像这样调用 vector table 设置:
extern uint32_t vec_table;
void install_vector_table()
{
asm volatile("mcr p15, 0, %[r], c12, c0, 0": :[r]"r" (&vec_table):);
}
当我测试此异常是否真的发生时,我注意到如果我在 boot.S 文件的开头添加一些 .word 块,异常逻辑将停止工作。例如,如果我移动此数据
und_stack: .word 0xc0026000
dab_stack: .word 0xc0028000
svc_stack: .word 0xc0032000
从文件末尾到开头异常停止工作。我的意思是 - 例如,它没有调用数据中止异常处理程序,而是不断旋转以重置。
我的发现:
看起来像是对齐或绝对寻址问题,当我向开头添加更多数据时出现故障。当我添加两个词时,它看起来如下所示:
periph_base: .word 0x3f200000
virtual_base: .word 0xc0000000
und_stack: .word 0xc0026000
dab_stack: .word 0xc0028000
它工作正常,如果我再添加一个词 - 它就会崩溃。我以异常调用的方式分析了每个跳转的 objdump 地址,我发现它们在坏情况和好情况下没有关键区别。谁能告诉我这是什么?
It looks like alignment or absolute addressing issue
是。
您的向量 table 是 16 字节对齐的:
.align 4
.globl vec_table
vec_table:
但是架构要求它是 32 字节对齐的(即对齐到它的总大小)- 请注意,VBAR 的底部 5 位是保留的。
假设您的 16 字节对齐 table 在 0x12340010 处结束,VBAR 可能只会忽略位 0-4,取有效值 0x12340000,随后数据中止从该位置偏移 0x10地址确实会出现在您的重置处理程序中。
我的问题将基于 this code. 这是基于 arm 的板(rpi2)的启动代码。我最感兴趣的是与矢量 table 设置相关的部分。向量 table 如下所示:
// Vector table
.align 4
.globl vec_table
vec_table:
ldr pc,add_handler_00
ldr pc,add_handler_04
ldr pc,add_handler_08
ldr pc,add_handler_0C
ldr pc,add_handler_10
ldr pc,add_handler_14
ldr pc,add_handler_18
ldr pc,add_handler_1C
add_handler_00: .word _start
add_handler_04: .word handler_04
add_handler_08: .word handler_08
add_handler_0C: .word handler_0C
add_handler_10: .word handler_10
add_handler_14: .word handler_14
add_handler_18: .word handler_18
add_handler_1C: .word handler_1C
// Low-level vector table handlers
.macro vec_handler num
handler_\num:
mov r0,#0x\num
ldr r3,=exception_handler
bx r3
.endm
vec_handler 04
vec_handler 08
vec_handler 0C
vec_handler 10
vec_handler 14
vec_handler 18
vec_handler 1C
进一步,当启动代码会跳转到kernel_main
// Call kernel_main
ldr r3, =kernel_main
main 函数会像这样调用 vector table 设置:
extern uint32_t vec_table;
void install_vector_table()
{
asm volatile("mcr p15, 0, %[r], c12, c0, 0": :[r]"r" (&vec_table):);
}
当我测试此异常是否真的发生时,我注意到如果我在 boot.S 文件的开头添加一些 .word 块,异常逻辑将停止工作。例如,如果我移动此数据
und_stack: .word 0xc0026000
dab_stack: .word 0xc0028000
svc_stack: .word 0xc0032000
从文件末尾到开头异常停止工作。我的意思是 - 例如,它没有调用数据中止异常处理程序,而是不断旋转以重置。
我的发现:
看起来像是对齐或绝对寻址问题,当我向开头添加更多数据时出现故障。当我添加两个词时,它看起来如下所示:
periph_base: .word 0x3f200000
virtual_base: .word 0xc0000000
und_stack: .word 0xc0026000
dab_stack: .word 0xc0028000
它工作正常,如果我再添加一个词 - 它就会崩溃。我以异常调用的方式分析了每个跳转的 objdump 地址,我发现它们在坏情况和好情况下没有关键区别。谁能告诉我这是什么?
It looks like alignment or absolute addressing issue
是。
您的向量 table 是 16 字节对齐的:
.align 4
.globl vec_table
vec_table:
但是架构要求它是 32 字节对齐的(即对齐到它的总大小)- 请注意,VBAR 的底部 5 位是保留的。
假设您的 16 字节对齐 table 在 0x12340010 处结束,VBAR 可能只会忽略位 0-4,取有效值 0x12340000,随后数据中止从该位置偏移 0x10地址确实会出现在您的重置处理程序中。