summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/unix/posix/startup/rtems-ctor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/unix/posix/startup/rtems-ctor.cc')
-rw-r--r--c/src/lib/libbsp/unix/posix/startup/rtems-ctor.cc108
1 files changed, 108 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/unix/posix/startup/rtems-ctor.cc b/c/src/lib/libbsp/unix/posix/startup/rtems-ctor.cc
new file mode 100644
index 0000000000..4c55f3798f
--- /dev/null
+++ b/c/src/lib/libbsp/unix/posix/startup/rtems-ctor.cc
@@ -0,0 +1,108 @@
+// @(#)rtems-ctor.cc 1.6 - 95/04/25
+//
+//
+
+/*
+ * rtems-ctor.cc
+ *
+ * Description:
+ * This file exists solely to (try to) ensure RTEMS is initialized
+ * before any global constructors are run.
+ *
+ * The problem:
+ * Global constructors might reasonably expect that new() will
+ * work, but since new() uses malloc() which uses RTEMS regions,
+ * it can not be called until after initialize_executive().
+ *
+ * Global constructors are called in GNU systems one of 2 ways:
+ *
+ * an "invisible" call to __main() inserted by compiler
+ * This __main() calls __do_global_ctors() which
+ * walks thru the table and calls all global
+ * constructors.
+ *
+ * or -
+ * A special section is put into the linked binary. The
+ * system startup code knows to run the constructors in
+ * this special section before calling main().
+ *
+ * By making RTEMS initialization a constructor, we avoid having
+ * too much about all this. All we have to guarantee is that
+ * this constructor is the first one run.
+ *
+ *
+ * So for the first case above, this is what happens
+ *
+ * host crt0
+ * main()
+ * __main()
+ * __do_global_ctors()
+ * bsp_start()
+ * init_executive_early()
+ * <<any other constructors>>
+ *
+ * init_executive_late()
+ * bsp_cleanup()
+ *
+ * TODO:
+ *
+ */
+
+#include <bsp.h>
+
+/*
+ * RTEMS program name
+ * Probably not used by anyone, but it is nice to have it.
+ * Actually the UNIX version of CPU_INVOKE_DEBUGGER will probably
+ * need to use it
+ */
+
+char *rtems_progname;
+
+class RTEMS {
+ public:
+ RTEMS();
+ ~RTEMS();
+};
+
+RTEMS rtems_constructor;
+
+RTEMS::RTEMS()
+{
+ bsp_start();
+}
+
+RTEMS::~RTEMS()
+{
+ bsp_cleanup();
+}
+
+extern "C" {
+ int
+ main(int argc,
+ char **argv,
+ char **environp)
+ {
+ rtems_argc = argc;
+ rtems_argv = argv;
+ rtems_envp = environp;
+
+ if ((argc > 0) && argv && argv[0])
+ rtems_progname = argv[0];
+ else
+ rtems_progname = "RTEMS";
+
+ /*
+ * Start multitasking
+ */
+
+ rtems_initialize_executive_late( bsp_isr_level );
+
+ /*
+ * Returns when multitasking is stopped
+ * This allows our destructors to get run normally
+ */
+
+ return 0;
+ }
+}