* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)crt0.c 5.3 (Berkeley) 3/9/86";
#endif LIBC_SCCS and not lint
* 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
* 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
char **environ
= (char **)0;
asm("#define _start start");
asm("#define _eprol eprol");
asm("#define link .long 0; linkw"); /* Yuk!! */
extern unsigned char etext
;
extern unsigned char eprol
;
char *kargv
[1]; /* size depends on kargc */
char kargstr
[1]; /* size varies */
char kenvstr
[1]; /* size varies */
* ALL REGISTER VARIABLES!!!
register int d7
; /* needed for init (this will be
register struct kframe
*kfp
; /* PCC a5 */
asm("lea a6@(4),%0" : "=r" (kfp
)); /* catch it quick */
asm(" lea a6@(4),a5"); /* catch it quick */
for (argv
= targv
= &kfp
->kargv
[0]; *targv
++; /* void */)
if (targv
>= (char **)(*argv
))
* 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
fd
= open("/dev/null", 2);
} while (fd
>= 0 && fd
< 3);
monstartup(&eprol
, &etext
);
exit(main(kfp
->kargc
, argv
, environ
));
register int code
; /* PCC d7 */
asm("movl %1,sp@-" : "=m" (*(char *)0) : "r" (code
));
* null mcount and moncontrol,
* just in case some routine is compiled for profiling