1*5102Smckusick static char *sccsid = "@(#)crt0.c 1.1 (Berkeley) 11/29/81"; 2*5102Smckusick 3*5102Smckusick /* 4*5102Smckusick * C start up routine. 5*5102Smckusick * Robert Henry, UCB, 20 Oct 81 6*5102Smckusick * 7*5102Smckusick * We make the following (true) assumptions: 8*5102Smckusick * 1) when the kernel calls start, it does a jump to location 2, 9*5102Smckusick * and thus avoids the register save mask. We are NOT called 10*5102Smckusick * with a calls! see sys1.c:setregs(). 11*5102Smckusick * 2) The only register variable that we can trust is sp, 12*5102Smckusick * which points to the base of the kernel calling frame. 13*5102Smckusick * Do NOT believe the documentation in exec(2) regarding the 14*5102Smckusick * values of fp and ap. 15*5102Smckusick * 3) We can allocate as many register variables as we want, 16*5102Smckusick * and don't have to save them for anybody. 17*5102Smckusick * 4) Because of the ways that asm's work, we can't have 18*5102Smckusick * any automatic variables allocated on the stack, because 19*5102Smckusick * we must catch the value of sp before any automatics are 20*5102Smckusick * allocated. 21*5102Smckusick */ 22*5102Smckusick 23*5102Smckusick char **environ; 24*5102Smckusick 25*5102Smckusick start() 26*5102Smckusick { 27*5102Smckusick struct kframe { 28*5102Smckusick int kargc; 29*5102Smckusick char *kargv[1]; /* size depends on kargc */ 30*5102Smckusick char kargstr[1]; /* size varies */ 31*5102Smckusick char kenvstr[1]; /* size varies */ 32*5102Smckusick }; 33*5102Smckusick /* 34*5102Smckusick * ALL REGISTER VARIABLES!!! 35*5102Smckusick */ 36*5102Smckusick register struct kframe *kfp; /* r11 */ 37*5102Smckusick register char **targv; 38*5102Smckusick register char **argv; 39*5102Smckusick 40*5102Smckusick #ifdef lint 41*5102Smckusick kfp = 0; 42*5102Smckusick #else not lint 43*5102Smckusick asm(" movl sp,r11"); /* catch it quick */ 44*5102Smckusick #endif not lint 45*5102Smckusick for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) 46*5102Smckusick /* void */ ; 47*5102Smckusick if (targv >= (char **)(*argv)) 48*5102Smckusick --targv; 49*5102Smckusick environ = targv; 50*5102Smckusick exit(main(kfp->kargc, argv, environ)); 51*5102Smckusick } 52*5102Smckusick 53*5102Smckusick /* 54*5102Smckusick * null mcount, just in case some routine is compiled for profiling 55*5102Smckusick */ 56*5102Smckusick asm("#define _mcount mcount"); 57*5102Smckusick mcount() 58*5102Smckusick { 59*5102Smckusick asm(" forgot to run ex script on gcrt0.s" ); 60*5102Smckusick asm( " rsb" ); 61*5102Smckusick asm( "#undef _mcount"); 62*5102Smckusick } 63