xref: /csrg-svn/sys/kern/init_main.c (revision 235)
1 /*	init_main.c	3.5	06/07/80	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/dir.h"
6 #include "../h/user.h"
7 #include "../h/filsys.h"
8 #include "../h/mount.h"
9 #include "../h/map.h"
10 #include "../h/proc.h"
11 #include "../h/inode.h"
12 #include "../h/seg.h"
13 #include "../h/conf.h"
14 #include "../h/buf.h"
15 #include "../h/mtpr.h"
16 #include "../h/pte.h"
17 #include "../h/clock.h"
18 #include "../h/vm.h"
19 #include "../h/cmap.h"
20 
21 /*
22  * Initialization code.
23  * Called from cold start routine as
24  * soon as a stack and segmentation
25  * have been established.
26  * Functions:
27  *	clear and free user core
28  *	turn on clock
29  *	hand craft 0th process
30  *	call all initialization routines
31  *	fork - process 0 to schedule
32  *	     - process 2 to page out
33  *	     - process 1 execute bootstrap
34  *
35  * loop at loc 13 (0xd) in user mode -- /etc/init
36  *	cannot be executed.
37  */
38 main(firstaddr)
39 {
40 
41 	cpusid = mfpr(SID);		/* get system identification */
42 #ifdef FASTVAX
43 	rqinit();
44 #endif
45 	startup(firstaddr);
46 	if (lotsfree == 0)
47 		lotsfree = LOTSFREE;
48 
49 	/*
50 	 * set up system process 0 (swapper)
51 	 */
52 
53 	proc[0].p_p0br = (struct pte *)mfpr(P0BR);
54 	proc[0].p_szpt = 1;
55 	proc[0].p_addr = uaddr(&proc[0]);
56 	proc[0].p_stat = SRUN;
57 	proc[0].p_flag |= SLOAD|SSYS;
58 	proc[0].p_nice = NZERO;
59 	u.u_procp = &proc[0];
60 	u.u_cmask = CMASK;
61 	clkstart();
62 
63 	/*
64 	 * Initialize devices and
65 	 * set up 'known' i-nodes
66 	 */
67 
68 	ihinit();
69 	bhinit();
70 	cinit();
71 	binit();
72 	bswinit();
73 	iinit();
74 	rootdir = iget(rootdev, (ino_t)ROOTINO);
75 	rootdir->i_flag &= ~ILOCK;
76 	u.u_cdir = iget(rootdev, (ino_t)ROOTINO);
77 	u.u_cdir->i_flag &= ~ILOCK;
78 	u.u_rdir = NULL;
79 	u.u_dmap = zdmap;
80 	u.u_smap = zdmap;
81 
82 	/*
83 	 * make page-out daemon (process 2)
84 	 * the daemon has ctopt(NSWBUF*CLSIZE*KLMAX) pages of page
85 	 * table so that it can map dirty pages into
86 	 * its address space during asychronous pushes.
87 	 */
88 
89 	mpid = 1;
90 	proc[0].p_szpt = clrnd(ctopt(NSWBUF*CLSIZE*KLMAX + UPAGES));
91 	proc[1].p_stat = SZOMB;		/* force it to be in proc slot 2 */
92 	if (newproc(0)) {
93 		proc[2].p_flag |= SLOAD|SSYS;
94 		proc[2].p_dsize = u.u_dsize = NSWBUF*CLSIZE*KLMAX;
95 		pageout();
96 	}
97 
98 	/*
99 	 * make init process and
100 	 * enter scheduling loop
101 	 */
102 
103 	mpid = 0;
104 	proc[1].p_stat = 0;
105 	proc[0].p_szpt = CLSIZE;
106 	if (newproc(0)) {
107 		expand(clrnd((int)btoc(szicode)), P0BR);
108 		(void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
109 		/*
110 		 * Return goes to loc. 0 of user init
111 		 * code just copied out.
112 		 */
113 		return;
114 	}
115 	proc[0].p_szpt = 1;
116 	sched();
117 }
118 
119 /*
120  * iinit is called once (from main)
121  * very early in initialization.
122  * It reads the root's super block
123  * and initializes the current date
124  * from the last modified date.
125  *
126  * panic: iinit -- cannot read the super
127  * block. Usually because of an IO error.
128  */
129 iinit()
130 {
131 	register struct buf *cp, *bp;
132 	register struct filsys *fp;
133 	register unsigned i, j;
134 
135 	(*bdevsw[major(rootdev)].d_open)(rootdev, 1);
136 	bp = bread(rootdev, SUPERB);
137 	cp = geteblk();
138 	if(u.u_error)
139 		panic("iinit");
140 	bcopy(bp->b_un.b_addr, cp->b_un.b_addr, sizeof(struct filsys));
141 	brelse(bp);
142 	mount[0].m_bufp = cp;
143 	mount[0].m_dev = rootdev;
144 	fp = cp->b_un.b_filsys;
145 	fp->s_flock = 0;
146 	fp->s_ilock = 0;
147 	fp->s_ronly = 0;
148 	fp->s_lasti = 1;
149 	fp->s_nbehind = 0;
150 	/* on boot, read VAX TODR register (GMT 10 ms.
151 	*	clicks into current year) and set software time
152 	*	in 'int time' (GMT seconds since year YRREF)
153 	*/
154 	for (i = 0 , j = YRREF ; j < YRCURR ; j++)
155 		i += (SECYR + (j%4?0:SECDAY)) ;
156 	time = udiv(mfpr(TODR),100) + i ;
157 	bootime = time;
158 }
159 
160 /*
161  * This is the set of buffers proper, whose heads
162  * were declared in buf.h.  There can exist buffer
163  * headers not pointing here that are used purely
164  * as arguments to the I/O routines to describe
165  * I/O to be done-- e.g. swap headers swbuf[] for
166  * swapping.
167  */
168 char	buffers[NBUF][BSIZE];
169 
170 /*
171  * Initialize the buffer I/O system by freeing
172  * all buffers and setting all device buffer lists to empty.
173  *
174  * SHOULD USE MEMALL HERE!!!
175  */
176 binit()
177 {
178 	register struct buf *bp;
179 	register struct buf *dp;
180 	register int i;
181 	struct bdevsw *bdp;
182 
183 	bfreelist.b_forw = bfreelist.b_back =
184 	    bfreelist.av_forw = bfreelist.av_back = &bfreelist;
185 	for (i=0; i<NBUF; i++) {
186 		bp = &buf[i];
187 		bp->b_dev = NODEV;
188 		bp->b_un.b_addr = buffers[i];
189 		bp->b_back = &bfreelist;
190 		bp->b_forw = bfreelist.b_forw;
191 		bfreelist.b_forw->b_back = bp;
192 		bfreelist.b_forw = bp;
193 		bp->b_flags = B_BUSY;
194 		brelse(bp);
195 	}
196 	for (bdp = bdevsw; bdp->d_open; bdp++) {
197 		dp = bdp->d_tab;
198 		if(dp) {
199 			dp->b_forw = dp;
200 			dp->b_back = dp;
201 		}
202 		nblkdev++;
203 	}
204 }
205 
206 /*
207  * Initialize linked list of free swap
208  * headers. These do not actually point
209  * to buffers, but rather to pages that
210  * are being swapped in and out.
211  */
212 bswinit()
213 {
214 	register int i;
215 
216 	bswlist.av_forw = &swbuf[0];
217 	for (i=0; i<NSWBUF-1; i++)
218 		swbuf[i].av_forw = &swbuf[i+1];
219 	swbuf[NSWBUF-1].av_forw = NULL;
220 }
221