267 lines
4.3 KiB
C
267 lines
4.3 KiB
C
#
|
|
#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: </etc/init\0> */
|
|
0061564,
|
|
0064457,
|
|
0064556,
|
|
0000164,
|
|
};
|
|
|
|
/*
|
|
* 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;
|
|
UISD->r[0] = 077406;
|
|
for(;;) {
|
|
UISA->r[0] = i;
|
|
if(fuibyte(0) < 0)
|
|
break;
|
|
clearseg(i);
|
|
maxmem++;
|
|
mfree(coremap, 1, i);
|
|
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);
|
|
}
|