# #include "../param.h" #include "../user.h" #include "../systm.h" #include "../proc.h" #include "../text.h" #include "../inode.h" #include "../seg.h" #define CLOCK1 0177546 #define CLOCK2 0172540 /* * Icode is the octal bootstrap * program executed in user mode * to bring up the system. */ int icode[] { 0104413, /* sys exec; init; initp */ 0000014, 0000010, 0000777, /* br . */ 0000014, /* initp: init; 0 */ 0000000, 0062457, /* init: */ 0061564, 0064457, 0064556, 0000164, }; int stmem, endmem; /* For system status */ /* * Initialization code. * Called from m40.s or m45.s as * soon as a stack and segmentation * have been established. * Functions: * clear and free user core * find which clock is configured * hand craft 0th process * call all initialization routines * fork - process 0 to schedule * - process 1 execute bootstrap * * panic: no clock -- neither clock responds * loop at loc 6 in user mode -- /etc/init * cannot be executed. */ main() { extern schar; register i, *p; /* * zero and free all of core */ updlock = 0; i = *ka6 + USIZE; stmem = i; UISD->r[0] = 077406; for(;;) { UISA->r[0] = i; if(fuibyte(0) < 0) break; clearseg(i); maxmem++; mfree(coremap, 1, i); i++; } endmem = i; if(cputype == 70) for(i=0; i<62; i=+2) { UBMAP->r[i] = i<<12; UBMAP->r[i+1] = 0; } printf("mem = %l\n", maxmem*5/16); maxmem = min(maxmem, MAXMEM); mfree(swapmap, nswap, swplo); /* * determine clock */ UISA->r[7] = ka6[1]; /* io segment */ UISD->r[7] = 077406; lks = CLOCK1; if(fuiword(lks) == -1) { lks = CLOCK2; if(fuiword(lks) == -1) panic("no clock"); } /* * set up system process */ proc[0].p_addr = *ka6; proc[0].p_size = USIZE; proc[0].p_stat = SRUN; proc[0].p_flag =| SLOAD|SSYS; u.u_procp = &proc[0]; /* * set up 'known' i-nodes */ *lks = 0115; cinit(); binit(); iinit(); rootdir = iget(rootdev, ROOTINO); rootdir->i_flag =& ~ILOCK; u.u_cdir = iget(rootdev, ROOTINO); u.u_cdir->i_flag =& ~ILOCK; /* * make init process * enter scheduling loop * with system process */ if(newproc()) { expand(USIZE+1); estabur(0, 1, 0, 0); copyout(icode, 0, sizeof icode); /* * Return goes to loc. 0 of user init * code just copied out. */ return; } sched(); } /* * Load the user hardware segmentation * registers from the software prototype. * The software registers must have * been setup prior by estabur. */ sureg() { register *up, *rp, a; a = u.u_procp->p_addr; up = &u.u_uisa[16]; rp = &UISA->r[16]; if(cputype == 40) { up =- 8; rp =- 8; } while(rp > &UISA->r[0]) *--rp = *--up + a; if((up=u.u_procp->p_textp) != NULL) a =- up->x_caddr; up = &u.u_uisd[16]; rp = &UISD->r[16]; if(cputype == 40) { up =- 8; rp =- 8; } while(rp > &UISD->r[0]) { *--rp = *--up; if((*rp & WO) == 0) rp[(UISA-UISD)/2] =- a; } } /* * Set up software prototype segmentation * registers to implement the 3 pseudo * text,data,stack segment sizes passed * as arguments. * The argument sep specifies if the * text and data+stack segments are to * be separated. */ estabur(nt, nd, ns, sep) { register a, *ap, *dp; if(sep) { if(cputype == 40) goto err; if(nseg(nt) > 8 || nseg(nd)+nseg(ns) > 8) goto err; } else if(nseg(nt)+nseg(nd)+nseg(ns) > 8) goto err; if(nt+nd+ns+USIZE > maxmem) goto err; a = 0; ap = &u.u_uisa[0]; dp = &u.u_uisd[0]; while(nt >= 128) { *dp++ = (127<<8) | RO; *ap++ = a; a =+ 128; nt =- 128; } if(nt) { *dp++ = ((nt-1)<<8) | RO; *ap++ = a; } if(sep) while(ap < &u.u_uisa[8]) { *ap++ = 0; *dp++ = 0; } a = USIZE; while(nd >= 128) { *dp++ = (127<<8) | RW; *ap++ = a; a =+ 128; nd =- 128; } if(nd) { *dp++ = ((nd-1)<<8) | RW; *ap++ = a; a =+ nd; } while(ap < &u.u_uisa[8]) { *dp++ = 0; *ap++ = 0; } if(sep) while(ap < &u.u_uisa[16]) { *dp++ = 0; *ap++ = 0; } a =+ ns; while(ns >= 128) { a =- 128; ns =- 128; *--dp = (127<<8) | RW; *--ap = a; } if(ns) { *--dp = ((128-ns)<<8) | RW | ED; *--ap = a-128; } if(!sep) { ap = &u.u_uisa[0]; dp = &u.u_uisa[8]; while(ap < &u.u_uisa[8]) *dp++ = *ap++; ap = &u.u_uisd[0]; dp = &u.u_uisd[8]; while(ap < &u.u_uisd[8]) *dp++ = *ap++; } sureg(); return(0); err: u.u_error = ENOMEM; return(-1); } /* * Return the arg/128 rounded up. */ nseg(n) { return((n+127)>>7); }