1 static char *sccsid = "@(#)crt0.c 4.6 (Berkeley) 03/30/83"; 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 = (char **)0; 24 25 asm("#define _start start"); 26 asm("#define _eprol eprol"); 27 extern unsigned char etext; 28 extern unsigned char eprol; 29 start() 30 { 31 struct kframe { 32 int kargc; 33 char *kargv[1]; /* size depends on kargc */ 34 char kargstr[1]; /* size varies */ 35 char kenvstr[1]; /* size varies */ 36 }; 37 /* 38 * ALL REGISTER VARIABLES!!! 39 */ 40 register int r11; /* needed for init */ 41 register struct kframe *kfp; /* r10 */ 42 register char **targv; 43 register char **argv; 44 45 #ifdef lint 46 kfp = 0; 47 initcode = initcode = 0; 48 #else not lint 49 asm(" movl sp,r10"); /* catch it quick */ 50 #endif not lint 51 for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) 52 /* void */ ; 53 if (targv >= (char **)(*argv)) 54 --targv; 55 environ = targv; 56 asm("eprol:"); 57 #ifdef MCRT0 58 monstartup(&eprol, &etext); 59 #endif MCRT0 60 exit(main(kfp->kargc, argv, environ)); 61 } 62 asm("#undef _start"); 63 asm("#undef _eprol"); 64 65 #ifdef MCRT0 66 /*ARGSUSED*/ 67 exit(code) 68 register int code; /* r11 */ 69 { 70 monitor(0); 71 _cleanup(); 72 asm(" movl r11,r0"); 73 asm(" chmk $1"); 74 } 75 #endif MCRT0 76 77 #ifdef CRT0 78 /* 79 * null mcount and moncontrol, 80 * just in case some routine is compiled for profiling 81 */ 82 moncontrol(val) 83 int val; 84 { 85 86 } 87 asm(" .globl mcount"); 88 asm("mcount: rsb"); 89 #endif CRT0 90