皮质 M33 缺失向量 table
Cortex M33 missing vector table
我想使用半主机在 QEMU 中测试我的 ARM 项目。最初我为 Cortex A7 和 A9 处理器构建并且没有问题 运行 我的代码,但是现在我切换到 CM33(和 CM33 板),它立即中断:
C:\Program Files\qemu>qemu-system-aarch64.exe -nographic -machine musca-a -cpu cortex-m33 -monitor none -serial stdio
-kernel app -m 512 -semihosting
qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)
R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=ffffffe0 R14=fffffff9 R15=00000000
XPSR=40000003 -Z-- A S handler
FPSCR: 00000000
如果我理解正确,PC=00000000
表示重置处理程序问题。我想也许这个 musca-a
板希望 table 在别的地方,但看起来它完全不见了:
psykana@psykana-lap:~$ readelf app -S
There are 26 section headers, starting at offset 0xb1520:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .init PROGBITS 00008000 008000 00000c 00 AX 0 0 4
[ 2] .text PROGBITS 00008010 008010 01d5b4 00 AX 0 0 8
[ 3] .fini PROGBITS 000255c4 0255c4 00000c 00 AX 0 0 4
[ 4] .rodata PROGBITS 000255d0 0255d0 003448 00 A 0 0 8
[ 5] .ARM.exidx ARM_EXIDX 00028a18 028a18 000008 00 AL 2 0 4
[ 6] .eh_frame PROGBITS 00028a20 028a20 000004 00 A 0 0 4
[ 7] .init_array INIT_ARRAY 00038a24 028a24 000008 04 WA 0 0 4
[ 8] .fini_array FINI_ARRAY 00038a2c 028a2c 000004 04 WA 0 0 4
[ 9] .data PROGBITS 00038a30 028a30 000ad8 00 WA 0 0 8
[10] .persistent PROGBITS 00039508 029508 000000 00 WA 0 0 1
[11] .bss NOBITS 00039508 029508 0001c4 00 WA 0 0 4
[12] .noinit NOBITS 000396cc 000000 000000 00 WA 0 0 1
[13] .comment PROGBITS 00000000 029508 000049 01 MS 0 0 1
[14] .debug_aranges PROGBITS 00000000 029551 000408 00 0 0 1
[15] .debug_info PROGBITS 00000000 029959 02e397 00 0 0 1
[16] .debug_abbrev PROGBITS 00000000 057cf0 005b3e 00 0 0 1
[17] .debug_line PROGBITS 00000000 05d82e 01629f 00 0 0 1
[18] .debug_frame PROGBITS 00000000 073ad0 004bf4 00 0 0 4
[19] .debug_str PROGBITS 00000000 0786c4 006a87 01 MS 0 0 1
[20] .debug_loc PROGBITS 00000000 07f14b 01f27e 00 0 0 1
[21] .debug_ranges PROGBITS 00000000 09e3c9 009838 00 0 0 1
[22] .ARM.attributes ARM_ATTRIBUTES 00000000 0a7c01 000036 00 0 0 1
[23] .symtab SYMTAB 00000000 0a7c38 006ec0 10 24 1282 4
[24] .strtab STRTAB 00000000 0aeaf8 002927 00 0 0 1
[25] .shstrtab STRTAB 00000000 0b141f 000100 00 0 0 1
我正在使用以下选项构建(来自 的修改工具链文件):
add_compile_options(
-mcpu=cortex-m33
-specs=rdimon.specs
-O0
-g
-mfpu=fpv5-sp-d16
-mfloat-abi=hard
)
add_link_options(-specs=rdimon.specs -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard)
再次强调,这对我尝试过的所有 A 处理器都运行良好,但对 CM33 来说就不行了。事实上,它对任何 M 核和 M 核 QEMU 板都是坏的。
备案:
- arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10)
- QEMU emulator version 7.0.0 (v7.0.0-11902-g1d935f4a02-dirty)
- Microsoft Windows [Version 10.0.19044.1645]
- cmake version 3.22.
您的来宾代码在启动时崩溃,这几乎总是因为您的异常向量问题 table。如果你使用 QEMU 的 -d 选项(例如 -d cpu,int,guest_errors,unimp,in_asm),这通常会提供更多关于究竟发生了什么的细节。
查看您的 ELF headers,您似乎没有将矢量 table 放入二进制文件中。 QEMU 需要这个(真正的硬件也是如此)。通常的方法是使用一个小的汇编源文件来布置数据 table 以及各种异常入口点的地址,尽管还有其他方法可以做到这一点。 (This is one example.)
你在 A-profile CPUs 上看不到这个的原因是 A-profile 异常处理是完全不同的:在 A-profile 上重置从地址 0x0 开始执行, 并且通过将 PC 设置为固定的低地址来采取类似的例外。在 M-profile 上,重置通过从向量 table 读取初始 PC 和 SP 值来工作,异常处理程序的起始地址也从向量 table 读取。 (也就是说,在 A-profile 上,魔术低地址是代码,而在 M-profile 上,它是数据,有效的函数指针)。
另请注意 QEMU -kernel 选项的行为在 A-profile 和 M-profile 之间是不同的:在 A-profile 上它会将 ELF 文件加载到内存中并接受 ELF 条目点(执行将从那里开始)。在 M-profile 上,它将加载 ELF 文件,然后以 hardware-specified 方式从重置开始 CPU,即不将 PC 设置为 ELF 入口点。 (这种变化主要是出于 historical/back-compat 原因。)如果你想“只加载我的 ELF 文件并将 PC 设置为其 ELF 入口点”,你应该使用 QEMU 的通用加载器设备,它在所有目标上的行为方式相同,并且not -kernel,这通常意味着“我是一个 Linux 内核,请将我加载到任何随机 target-specific 加上 do-what-I-mean 行为的最佳组合”。如果您尝试加载 bare-metal 二进制文件而不是实际的 Linux 内核,通常最好避免使用 -kernel。
This similar question about getting a working M-profile binary running on QEMU 也可能有帮助。
我想使用半主机在 QEMU 中测试我的 ARM 项目。最初我为 Cortex A7 和 A9 处理器构建并且没有问题 运行 我的代码,但是现在我切换到 CM33(和 CM33 板),它立即中断:
C:\Program Files\qemu>qemu-system-aarch64.exe -nographic -machine musca-a -cpu cortex-m33 -monitor none -serial stdio
-kernel app -m 512 -semihosting
qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)
R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=ffffffe0 R14=fffffff9 R15=00000000
XPSR=40000003 -Z-- A S handler
FPSCR: 00000000
如果我理解正确,PC=00000000
表示重置处理程序问题。我想也许这个 musca-a
板希望 table 在别的地方,但看起来它完全不见了:
psykana@psykana-lap:~$ readelf app -S
There are 26 section headers, starting at offset 0xb1520:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .init PROGBITS 00008000 008000 00000c 00 AX 0 0 4
[ 2] .text PROGBITS 00008010 008010 01d5b4 00 AX 0 0 8
[ 3] .fini PROGBITS 000255c4 0255c4 00000c 00 AX 0 0 4
[ 4] .rodata PROGBITS 000255d0 0255d0 003448 00 A 0 0 8
[ 5] .ARM.exidx ARM_EXIDX 00028a18 028a18 000008 00 AL 2 0 4
[ 6] .eh_frame PROGBITS 00028a20 028a20 000004 00 A 0 0 4
[ 7] .init_array INIT_ARRAY 00038a24 028a24 000008 04 WA 0 0 4
[ 8] .fini_array FINI_ARRAY 00038a2c 028a2c 000004 04 WA 0 0 4
[ 9] .data PROGBITS 00038a30 028a30 000ad8 00 WA 0 0 8
[10] .persistent PROGBITS 00039508 029508 000000 00 WA 0 0 1
[11] .bss NOBITS 00039508 029508 0001c4 00 WA 0 0 4
[12] .noinit NOBITS 000396cc 000000 000000 00 WA 0 0 1
[13] .comment PROGBITS 00000000 029508 000049 01 MS 0 0 1
[14] .debug_aranges PROGBITS 00000000 029551 000408 00 0 0 1
[15] .debug_info PROGBITS 00000000 029959 02e397 00 0 0 1
[16] .debug_abbrev PROGBITS 00000000 057cf0 005b3e 00 0 0 1
[17] .debug_line PROGBITS 00000000 05d82e 01629f 00 0 0 1
[18] .debug_frame PROGBITS 00000000 073ad0 004bf4 00 0 0 4
[19] .debug_str PROGBITS 00000000 0786c4 006a87 01 MS 0 0 1
[20] .debug_loc PROGBITS 00000000 07f14b 01f27e 00 0 0 1
[21] .debug_ranges PROGBITS 00000000 09e3c9 009838 00 0 0 1
[22] .ARM.attributes ARM_ATTRIBUTES 00000000 0a7c01 000036 00 0 0 1
[23] .symtab SYMTAB 00000000 0a7c38 006ec0 10 24 1282 4
[24] .strtab STRTAB 00000000 0aeaf8 002927 00 0 0 1
[25] .shstrtab STRTAB 00000000 0b141f 000100 00 0 0 1
我正在使用以下选项构建(来自
add_compile_options(
-mcpu=cortex-m33
-specs=rdimon.specs
-O0
-g
-mfpu=fpv5-sp-d16
-mfloat-abi=hard
)
add_link_options(-specs=rdimon.specs -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard)
再次强调,这对我尝试过的所有 A 处理器都运行良好,但对 CM33 来说就不行了。事实上,它对任何 M 核和 M 核 QEMU 板都是坏的。
备案:
- arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10)
- QEMU emulator version 7.0.0 (v7.0.0-11902-g1d935f4a02-dirty)
- Microsoft Windows [Version 10.0.19044.1645]
- cmake version 3.22.
您的来宾代码在启动时崩溃,这几乎总是因为您的异常向量问题 table。如果你使用 QEMU 的 -d 选项(例如 -d cpu,int,guest_errors,unimp,in_asm),这通常会提供更多关于究竟发生了什么的细节。
查看您的 ELF headers,您似乎没有将矢量 table 放入二进制文件中。 QEMU 需要这个(真正的硬件也是如此)。通常的方法是使用一个小的汇编源文件来布置数据 table 以及各种异常入口点的地址,尽管还有其他方法可以做到这一点。 (This is one example.)
你在 A-profile CPUs 上看不到这个的原因是 A-profile 异常处理是完全不同的:在 A-profile 上重置从地址 0x0 开始执行, 并且通过将 PC 设置为固定的低地址来采取类似的例外。在 M-profile 上,重置通过从向量 table 读取初始 PC 和 SP 值来工作,异常处理程序的起始地址也从向量 table 读取。 (也就是说,在 A-profile 上,魔术低地址是代码,而在 M-profile 上,它是数据,有效的函数指针)。
另请注意 QEMU -kernel 选项的行为在 A-profile 和 M-profile 之间是不同的:在 A-profile 上它会将 ELF 文件加载到内存中并接受 ELF 条目点(执行将从那里开始)。在 M-profile 上,它将加载 ELF 文件,然后以 hardware-specified 方式从重置开始 CPU,即不将 PC 设置为 ELF 入口点。 (这种变化主要是出于 historical/back-compat 原因。)如果你想“只加载我的 ELF 文件并将 PC 设置为其 ELF 入口点”,你应该使用 QEMU 的通用加载器设备,它在所有目标上的行为方式相同,并且not -kernel,这通常意味着“我是一个 Linux 内核,请将我加载到任何随机 target-specific 加上 do-what-I-mean 行为的最佳组合”。如果您尝试加载 bare-metal 二进制文件而不是实际的 Linux 内核,通常最好避免使用 -kernel。
This similar question about getting a working M-profile binary running on QEMU 也可能有帮助。