One of the most overlooked processes in embedded software development is the microcontroller boot process. The reason for this is that silicon toolchains have become very good at providing and abstracting out the boot process so that developers generally don’t think about it. Unfortunately this can lead to a lack of understanding how the microcontroller start-ups, initializes itself and eventually finds its way to the all too familiar main function. This article will explore the boot process and elucidate what is happening behind the scenes.
The microcontroller boot process starts by simply applying power to the system. Once the voltage rails stabilize, the microcontroller looks to the reset vector for the location in flash where the start-up instruction can be found. The reset vector is a special location within the flash memory map. For example, taking a look at Figure 1, it can be seen that at address 0x0002 is where the reset vector is located within the memory map.
Figure 1 – Reset Vector Location
The address that is stored at the reset vector is loaded by the microcontroller and the instructions that are contained there are then loaded and executed by the CPU. Now these first instructions aren’t the start of main that the developer created. Instead, these are instructions on how to start-up the microcontroller.
The first thing that usually occurs is that the vector tables that are stored in flash are copied to RAM. They are copied from and to the location that is specified in the linker file at the time the executable program is created. One reason for copying the vector tables to RAM is that it is faster to execute from RAM than flash. This helps to decrease the latency of any interrupt calls within the system. Depending on the particular architecture of the microcontroller there may then be an instruction to update a vector table register so that the microcontroller knows where the start of the RAM table is.
Next the initialized data sections are copied into RAM. This is usually variables that are stored in the .data section of the linker. Examples of initialized data would be static, global and static local variables that have been provided with an initialization value during compile time. These are explicit definitions such as int Var = 0x32;.
Following the copy of the data section, the .bss section is also copied. The .bss section contains variables that are not initialized explicitly or that have been initialized to a value of zero. A simple example is that the variable static int Var; would be contained within this section.
Finally, the microcontroller will copy any RAM functions from flash to RAM. Once again it is sometimes worthwhile to execute certain functions out of RAM rather than flash due to the execution speed being slightly faster. These are functions usually decided upon by the developer and purposely placed there in the linker file prior to compiling the program.
This entire process is often known as the “C Copy Down”. Without performing this copy down the C environment would not be properly setup in order to execute the program. Usually once the copy down has been completed the microcontroller then jumps to the start of main where the developers application then begins.
The microcontroller boot process is actually relatively straight forward. Often times though it is written in assembly language or some other obscure and sparsely documented way so that it is difficult to get a clear understanding of how the microcontroller actually gets to main. Instead it looks like a very complex and nearly unknowable process which then makes custom development of boot code a potentially painful process.
please explain in detailed form on how the microcontroller starts-up on its own
Very good explanation of booting process.
Thanks for the information.
Your blog is really helpful for everyone in embedded domain, specially for freshers. I really appreciate your efforts for carrying out this brilliant job.
Thank You Very Much!!
Thanks! I’m glad you are finding the blogs useful!
I have a question:
I have seen some startup codes and I see that contents of CPU registers are copied into the whole RAM section being used. This process is referred as initializing the RAM. After that the ROM to RAM copy is done.
If this process is not done then the MCU gets an exception. Could you please explain this?
The ROM to RAM copy is often referred to as the C copy down. I have not seen an MCU exception that is caused by skipping this copy down although I have never purposely removed it. Usually this is done automatically in the start-up code but I have seen cases where the developer had to add the start-up code themselves. Several years ago I saw this on a C2000 part but the code ran just not properly. No exception. What processor are you using?
Your information is fully based on how boot process working on microcontroller. i really appreciate your effort for post this information thanks for sharing useful content
How much time it would take/ what are different steps between power on to execute first instruction for microcontroller?Is it only voltage rails stabilize ? Normally how much time it would take to stabilize voltage rail ?
This article mentions only one state ment as follows .
The microcontroller boot process starts by simply applying power to the system. Once the voltage rails stabilize, the microcontroller looks to the reset vector for the location in flash where the start-up instruction can be found.
The time it takes to stabilize is going to be in your microcontroller datasheet. It will vary from one controller to the next.
THanks for the question.
Your effort is appreciated. This is the best concise article about the booting process.
I really appreciate this article.
It is neat and clean; and can make anyone understand the booting process, very easily.
I would like to know further about this process, if you can help.
1. Is it possible for us to change the address stored in ‘Reset Vector’? How ?
2. As in most cases, after executing ‘reset vector’, program counter jumps to a address from where ‘C copy down’ process needs to be started (boot-loader code, in my understanding). If so, why this code isn’t written from the address just after ‘reset vector’?
Thanks for the question.
1) Yes. You can look at your start-up code and make the change. You can also use #pragma or create a const variable that uses that location.
2) The toolchain will decide where to place the copy down and other code. It may be located right next to the reset vector but it also may not be.
nice way of sharing this information is appreciated. Great work. Expecting more like this.
In which memory section vector tables are stored? i.e. stack,heap,data,bss,text?
It depends on how your microcontroller is configured. The vector tables will NOT be in the stack, heap or bss sections.
If your vector tables will reside in flash, i.e. execute out of flash, then they would be in the text section.
If your vector tables will reside in RAM, usually how they are to eliminate wait times and so forth, then they would be in the data section.
Thanks for the question!
Thanks for sharing this. However, I have a doubt. Even if the data section is copied into RAM from FLASH, the compiled program will still try to access the data from the original FLASH location right! How does it know that the data is now in RAM?
Thanks in advance,
Thanks for the comment. This is indeed how it works.
The linker file decides where these things will exist in RAM and the C copy down puts them in those locations during the copy down.
Some parts will also have vector location registers to tell the processor where the interrupt tables live. However, that’s different than just the standard RAM variables, etc.
A very neat and straightforward explanation of Boot up sequence in Microcontroller.
I would like to further know more about the sequence.
1. When is built in self test done in the boot up sequence and where.
2. I want to write a power on self test code for checking the state of RAM , peripherals(ADC and DAC) .
Thanks and Regards ,
Thanks for explanation really good effort.
Got clear picture of boot process. Thank you:)
Copy of .bss section from flash to RAM is not required. Its a bunch of zeros and wasting the flash space. Instead the startup routime knows the start of .bss section address, and the program can initialize it as part of startup.
Thank you very much for the useful information. I faced a problem with a Renasas RH850 MCU; using the VVDI Prog, I could read and save both data- flash and P-flash, but unfortunately I lost the so called “Boot” file which I found empty when I read it after making “Sector set” and “Sector Reset” to erase the chip. Would this make a problem to the normal function of the Airbag ECU, even after rewriting the data falsh and p-flash? should I look for a similar ECU to get this Boot file from the flash memory? any advice?
Thanks in advance
Thanks for the question.
Unfortunately, I’m not familiar with that specific part so I’m not sure how their boot sequence works. It’s possible the “boot” file was custom, or it could be part of the toolchain-generated code. The best advice I can give is to review your revision control system to see what was in the file before the changes. You could also review a new baseline project and see what code is generated.
I suspect though that the code may be custom and the VCS is your best bet. Good Luck!
This is really helpful
Thank you for this excellent explanation about the booting process of micro-controller.
Hoping to see more such blog posts.
it is very help full, thanks for the post,
i have on question does micro-controller have the os inside if it is what type of os is it, if not how does exception and interrupt will handle.
Thanks for the question.
If the MCU has an OS, usually an RTOS, it will depend on the RTOS as to whether the RTOS handles the interrupts or if they are handled outside the context of the RTOS. Many RTOSes like FreeRTOS, ThreadX, etc, just leave the interrupt handling to the developer to manage outside the RTOS.
Found the article to be really helpful. I just had 1 question. Would we still require a C COPY DOWN if the designate the data section into RAM itself using the linker.
something like :
.data : > RAM
Please let me know your thoughts.
Thanks for the comment. Yes, the C copy down is what initializes the RAM variables. So when the processor starts, the variables, objects, etc that you want stored in RAM with initialized values needs to copy from flash to RAM. If you review your start-up code, usually written in assembly, you’ll find the statements that perform this operation.