0x00400000 70 0a 40 20 d9 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 00 00 00 00 p.@ Ù.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.....
0x00400020 00 00 00 00 00 00 00 00 00 00 00 00 d5 01 40 00 d5 01 40 00 00 00 00 00 d5 01 40 00 d5 01 40 00 ............Õ.@.Õ.@.....Õ.@.Õ.@.
0x00400040 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400060 d5 01 40 00 00 00 00 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 Õ.@.....Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400080 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
So these look fine the first one is the stack pointer load value
0x20400a70
A strange number perhaps but this part has 0x80000 bytes of ram so it is valid. so probably a linker script generated value (stack setup in the linker script rather than just start with top of ram).
Reset vector is
0x004001d9
which is properly formatted (lsbit is set) as to what it points to you have not provided.
many of the others are
0x004001d5
Also properly formatted is probably an infinite loop based on its proximity to the reset vector but who knows have to look at the code. It does not matter much for booting.
The chip/family doc indicates that user flash is at address 0x00400000 and is quite large for these parts, so both the address on the left of this dump and the reset vectors this all looks fine.
There is an indication that there is a sam-ba bootloader at some address 0x00800000 or 0x08000000 or I do not remember, you can look it up. Now I have used other Atmel parts that did not have the bootloader burned in the flash from Atmel but instead source to a sam-ba you could build and use yourself (why bother make your own much simpler less bulky), but I had issues with that approach how the flash did or didn't lock, how easy to unlock and erase, so what is the point? use SWD. This comment in the doc may indicate a burned in one in that case then you need to look at how to choose to boot that application instead of the user application, in either case since they indicate a specific address. If it is user changeable then that would be where you want to put your bootloader possibly or if fixed and not changeable then just use it as your bootloader.
As to where in general you put your bootloader that is all you, you choose your design, what you mean by bootloader, what features etc. Often misused but the term implies both booting the part but also having a way to load other applications in some way (run one in ram, reprogram the user/boot/application flash, etc). Something you need to look at is how the flash works on this device assuming you want to be able to re-write a portion of it with new firmware. Sometimes you can execute out of and flash at the same time but more likely to do that they use multiple flash banks so you can run in one and modify the other, which then leads into what is their boot scheme does it always only boot on one and never the other so you either have to keep the bootloader as-is forever or have a scheme, also have to have a scheme for choosing which of the images on which banks to be the default firmware after the bootloader boots.
These cores can run code in ram generally and no reason to expect not here (it's not the core, it's the chip vendor's implementation that matters) so doing a copy and jump of a portion of the bootloader to ram in order to not be running on flash allowing you to reprogram any of the flash but put yourself at risk if it fails or if power goes the part may be bricked.
If the chip vendor has not already done this with a factory bootloader and that factory loader being desirable for field use, it may use an I/O pin to determine which one boots, have to look at the docs. If you choose to do this yourself it is not unwise to have a gpio pin pick two boot paths, you can then have a very small, ideally bug free dozen or so lines of assembly that read the gpio pin and branch to a fixed point in flash that you choose Say 0x00500000 and 0x00600000 for example depending on how big you think your applications really will be. Then you can do a copy and jump into ram if the user desires loading the flash and then you can choose to load one or the other. The handful of lines of code could be a few dozen and do a checksum of some sort of the selected bank and the not selected if the selected is bad and did not complete. or a third bootloader that you provide in case the two do not checksum.
Tons of solutions, generally if you do not have separately banked flashes you need to branch to ram and have more freedom as to how to design your memory space (assuming the flash can be erased in pages). Otherwise you might want to just go with the banking solution from the chip vendor.
So all of this is documented in documents from arm and Atmel (microchip) that you should have had before starting work on this device. The only thing remotely related to arm in any of this is how the vector table works. All of the rest, the addresses, sizes, etc are all chip vendor implementation. So most of your reading is in the chip vendors docs, in this case they have the huge datasheet approach (rather than separate data sheet and reference manual approach).
You need to re-read what I found about sam-ba if you want to use that if it works for you, the nature of the flash implementation, is it in application programmable, etc. And then you design not only the functionality of your bootloader but the address space, whether it executes in flash or ram.
Edit
In case I did not understand the question.
The arm reset vector is at 0x00000004 not 0x00000000 (for the cortex-ms) and it is the address of the handler ORRED with one. Address 0x00000000 is the stack pointer initialization value, if you choose to init the stack pointer in code and not using this mechanism you can put whatever you want there.
If you want to change the reset handler address then you have to modify 0x00000004 which on some parts you can change without an erase (often flashes either work by erasing to all ones then you can write zeros, can't write ones but can changes ones to zeros on a per byte/word/chunk basis). So to change this you likely need to save it erase the block/page, change the bits you want and write back. You might for example be able to change it from 0x004001d9 to sah 0x004101d9 or to 0x004000d9, but not worth trying to do that. The value is the address of the handler ORRED with one.
It is not a branch as code is not executing at this point (normally/assumed) it is the logic reading that location and using that as the starting point, the first fetch not branch.
And as pointed out look at where the vector table is in the project and then modify that to point at your alternate reset handler. It might be code that looks like this
.word STACK_END
.word reset_handler
.word
in this case some fill/dummy vector for many of the rest. Just replace the reset_handler or whatever you find with your handler, remember this is a bootloader and you need to bootstrap C if you plan to call any C functions, worse if C++ or other language.
0x00000000just the reset vector, i.e. a pointer to the actual code that is executed on reset? - fuz0x004001d9might be the actually entry point code (actually, it's0x004001d8since it's thumb code). It does look plausible. - fuz0x20400a70is in RAM. So if I want to branch, I just have to update the vector table and update the stack pointer with the value0x20400a70and branch to0x004001d8, right ? - Antoine Boré