For bootloaders, the first line of code to be executed has to be written in assembly. The correspondent file name is usually called start.s(or crt0.s). start.s is the first program to run after power up. It does some initialization, then jumps to your main function in C language. In the lingo of C language, start.s is called run time library.
The C run time library has to be written in assembly language, and takes the name like crt0.s or start.s. As its name implies, it needs to set up the run time environment before the code in main() function can be executed (That is why it can not be written in C!), which includes:
(1) Initialize the hardware, such as CPU cache and MMU, if necessary
(2) Setup the Stack
(3) Initialize the .bss section to all zero in the memory
(4) Calling the main() function
For application developers, the compiler would provide a default run time library during link stage, which is good enough in most cases. However, for programs like the bootloader, the developer has to provide its own run time library in order to set up the environment correctly. It will be the first code to run after power reset.