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.
Let's see the big picture first.
The following figure shows a possible initialization sequence fro an embedded system based on an ARM architecture:
The reset handler is normally a short module coded in assembler that executes immediately on system
startup. As a minimum, your reset handler initializes stack pointers for the modes that your application is
running in. For processors with local memory systems, such as caches, TCMs, MMUs, and MPUs, some
configuration must be done at this stage in the initialization process. After executing, the reset handler
typically branches to __main to begin the C library initialization sequence.
There are some components of system initialization, for example, the enabling of interrupts, that are
generally performed after the C library initialization code has finished executing. The block of code
labeled $sub$$main( ) performs these tasks immediately before the main application begins executing.
There are special patterns you can use for situations where an existing symbol cannot be modified.
An existing symbol cannot be modified, for example, if it is located in an external library or in ROM code. In such
cases you can use the $Sub$$ patterns to patch an existing symbol.
__main is responsible for setting up the memory
__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 calls __rt_entry, This lists the functions that __rt_entry can call. The function are listed in the order the get called.
2. __user_setup_stackheap or setup the SP by another method
4. __rt_lib_init // initialize the run time library functions
to set up the stack and heap, by calling __rt_lib_init. and call any top level C++ constructors.
branches to main(), the entry to your application.
The _platform_* functions are not part of the standard C library. If you define them, then the linker places calls to them
setting up the stack and heap depends on the method specified by the user. The stack and heap can be setup by any of the following methods:
1. Calling __user_setup_stackheap. This also obtains the bounds of the memory used by the heap (heap top
and heap base).
2. Loading the SP with the value of the symbol __initial_sp.
3. Using the top of the ARM_LIB_STACK or ARM_LIB_STACKHEAP region specified in the linker scatter file.
main is the entry point to the application at the user-level. Registers r0 and r1 contain the arguments to main(). If
main returns, its return value is passed to exit( ) and the application exits.
__rt_entry and __rt_lib_init do not exist as complete functions in the C library. Small sections of these functions
are present in several internal objects that are part of the C library. Not all of these code sections are useful for a given
user application The linker decides which subset of those code sections are needed for a given application, and
includes just those sections in the startup code. The linker places these sections in the correct order to create custom
entry and functions as required by the user application.