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