Copied from https://developer.arm.com/documentation/100748/0618/Embedded-Software-Development/Application-startup
Application startup
In most embedded systems, an initialization sequence executes to set up the system before the main task is executed.
The following figure shows the default initialization sequence.
Figure 1. Default initialization sequence

Default initialization sequence
__main is responsible for setting up the memory and __rt_entry is responsible for setting up the run-time environment.
__main performs code and data copying, decompression, and zero initialization of the ZI data. It then branches to __rt_entry to set up the stack and heap, initialize the library functions and static data, and call any top level C++ constructors. __rt_entry then branches to main(), the entry to your application. When the main application has finished executing, __rt_entry shuts down the library, then hands control back to the debugger.
The function label main() has a special significance. The presence of a main() function forces the linker to link in the initialization code in __main and __rt_entry. Without a function labeled main(), the initialization sequence is not linked in, and as a result, some standard C library functionality is not supported.