I'm very confused with the difference between Bootloader and Startup code used in microcontrollers(Like AVR atmega) and I have some questions that need to be answered :
Can I use both in the same time or when I use one I can't use the other ?
Which one should run first upon restarting the AVR?
Which one is written in assembly and which one is written in C ?
Can bootloader do startup code functionality? like(copying any initialized data from ROM to RAM,initializing the processor’s stack pointer,calling main, ...etc).
Which one is "built-in" in the AVR and which one should I develop?
Thanks in advance !
I think you are talking about bootstrap not bootloader. A C bootstrap does want to be written in assembly otherwise you have a chicken and egg problem. You can write some of it in C but that C code cant completely conform to the standard (cant assume that variables in bss are zero nor pre-initialized variables are initialized if that C code is doing both of those things).
Needing to bootstrap a high level language has nothing to do with microcontrollers or a specific instruction set, it is required globally. A high level language, even C, has certain assumptions (the stack pointer has been setup, global variables that are defined with an initial value are that value, and others are zero, any C library preparation (heap location)) are all done before main() or whatever the entry point into C is. Same is true for other languages.
This is why the bootstrap is usually in asm as it has none of these rules and it has access to things like the stack pointer that the high level languages dont have.
If you are willing to forgo some language compatibility the bootstrap can be simpler. With the arm cortex-m's the hardware provides a solution for initializing the stack pointer without code, and launching into C if you want it to for the entry point, but you dont get the global variable initialization if you do that, so if willing to forgo that then you only need a way to define the vector table (asm directives is by far the easiest since the tools are all there).
Now maybe what you are calling startup code I am calling bootstrap.
A bootloader is a program written in whatever language you like, that brings up the chip or system. It may turn clocks on or bring up ddr or wipe memory to enable ecc, whatever you need. And then launch the main application (written in whatever language, each of these things the bootloader and the main application has startup code per the language rules as mentioned above as bootstrap the term I use). that is the boot part of bootloader. The loader part implies that someone could interrupt the boot process from starting the application allowing a developer to in some way experiment with a different application either overwriting the application in non volatile ram or loading into ram the application and running it instead of the normal boot path.
Some bootloaders are designed in parts, so that you can update the bootloader with the bootloader, for example your bootloader could be designed so that it copies itself to ram before doing anything else, then if you want to modify the bootloader itself you can, using the bootloader overwrite the flash, hoping not to brick yourself. You can also put some protections against that like having two bootloaders, the first one has code that checks itself if corrupt or if you have a strap or whatever it launches the secondary, the secondary can be used to overwrite the primary the primary can overwrite the secondary. you still have a chicken and egg problem with the wee bit of code up front that checks the strap or does a checksum before launching into the rest of the code. you break that and you are still bricked.
chips like the AVR have hardware ways to recover from being bricked, and also have hardware protected bootloaders, sometimes factory programmed before you get the chip from which you can use a strap or hit a key or whatever to launch and re-load your application.