summaryrefslogtreecommitdiff
path: root/boot/mach-crt0.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/mach-crt0.c')
-rw-r--r--boot/mach-crt0.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/boot/mach-crt0.c b/boot/mach-crt0.c
new file mode 100644
index 00000000..bf1a605f
--- /dev/null
+++ b/boot/mach-crt0.c
@@ -0,0 +1,161 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)crt0.c 5.2 (Berkeley) 5/14/90";
+#endif /* not lint */
+
+/*
+ * C start up routine.
+ * Robert Henry, UCB, 20 Oct 81
+ *
+ * We make the following (true) assumptions:
+ * 1) when the kernel calls start, it does a jump to location 2,
+ * and thus avoids the register save mask. We are NOT called
+ * with a calls! see sys1.c:setregs().
+ * 2) The only register variable that we can trust is sp,
+ * which points to the base of the kernel calling frame.
+ * Do NOT believe the documentation in exec(2) regarding the
+ * values of fp and ap.
+ * 3) We can allocate as many register variables as we want,
+ * and don't have to save them for anybody.
+ * 4) Because of the ways that asm's work, we can't have
+ * any automatic variables allocated on the stack, because
+ * we must catch the value of sp before any automatics are
+ * allocated.
+ */
+
+#include <mach/machine/asm.h>
+
+char **environ = (char **)0;
+#ifdef paranoid
+static int fd;
+#endif paranoid
+
+int (*mach_init_routine)();
+int (*_cthread_init_routine)();
+int (*_cthread_exit_routine)();
+int (*_monstartup_routine)();
+int (*_StrongBox_init_routine)();
+int errno = 0;
+int exit();
+
+extern unsigned char etext;
+extern unsigned char _eprol;
+_start()
+{
+ struct kframe {
+ int kargc;
+ char *kargv[1]; /* size depends on kargc */
+ char kargstr[1]; /* size varies */
+ char kenvstr[1]; /* size varies */
+ };
+ /*
+ * ALL REGISTER VARIABLES!!!
+ */
+ register int r11; /* needed for init */
+ register struct kframe *kfp; /* r10 */
+ register char **targv;
+ register char **argv;
+
+#ifdef lint
+ kfp = 0;
+ initcode = initcode = 0;
+#else not lint
+#define Entry_sp() \
+({ int _spl__, _tmp1__; \
+ asm volatile("leal 4(%%ebp), %0" : "=r" (_spl__) : "r" (_tmp1__)); \
+ _spl__; })
+
+ kfp = (struct kframe *)Entry_sp();
+#endif not lint
+ for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
+ /* void */ ;
+ if (targv >= (char **)(*argv))
+ --targv;
+ environ = targv;
+ if (mach_init_routine)
+ (void) mach_init_routine();
+
+asm(".globl __eprol");
+asm("__eprol:");
+
+#ifdef paranoid
+ /*
+ * The standard I/O library assumes that file descriptors 0, 1, and 2
+ * are open. If one of these descriptors is closed prior to the start
+ * of the process, I/O gets very confused. To avoid this problem, we
+ * insure that the first three file descriptors are open before calling
+ * main(). Normally this is undefined, as it adds two unnecessary
+ * system calls.
+ */
+ do {
+ fd = open("/dev/null", 2);
+ } while (fd >= 0 && fd < 3);
+ close(fd);
+#endif paranoid
+
+
+ if (_cthread_init_routine) {
+ int new_sp;
+ new_sp = (*_cthread_init_routine)();
+ if (new_sp) {
+ asm volatile("movl %0, %%esp" : : "g" (new_sp) );
+ }
+ }
+ if (_StrongBox_init_routine) (*_StrongBox_init_routine)();
+
+ if (_monstartup_routine) {
+ _monstartup_routine(&_eprol, &etext);
+ }
+
+ (* (_cthread_exit_routine ? _cthread_exit_routine : exit))
+ (main(kfp->kargc, argv, targv));
+}
+
+
+