What happens before main()?
It is completely dependent on the compiler and architecture, but generally that code initializes the most basic hardware required for the rest of the code to run. The code for example:


Defines the reset vectors
Defines the layout of data in memory (many systems use a linker script instead)
Defines the addresses of interrupt service routines in a big table (the interrupt vector table)  
Initializes CPU registers, e.g. the stack pointer  
Configures the core clock  


In addition, that section also serves the runtime needs of the programming language used. It:


Initializes whatever function parameter passing system used
Initializes global variables by e.g. copying flash contents to RAM and zero-initializing memory  
If dynamic memory allocation is used, initializes the heap
If floating point math is enabled, initializes the FPU (if available) or initializes the floating point library  
If exceptions are used, initializes exception handling.