1*6852Srrh static char *sccsid = "@(#)crt0.c 4.4 (Berkeley) 05/19/82"; 25102Smckusick 35102Smckusick /* 45102Smckusick * C start up routine. 55102Smckusick * Robert Henry, UCB, 20 Oct 81 65102Smckusick * 75102Smckusick * We make the following (true) assumptions: 85102Smckusick * 1) when the kernel calls start, it does a jump to location 2, 95102Smckusick * and thus avoids the register save mask. We are NOT called 105102Smckusick * with a calls! see sys1.c:setregs(). 115102Smckusick * 2) The only register variable that we can trust is sp, 125102Smckusick * which points to the base of the kernel calling frame. 135102Smckusick * Do NOT believe the documentation in exec(2) regarding the 145102Smckusick * values of fp and ap. 155102Smckusick * 3) We can allocate as many register variables as we want, 165102Smckusick * and don't have to save them for anybody. 175102Smckusick * 4) Because of the ways that asm's work, we can't have 185102Smckusick * any automatic variables allocated on the stack, because 195102Smckusick * we must catch the value of sp before any automatics are 205102Smckusick * allocated. 215102Smckusick */ 225102Smckusick 235102Smckusick char **environ; 245102Smckusick 255332Smckusic asm("#define _start start"); 265102Smckusick start() 275102Smckusick { 285102Smckusick struct kframe { 295102Smckusick int kargc; 305102Smckusick char *kargv[1]; /* size depends on kargc */ 315102Smckusick char kargstr[1]; /* size varies */ 325102Smckusick char kenvstr[1]; /* size varies */ 335102Smckusick }; 345102Smckusick /* 355102Smckusick * ALL REGISTER VARIABLES!!! 365102Smckusick */ 37*6852Srrh register int r11; /* needed for init */ 38*6852Srrh register struct kframe *kfp; /* r10 */ 395102Smckusick register char **targv; 405102Smckusick register char **argv; 415102Smckusick 425102Smckusick #ifdef lint 435102Smckusick kfp = 0; 445102Smckusick #else not lint 45*6852Srrh asm(" movl sp,r10"); /* catch it quick */ 465102Smckusick #endif not lint 475102Smckusick for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) 485102Smckusick /* void */ ; 495102Smckusick if (targv >= (char **)(*argv)) 505102Smckusick --targv; 515102Smckusick environ = targv; 525102Smckusick exit(main(kfp->kargc, argv, environ)); 535102Smckusick } 545102Smckusick 555102Smckusick /* 565102Smckusick * null mcount, just in case some routine is compiled for profiling 575102Smckusick */ 585397Smckusic asm(" .globl mcount"); 595332Smckusic asm("mcount: rsb"); 60