ARM start address - arm

Hi I’m newbie to ARM and am using a SAM3S4A ARM processor, with the IAR compiler.
Understanding that the flash code is from 0x00400000 – 0x0043FFFF and that the processor start at address zero (0x00000000), how does the PC jump to 0x00400000 as the VTOR register is zero at default.

From what I could understand from the document, ARM proc goes to 0x0 on reset. The 4K address space at 0x00000000 can be mapped to either ROM or FLASH using GPNVM register. So at reset ARM starts executing code either from ROM or FLASH. (ROM contains some proprietary bootloader and you can have your own OS/Bootloader at Flash). Once control reaches the code you have written to flash, you can setup a new Vector Table and update VTOR so that new exceptions are routed there.

Related

CodeViser JTag Debugger: how it knows u-boot's relocated offset in RAM?

I am currently using CodeViser Jtag debugger connecting to a FPGA for debugging firmware for an Armv8 processor. From within the CodeViser GUI client (called CVD64 on windows) I can set break points at absolute addresses.
One thing I noticed that, when I set a break point at some functions in u-boot, I use the address as shown in u-boot.map, which reflects the initial loading address of u-boot. In my case, the u-boot text section is initially loaded to 0x20408000.
When the break point I set hits, the actual address the PC stops is not what I specified from GUI, but another address, which is the relocated one (i.e., after u-boot relocation).
For example, I set break point from GUI at 0x20413040, and CVD64 stops at 0x207ae040, the offset is 0x39b000. This offset is exactly the same as u-boot itself printed to serial port:
Relocation Offset is: 0039b000
Relocating to 207a3000, new gd at 2075edf0, sp at 2075ede0
This is nice. I am just wondering how CVD64 knows the relocate offset and automatically place HLT instruction in relocated address?
Thanks!

Behaviour of VTOR register on STM32H7 at reset

The Vector Table offset register on a Cortex M7 allows to relocate the Vector Table.
I am wondering how the Vector Table is managed when it is relocated and a soft reset occurs.
The ARM programming manual mentions that the value of VTOR after reset is "unknown".
What reset handler is used after a soft reset: the "original" one from the vector table in Flash ? Or the "relocated" one set through VTOR ?
Same question for the Stack Pointer. The Programming manual states that "On reset, the processor loads the MSP with the value from address 0x00000000". Does that mean that the Stack Pointer in a relocated Vector Table is never used ?
Does that mean that the Stack Pointer in a relocated Vector Table is
never used ?
It is not used by the hardware. It is used by bootloader when launching the application.
What reset handler is used after a soft reset: the "original" one from
the vector table in Flash
The one selected by the boot pins & boot option bytes.
The ARM programming manual mentions that the value of VTOR after reset
is "unknown".
I do not think so, my programming manual shows:
Which is quite well defined :)
I am wondering how the Vector Table is managed when it is relocated
and a soft reset occurs.
Same as during the hardware reset.

Atmel SAM3X dual bank switching not working

