no swplo
[unix-history] / usr / src / sys / kern / init_main.c
CommitLineData
41888f16 1/* init_main.c 3.6 %G% */
c4708522
BJ
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 */
38main(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();
0d5a507c 69 bhinit();
c4708522
BJ
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);
81263dba 108 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
c4708522
BJ
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 */
129iinit()
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 */
143f81a8 168char buffers[NBUF][BSIZE];
c4708522
BJ
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 */
176binit()
177{
178 register struct buf *bp;
179 register struct buf *dp;
180 register int i;
181 struct bdevsw *bdp;
41888f16 182 struct swdevt *swp;
c4708522
BJ
183
184 bfreelist.b_forw = bfreelist.b_back =
185 bfreelist.av_forw = bfreelist.av_back = &bfreelist;
186 for (i=0; i<NBUF; i++) {
187 bp = &buf[i];
188 bp->b_dev = NODEV;
189 bp->b_un.b_addr = buffers[i];
190 bp->b_back = &bfreelist;
191 bp->b_forw = bfreelist.b_forw;
192 bfreelist.b_forw->b_back = bp;
193 bfreelist.b_forw = bp;
194 bp->b_flags = B_BUSY;
195 brelse(bp);
196 }
197 for (bdp = bdevsw; bdp->d_open; bdp++) {
198 dp = bdp->d_tab;
199 if(dp) {
200 dp->b_forw = dp;
201 dp->b_back = dp;
202 }
203 nblkdev++;
204 }
41888f16
BJ
205 /*
206 * Count swap devices, and adjust total swap space available.
207 * Some of this space will not be available until a vswapon()
208 * system is issued, usually when the system goes multi-user.
209 */
210 nswdev = 0;
211 for (swp = swdevt; swp->sw_dev; swp++)
212 nswdev++;
213 if (nswdev == 0)
214 panic("binit");
215 nswap *= nswdev;
216 maxpgio *= nswdev;
217 swfree(0);
c4708522
BJ
218}
219
220/*
221 * Initialize linked list of free swap
222 * headers. These do not actually point
223 * to buffers, but rather to pages that
224 * are being swapped in and out.
225 */
226bswinit()
227{
228 register int i;
229
230 bswlist.av_forw = &swbuf[0];
231 for (i=0; i<NSWBUF-1; i++)
232 swbuf[i].av_forw = &swbuf[i+1];
233 swbuf[NSWBUF-1].av_forw = NULL;
234}