ARM Cortex-M3 boot from RAM initial state

爱⌒轻易说出口 提交于 2021-01-21 05:56:51

问题


I have two ARM Cortex-M3 chips: STMF103C8T6 and STM32F103VET6.

When set to boot from RAM, initial state of STMF103C8T6 PC register is 0x20000108; 0x200001e0 for STM32F103VET6.

I am unable to find and information about these addresses in the datasheets. Why are they booted this way and where I can find some information about it?

Edit:

To clarify. When chip set to boot from flash, PC register points to the location of the Reset Handler. This address is provided in the reset vector table at address 0x0. But when chip set to boot from RAM, PC points to constant addresses, mentioned above.

Edit 2:

STMF103C8T6 disassembly:

20000000 <Vectors>:
20000000:       20005000        andcs   r5, r0, r0
20000004:       2000010f        andcs   r0, r0, pc, lsl #2
20000008:       2000010d        andcs   r0, r0, sp, lsl #2
2000000c:       2000010d        andcs   r0, r0, sp, lsl #2
20000010:       2000010d        andcs   r0, r0, sp, lsl #2
20000014:       2000010d        andcs   r0, r0, sp, lsl #2
20000018:       2000010d        andcs   r0, r0, sp, lsl #2
    ...
20000108:       f000 b801       b.w     2000010e <Reset_Handler>

2000010c <HardFault_Handler>:
2000010c:       e7fe            b.n     2000010c <HardFault_Handler>

2000010e <Reset_Handler>:
    ...

STM32F103VET6 disassembly:

20000000 <Vectors>:
20000000:       20005000        andcs   r5, r0, r0
20000004:       200001e7        andcs   r0, r0, r7, ror #3
20000008:       200001e5        andcs   r0, r0, r5, ror #3
2000000c:       200001e5        andcs   r0, r0, r5, ror #3
20000010:       200001e5        andcs   r0, r0, r5, ror #3
20000014:       200001e5        andcs   r0, r0, r5, ror #3
20000018:       200001e5        andcs   r0, r0, r5, ror #3
    ...
200001e0:       f000 b801       b.w     200001e6 <Reset_Handler>

200001e4 <HardFault_Handler>:
200001e4:       e7fe            b.n     200001e4 <HardFault_Handler>

200001e6 <Reset_Handler>:
    ...

回答1:


I am unable to find and information about these addresses in the datasheets. Why are they booted this way and where I can find some information about it?

As far as I am aware, there is no official documentation from ST that so much as mentions this behavior, let alone explains it in any detail. The STM32F1 family reference manual states vaguely in section 3.4 ("Boot Configuration") that:

Due to its fixed memory map, the code area starts from address 0x0000 0000 (accessed through the ICode/DCode buses) while the data area (SRAM) starts from address 0x2000 0000 (accessed through the system bus). The Cortex®-M3 CPU always fetches the reset vector on the ICode bus, which implies to have the boot space available only in the code area (typically, Flash memory). STM32F10xxx microcontrollers implement a special mechanism to be able to boot also from SRAM and not only from main Flash memory and System memory.

The only place these addresses and values are referenced at all is in some of their template startup files -- and even then, not all of them. The SPL startup files supplied for the ARM and IAR toolchains lack support for BootRAM; this functionality is only included in the startup files for the GCC and TrueSTUDIO toolchains.

Anyways. Here's my best analysis of the situation.

When a STM32F1 part is reset, the memory block starting at 0x00000000 is mapped based on the configuration of the BOOT pins. When it is set to boot from flash, that block is aliased to flash; when it is set to run from the bootloader, that block is aliased to a block of internal ROM (around or slightly below 0x1FFFF000). However, when it is set to boot from RAM, something very strange happens.

Instead of aliasing that memory block to SRAM, as you would expect, that memory block is aliased to a tiny (16 byte!) ROM. On a STM32F103C8 (medium density) part, this ROM has the contents:

20005000 20000109 20000004 20000004

This data is interpreted as a vector table:

  • The first word causes the stack pointer to be initialized to 0x20005000, which is at the top of RAM.

  • The second word is the reset vector, and is set to 0x20000108 (with the low bit set to enable Thumb mode). This address is in RAM as well, a few words beyond the end of the vector table, and it's where you're supposed to put the "magic" value 0xF108F85F. This is actually the instruction ldr.w pc, [pc, #-480], which loads the real reset vector from RAM and branches to it.

  • The third and fourth words are the NMI and hardfault vectors. They do not have the low bit set, so the processor will double-fault if either of these exceptions occurs while VTOR is still zero. Confusingly, the PC will be left pointing to the vector table in RAM.

The exact contents of this ROM vary slightly from part to part. For example, a F107 (connectivity line) has the ROM contents:

20005000 200001e1 20000004 20000004

which has the same initial SP, but a different initial PC. This is because this part has a larger vector table, and the medium-density address would be inside its vector table.

A full list of the locations and values used is:

  • Low/medium density: 0x0108 (value: 0xF108F85F)
  • Low/medium density value line: 0x01CC (value: 0xF1CCF85F)
    Note: ST's sample files give the same value as for low/medium density parts. I'm pretty sure this is wrong and have corrected it here, but I don't have any parts of this type to test with. I'd appreciate feedback to confirm if this works.
  • All others: 0x01E0 (value: 0xF1E0F85F)

Thankfully, this behavior seems to be largely unique to the F103/5/7 family. Newer parts use different methods to control booting which are much more consistent.



来源:https://stackoverflow.com/questions/50977529/arm-cortex-m3-boot-from-ram-initial-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!