Startup code
The code that runs between reset and main(), making sure C's assumptions about memory actually hold.
C promises that initialised globals hold their initial values and that everything else starts at zero. On a desktop, the OS loader arranges that. On bare metal nobody does, so the startup code has to: copy the .data section from flash into RAM, zero .bss, set up the clocks, run C++ constructors and finally call main. The addresses come from symbols defined in the linker script.
The name crt0, C runtime zero, comes from Unix. On Cortex-M the entry point is Reset_Handler, found via the vector table; the hardware loads the stack pointer itself, so the whole thing can be written in C. Vendors usually ship it as an assembly file that nobody reads until a global variable stubbornly refuses to hold its initial value.