Numworks Epsilon  1.4.1
Graphing Calculator Operating System
rt0.cpp
Go to the documentation of this file.
1 extern "C" {
2 #include "rt0.h"
3 }
4 #include <stdint.h>
5 #include <string.h>
6 #include <ion.h>
7 #include "../device.h"
8 #include "../console.h"
9 
10 typedef void (*cxx_constructor)();
11 
12 extern "C" {
13  extern char _data_section_start_flash;
14  extern char _data_section_start_ram;
15  extern char _data_section_end_ram;
16  extern char _bss_section_start_ram;
17  extern char _bss_section_end_ram;
20 }
21 
22 void abort() {
23 #if DEBUG
24  while (1) {
25  }
26 #else
28 #endif
29 }
30 
31 void start() {
32  // This is where execution starts after reset.
33  // Many things are not initialized yet so the code here has to pay attention.
34 
35  /* Copy data section to RAM
36  * The data section is R/W but its initialization value matters. It's stored
37  * in Flash, but linked as if it were in RAM. Now's our opportunity to copy
38  * it. Note that until then the data section (e.g. global variables) contains
39  * garbage values and should not be used. */
40  size_t dataSectionLength = (&_data_section_end_ram - &_data_section_start_ram);
42 
43  /* Zero-out the bss section in RAM
44  * Until we do, any uninitialized global variable will be unusable. */
45  size_t bssSectionLength = (&_bss_section_end_ram - &_bss_section_start_ram);
46  memset(&_bss_section_start_ram, 0, bssSectionLength);
47 
48  /* Initialize the FPU as early as possible.
49  * For example, static C++ objects are very likely to manipulate float values */
51 
52  /* Call static C++ object constructors
53  * The C++ compiler creates an initialization function for each static object.
54  * The linker then stores the address of each of those functions consecutively
55  * between _init_array_start and _init_array_end. So to initialize all C++
56  * static objects we just have to iterate between theses two addresses and
57  * call the pointed function. */
58 #define SUPPORT_CPP_GLOBAL_CONSTRUCTORS 0
59 #if SUPPORT_CPP_GLOBAL_CONSTRUCTORS
61  (*c)();
62  }
63 #else
64  /* In practice, static initialized objects are a terrible idea. Since the init
65  * order is not specified, most often than not this yields the dreaded static
66  * init order fiasco. How about bypassing the issue altogether? */
68  abort();
69  }
70 #endif
71 
73 
74  ion_main(0, nullptr);
75 
76  abort();
77 }
void * memset(void *b, int c, size_t len)
Definition: memset.c:3
char _bss_section_start_ram
cxx_constructor _init_array_start
void ion_main(int argc, char *argv[])
Definition: main.cpp:4
void(* cxx_constructor)()
Definition: rt0.cpp:10
c(generic_all_nodes)
char _bss_section_end_ram
void init()
Definition: device.cpp:121
char _data_section_start_ram
void coreReset()
Definition: device.cpp:99
void start()
Definition: rt0.cpp:31
void abort()
Definition: rt0.cpp:22
void initFPU()
Definition: device.cpp:92
cxx_constructor _init_array_end
void * memcpy(void *dst, const void *src, size_t n)
Definition: memcpy.c:3
char _data_section_start_flash
char _data_section_end_ram