1 static char *sccsid = "@(#)crt0.c 4.4 (Berkeley) 05/19/82"; 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 asm("#define _start start"); 26 start() 27 { 28 struct kframe { 29 int kargc; 30 char *kargv[1]; /* size depends on kargc */ 31 char kargstr[1]; /* size varies */ 32 char kenvstr[1]; /* size varies */ 33 }; 34 /* 35 * ALL REGISTER VARIABLES!!! 36 */ 37 register int r11; /* needed for init */ 38 register struct kframe *kfp; /* r10 */ 39 register char **targv; 40 register char **argv; 41 42 #ifdef lint 43 kfp = 0; 44 #else not lint 45 asm(" movl sp,r10"); /* catch it quick */ 46 #endif not lint 47 for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) 48 /* void */ ; 49 if (targv >= (char **)(*argv)) 50 --targv; 51 environ = targv; 52 exit(main(kfp->kargc, argv, environ)); 53 } 54 55 /* 56 * null mcount, just in case some routine is compiled for profiling 57 */ 58 asm(" .globl mcount"); 59 asm("mcount: rsb"); 60