1*5332Smckusic static char *sccsid = "@(#)crt0.c 4.2 (Berkeley) 01/05/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 25*5332Smckusic 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 */ 375102Smckusick register struct kframe *kfp; /* r11 */ 385102Smckusick register char **targv; 395102Smckusick register char **argv; 405102Smckusick 415102Smckusick #ifdef lint 425102Smckusick kfp = 0; 435102Smckusick #else not lint 445102Smckusick asm(" movl sp,r11"); /* catch it quick */ 455102Smckusick #endif not lint 465102Smckusick for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) 475102Smckusick /* void */ ; 485102Smckusick if (targv >= (char **)(*argv)) 495102Smckusick --targv; 505102Smckusick environ = targv; 515102Smckusick exit(main(kfp->kargc, argv, environ)); 525102Smckusick } 535102Smckusick 545102Smckusick /* 555102Smckusick * null mcount, just in case some routine is compiled for profiling 565102Smckusick */ 57*5332Smckusic asm("mcount: rsb"); 58