I'm currently working with an Atmel SAM3X8 ARM microcontroller that features a dual banked 2 x 256KB flash memory. I'm trying to implement a firmware update feature, that puts the new firmware into the currently unused flash bank, and when done swaps the banks using the flash remapping to run the new firmware.
The datasheet states to do so I need to set the GPNVM2 bit, then the MCU will remap the memory, so Flash 1 is now at 0x80000 and Flash 0 at 0xC0000. This will also lead to the MCU executing code beginning from Flash 1.
To cite the datasheet:
The GPNVM2 is used only to swap the Flash 0 and Flash 1. If GPNVM2 is ENABLE, the Flash 1 is mapped at
address 0x0008_0000 (Flash 1 and Flash 0 are continuous). If GPNVM2 is DISABLE, the Flash 0 is mapped at
address 0x0008_0000 (Flash 0 and Flash 1 are continuous).
[...]
GPNVM2 enables to select if Flash 0 or Flash 1 is used for the boot.
Setting GPNVM bit 2 selects the boot from Flash 1, clearing it selects the boot from Flash 0.
But when I set GPNVM2, either via SAM-BA or my own firmware using flash_set_gpnvm(2) (ASF SAM Flash Service API), it will still boot from the program in Flash 0, and the new program will still reside at Flash 1's offset 0xC0000. The state of GPNVM2 has been verified by flash_is_gpnvm_set(2)
Flashing the firmware itself to Flash1 bank works flawlessly, that has been verified by dumping the whole flash memory with SAM-BA.
There is an errata from Atmel about an issue, that the flash remapping only works for portions smaller than 64KB. My code is less than that (40KB), so this shouldn't be an issue.
I've not found any other people having this issue, nor any example how to use it, so maybe somebody could tell me if I'm doing something wrong here, or what else to check.
I had the same issue (see here: Atmel SAM3X8E dual bank switching for booting different behaviour).
After some more research I found an Application Note (Link: http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42141-SAM-AT02333-Safe-and-Secure-Bootloader-Implementation-for-SAM3-4_Application-Note.pdf) which explains the boot behaviour of the SAM3X in a more clear way. The problem is that the datasheet is a bit misleading (at least I was confused too). The SAM3X has no ability to remap the the Flash banks. The booting behaviour is a bit different (see the picture in the link, it's a snipped from the Application note, page 33/34):
Booting behaviour SAM3X
Picture 3-9 shows the SAM3X's behaviour at the boot-up. The GPNVM bits 1 and 2 just determine which memory section (ROM/Flash0/Flash1) is mirrored to the boot memory (located at 0x00000000). The mapping of the Flash banks is not changed. Therefore Flash0 still is mapped to 0x00080000 and Flash1 to 0x000C0000).
As the Application Note states some other Atmel microcontrollers are able to really remap the Flash banks (e.g. SAM3SD8 and SAM4SD32/16). These processors change the location of the Flash banks as you can see in picture 3-10.
To be able to update your firmware it is therefore necessary to implement some kind of bootloader. I implemented one by myself and was able to update my firmware even without using the GPNVM bits at all. I also opend a support ticket at Microchip to clarify the booting behaviour. When I receive an answer I hope to tell you more.
EDIT:
Here's the answer from the Microchip support:
Setting the GPNVM2 bit in SAM3X will merely make the CPU 'jump to' or start from flash bank 1 i.e. 0xC0000.
No actual swap of memory addresses will take place.
To use flash bank 1, you will need to change the linker file (flash.ld) to reflect the flash start address 0xC0000.
For flash bank 0 application, change:
rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K /
to:
rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00040000 / Flash, 256K */
For flash bank 1 application, change:
rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K /
to:
rom (rx) : ORIGIN = 0x000C0000, LENGTH = 0x00040000 / Flash, 256K */
If this is not done, the reset handler in the flash 1 application will point to an address in the flash 0 application.
So, although code will start execution in flash 1 (if GPNVM2 is set), it will jump back to the flash 0 application.
The errata stating the 64kb limitation can be ignored.
Therefore the Application Note is right and no actual change of the mmory mapping is performed.
Cheers
Lukas

Start to writing a bootloader for stm32l0 in IAR

What are the appropriate steps to write add a custom bootloader for stm32l0 in IAR? The following questions are not clear:
Do I make a new IAR Project?
If yes, do I write the bootloader like a normal project and just change my original .icf file so there is a small ROM and an small RAM region for the bootloader?
if no, what things do I have to configure in the IAR proejct apart from icf file and code?
what other things do I need to think of?
I'm having trouble starting into this.
So the icf would be for the main project:
__region_ROM_start__ = 0x08000000;
__region_ROM_end__ = 0x08008FFF;
So the icf would be for the bootloader project:
__region_Bootloader_ROM_start__ = 0x08009000;
__region_Bootloader_ROM_end__ = 0x08009FFF;
and the same thing for about 0xFF of RAM?
You do not need to restrict the RAM - you can use all of it because when you switch to the application a new run-time environment will be established and the RAM will be reused.
The flash you reserve for the bootloader must be a whole number of flash pages starting from the reset address The STM32L0 has very small flash pages so there should be minimal waste, but you don't want to have to change it if your bootloader grows, because then you will have to rebuild your application code for the new start address and old application images will no longer be loadable. So consider giving yourself a little headroom.
The bootloader can be built just like any other STM32L0xx project; the application code ROM configuration must start from an address above the bootloader. So for example say you have a 1Kbyte bootloader:
Boot ROM Start: 0x0800 0000
Boot ROM End: 0x0800 03FF
Application Start: 0x0800 0400
Application End: Part size dependent.
The bootloader itself must have a means of determining that an update is available, if an update is available it must then read the application data and write it to the application flash memory, it must then disable any interrupts that may have been enabled, it may also be necessary to deinitialise any peripherals used (if they remain active when the switch to the application is made it may cause problems), then the switch to the application code is made.
It is possible if the bootloader and application both run from the same clock configuration to minimise the configuration in the application and rely on the bootloader. This is a small space saving, but less flexible. If for example you make the bootloader run using the internal RC oscillator it will be portable across multiple hardware designs that may have differing application speed and clocking requirements and different external oscillator frequencies
The switch to the application is pretty simple on Cortex-M, it simply requires the vector table to be switched to the application's vector table, then the program-counter to be loaded - the latter requires a little assembly code. The following is for Cortex-M3, it may need some adaptation for M0+ but possibly not:
Given the following in-line assembly function:
__asm void boot_jump( uint32_t address )
{
LDR SP, [R0] ;Load new stack pointer address
LDR PC, [R0, #4] ;Load new program counter address
}
The bootloader switched to the application image thus:
// Switch off core clock before switching vector table
SysTick->CTRL = 0 ;
// Switch off any other enabled interrupts too
...
// Switch vector table
SCB->VTOR = APPLICATION_START_ADDR ;
//Jump to start address
boot_jump( APPLICATION_START_ADDR ) ;
Where APPLICATION_START_ADDR is the base address of the application area; this address is the start of the application's vector table, which starts with the initial stack pointer and reset vector, the boot_jump() function loads these into the SP and PC registers to start the application as if it had been started at reset. The application's reset vector contains the application's execution start address.
Your needs may vary, but in my experience a serial bootloader (using UART) using XMODEM and decoding an image in Intel Hex format takes about 4Kb of Flash. On an STM32L0 you may want to use something simpler - 1Kb is probably feasible if you simply stream raw binary the data and use hardware flow control (you need to control data flow because erasing and programming the flash takes time and also stops the CPU from running because you cannot on STM32 write flash memory while simultaneously fetching instructions from it).
See also: How to jump between programs in Stellaris

Micron NAND (MT29F2G08ABAEAWP): Cannot successfully flash first block (address 0x0)

We are trying to get our Micron NAND flash chip (MT29F2G08ABAEAWP) working. We are using u-boot as bootloader and our main processor is a TI DM8148. For evaluation we are using this evaluation module.
Now, the flash itself gets recognized by u-boot as 8-bit 2Gb NAND (which is correct). I'm able to flash 1st stage u-boot to 0x0 using the following uboot commands:
// select BCH8 as HW ECC
nandecc hw 2
// erase the first block
nand erase 0x0 0x20000
// write the content from RAM address 0x81000000 to the
// first flash block (0x0)
nand write.i 0x81000000 0x0 0x20000
However, when I try to read from that address using
nand read.i 0x81000000 0x0 0x20000
I get a lot of ECC: Uncorrectable errors. Choosing another ECC algorithm doesn't help. Booting from NAND (via ROM boot) doesn't work.
Any ideas?
Update:
Writing and reading every other block works like charm. Just the first one (Block 0) has those issues.
I know that issue is very specific. But I'm hoping that someone else might have had the same problems.
Thanks and greeting,
SamuelTee

Resources