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