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
;
18
extern
cxx_constructor
_init_array_start
;
19
extern
cxx_constructor
_init_array_end
;
20
}
21
22
void
abort
() {
23
#if DEBUG
24
while
(1) {
25
}
26
#else
27
Ion::Device::coreReset
();
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
);
41
memcpy
(&
_data_section_start_ram
, &
_data_section_start_flash
, dataSectionLength);
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 */
50
Ion::Device::initFPU
();
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
60
for
(
cxx_constructor
*
c
= &
_init_array_start
;
c
<&
_init_array_end
;
c
++) {
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? */
67
if
(&
_init_array_start
!= &
_init_array_end
) {
68
abort
();
69
}
70
#endif
71
72
Ion::Device::init
();
73
74
ion_main
(0,
nullptr
);
75
76
abort
();
77
}
memset
void * memset(void *b, int c, size_t len)
Definition:
memset.c:3
ion.h
_bss_section_start_ram
char _bss_section_start_ram
_init_array_start
cxx_constructor _init_array_start
ion_main
void ion_main(int argc, char *argv[])
Definition:
main.cpp:4
cxx_constructor
void(* cxx_constructor)()
Definition:
rt0.cpp:10
c
c(generic_all_nodes)
_bss_section_end_ram
char _bss_section_end_ram
Ion::Device::init
void init()
Definition:
device.cpp:121
rt0.h
_data_section_start_ram
char _data_section_start_ram
Ion::Device::coreReset
void coreReset()
Definition:
device.cpp:99
start
void start()
Definition:
rt0.cpp:31
abort
void abort()
Definition:
rt0.cpp:22
stdint.h
Ion::Device::initFPU
void initFPU()
Definition:
device.cpp:92
_init_array_end
cxx_constructor _init_array_end
memcpy
void * memcpy(void *dst, const void *src, size_t n)
Definition:
memcpy.c:3
_data_section_start_flash
char _data_section_start_flash
_data_section_end_ram
char _data_section_end_ram
epsilon
ion
src
device
boot
rt0.cpp
Generated by
1.8.14