diff options
Diffstat (limited to 'boot')
-rw-r--r-- | boot/mach-crt0.c | 161 |
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)); +} + + + |