* Copyright (c) 1990 The Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)crt0.c 5.5 (Berkeley) %G%";
* Robert Henry, UCB, 20 Oct 81
* We make the following (true) assumption:
* 1) The only register variable that we can trust is ebp,
* which points to the base of the kernel calling frame.
char **environ
= (char **)0;
extern unsigned char etext
;
extern unsigned char eprol
asm ("eprol");
extern start() asm("start");
char *kargv
[1]; /* size depends on kargc */
char kargstr
[1]; /* size varies */
char kenvstr
[1]; /* size varies */
* ALL REGISTER VARIABLES!!!
register struct kframe
*kfp
; /* r10 */
asm("lea 4(%ebp),%ebx"); /* 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
));
asm(".byte 0x9a; .long 0; .word 0");
* null mcount and moncontrol,
* just in case some routine is compiled for profiling