-/* init_main.c 4.38 82/09/12 */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * @(#)init_main.c 7.7 (Berkeley) %G%
+ */
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/kernel.h"
-#include "../h/fs.h"
-#include "../h/mount.h"
-#include "../h/map.h"
-#include "../h/proc.h"
-#include "../h/inode.h"
-#include "../h/seg.h"
-#include "../h/conf.h"
-#include "../h/buf.h"
-#include "../h/mtpr.h"
-#include "../h/pte.h"
-#include "../h/vm.h"
-#include "../h/cmap.h"
-#include "../h/text.h"
-#include "../h/clist.h"
-#ifdef INET
-#include "../h/protosw.h"
-#endif
-#include "../h/quota.h"
+#include "../machine/pte.h"
+
+#include "param.h"
+#include "systm.h"
+#include "dir.h"
+#include "user.h"
+#include "kernel.h"
+#include "fs.h"
+#include "mount.h"
+#include "map.h"
+#include "proc.h"
+#include "inode.h"
+#include "seg.h"
+#include "conf.h"
+#include "buf.h"
+#include "vm.h"
+#include "cmap.h"
+#include "text.h"
+#include "clist.h"
+#include "malloc.h"
+#include "protosw.h"
+#include "quota.h"
+#include "reboot.h"
+#include "../machine/reg.h"
+#include "../machine/cpu.h"
+int cmask = CMASK;
/*
* Initialization code.
* Called from cold start routine as
* hand craft 0th process
* call all initialization routines
* fork - process 0 to schedule
- * - process 2 to page out
* - process 1 execute bootstrap
- *
- * loop at loc 13 (0xd) in user mode -- /etc/init
- * cannot be executed.
+ * - process 2 to page out
*/
main(firstaddr)
+ int firstaddr;
{
register int i;
register struct proc *p;
+ register struct pgrp *pg;
struct fs *fs;
+ int s;
rqinit();
#include "loop.h"
* set up system process 0 (swapper)
*/
p = &proc[0];
- p->p_p0br = (struct pte *)mfpr(P0BR);
+ p->p_p0br = u.u_pcb.pcb_p0br;
p->p_szpt = 1;
p->p_addr = uaddr(p);
p->p_stat = SRUN;
p->p_nice = NZERO;
setredzone(p->p_addr, (caddr_t)&u);
u.u_procp = p;
- u.u_cmask = CMASK;
+ MALLOC(pgrphash[0], struct pgrp *, sizeof (struct pgrp),
+ M_PGRP, M_NOWAIT);
+ if ((pg = pgrphash[0]) == NULL)
+ panic("no space to craft zero'th process group");
+ pg->pg_id = 0;
+ pg->pg_hforw = 0;
+ pg->pg_mem = p;
+ pg->pg_jobc = 0;
+ p->p_pgrp = pg;
+ p->p_pgrpnxt = 0;
+ MALLOC(pg->pg_session, struct session *, sizeof (struct session),
+ M_SESSION, M_NOWAIT);
+ if (pg->pg_session == NULL)
+ panic("no space to craft zero'th session");
+ pg->pg_session->s_count = 1;
+ pg->pg_session->s_leader = 0;
+ /*
+ * These assume that the u. area is always mapped
+ * to the same virtual address. Otherwise must be
+ * handled when copying the u. area in newproc().
+ */
+ u.u_nd.ni_iov = &u.u_nd.ni_iovec;
+ u.u_ap = u.u_arg;
+ u.u_nd.ni_iovcnt = 1;
+
+ u.u_cmask = cmask;
+ u.u_lastfile = -1;
for (i = 1; i < NGROUPS; i++)
- u.u_groups[i] = -1;
+ u.u_groups[i] = NOGROUP;
for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++)
u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max =
RLIM_INFINITY;
- u.u_rlimit[RLIMIT_STACK].rlim_cur = 512*1024;
- u.u_rlimit[RLIMIT_STACK].rlim_max = ctob(MAXDSIZ);
- u.u_rlimit[RLIMIT_DATA].rlim_max =
- u.u_rlimit[RLIMIT_DATA].rlim_cur = ctob(MAXDSIZ);
- p->p_maxrss = RLIM_INFINITY/NBPG;
-#ifdef QUOTA
+ /*
+ * configure virtual memory system,
+ * set vm rlimits
+ */
+ vminit();
+
+#if defined(QUOTA)
qtinit();
p->p_quota = u.u_quota = getquota(0, 0, Q_NDQ);
#endif
- clockstart();
+ startrtclock();
+#if defined(vax)
+#include "kg.h"
+#if NKG > 0
+ startkgclock();
+#endif
+#endif
/*
* Initialize tables, protocols, and set up well-known inodes.
*/
mbinit();
- cinit(); /* needed by dmc-11 driver */
-#ifdef INET
+ cinit();
+#include "sl.h"
+#if NSL > 0
+ slattach(); /* XXX */
+#endif
#if NLOOP > 0
loattach(); /* XXX */
#endif
+ /*
+ * Block reception of incoming packets
+ * until protocols have been initialized.
+ */
+ s = splimp();
ifinit();
- pfinit(); /* must follow interfaces */
-#endif
+ domaininit();
+ splx(s);
+ pqinit();
+ xinit();
ihinit();
- bhinit();
- binit();
- bswinit();
+ swapinit();
+ nchinit();
#ifdef GPROF
kmstartup();
#endif
- fs = mountfs(rootdev, 0, (struct inode *)0);
+ fs = mountfs(rootdev, boothowto & RB_RDONLY, (struct inode *)0);
if (fs == 0)
panic("iinit");
bcopy("/", fs->fs_fsmnt, 2);
-/* initialize wall clock */
- clockinit(fs->fs_time);
+ inittodr(fs->fs_time);
boottime = time;
/* kick off timeout driven events by calling first time */
u.u_dmap = zdmap;
u.u_smap = zdmap;
+ enablertclock(); /* enable realtime clock interrupts */
/*
- * Set the scan rate and other parameters of the paging subsystem.
+ * make init process
*/
- setupclock();
+ proc[0].p_szpt = CLSIZE;
+ if (newproc(0)) {
+ expand(clrnd((int)btoc(szicode)), 0);
+ (void) swpexpand(u.u_dsize, (size_t)0, &u.u_dmap, &u.u_smap);
+ (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
+ /*
+ * Return goes to loc. 0 of user init
+ * code just copied out.
+ */
+ return;
+ }
/*
* make page-out daemon (process 2)
* the daemon has ctopt(nswbuf*CLSIZE*KLMAX) pages of page
* table so that it can map dirty pages into
* its address space during asychronous pushes.
*/
- mpid = 1;
proc[0].p_szpt = clrnd(ctopt(nswbuf*CLSIZE*KLMAX + UPAGES));
- proc[1].p_stat = SZOMB; /* force it to be in proc slot 2 */
if (newproc(0)) {
proc[2].p_flag |= SLOAD|SSYS;
proc[2].p_dsize = u.u_dsize = nswbuf*CLSIZE*KLMAX;
pageout();
+ /*NOTREACHED*/
}
/*
- * make init process and
* enter scheduling loop
*/
-
- mpid = 0;
- proc[1].p_stat = 0;
- proc[0].p_szpt = CLSIZE;
- if (newproc(0)) {
- expand(clrnd((int)btoc(szicode)), P0BR);
- (void) swpexpand(u.u_dsize, 0, &u.u_dmap, &u.u_smap);
- (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
- /*
- * Return goes to loc. 0 of user init
- * code just copied out.
- */
- return;
- }
-#ifdef MUSH
- /*
- * start MUSH daemon
- * pid == 3
- */
- if (newproc(0)) {
- expand(clrnd((int)btoc(szmcode)), P0BR);
- (void) swpexpand(u.u_dsize, 0, &u.u_dmap, &u.u_smap);
- (void) copyout((caddr_t)mcode, (caddr_t)0, (unsigned)szmcode);
- /*
- * Return goes to loc. 0 of user mush
- * code just copied out.
- */
- return;
- }
-#endif
proc[0].p_szpt = 1;
sched();
}
*/
binit()
{
- register struct buf *bp;
- register struct buf *dp;
+ register struct buf *bp, *dp;
register int i;
- struct bdevsw *bdp;
- struct swdevt *swp;
+ int base, residual;
for (dp = bfreelist; dp < &bfreelist[BQUEUES]; dp++) {
dp->b_forw = dp->b_back = dp->av_forw = dp->av_back = dp;
dp->b_flags = B_HEAD;
}
- dp--; /* dp = &bfreelist[BQUEUES-1]; */
+ base = bufpages / nbuf;
+ residual = bufpages % nbuf;
for (i = 0; i < nbuf; i++) {
bp = &buf[i];
bp->b_dev = NODEV;
+ bp->b_bcount = 0;
bp->b_un.b_addr = buffers + i * MAXBSIZE;
- bp->b_bcount = MAXBSIZE;
- bp->b_back = dp;
- bp->b_forw = dp->b_forw;
- dp->b_forw->b_back = bp;
- dp->b_forw = bp;
+ if (i < residual)
+ bp->b_bufsize = (base + 1) * CLBYTES;
+ else
+ bp->b_bufsize = base * CLBYTES;
+ binshash(bp, &bfreelist[BQ_AGE]);
bp->b_flags = B_BUSY|B_INVAL;
brelse(bp);
}
- for (bdp = bdevsw; bdp->d_open; bdp++)
- nblkdev++;
- /*
- * Count swap devices, and adjust total swap space available.
- * Some of this space will not be available until a vswapon()
- * system is issued, usually when the system goes multi-user.
- */
- nswdev = 0;
- for (swp = swdevt; swp->sw_dev; swp++)
- nswdev++;
- if (nswdev == 0)
- panic("binit");
- if (nswdev > 1)
- nswap = (nswap/DMMAX)*DMMAX;
- nswap *= nswdev;
- maxpgio *= nswdev;
- swfree(0);
}
/*
+ * Set up swap devices.
* Initialize linked list of free swap
* headers. These do not actually point
* to buffers, but rather to pages that
* are being swapped in and out.
*/
-bswinit()
+swapinit()
{
register int i;
register struct buf *sp = swbuf;
+ struct swdevt *swp;
+ int error;
+ /*
+ * Count swap devices, and adjust total swap space available.
+ * Some of this space will not be available until a swapon()
+ * system is issued, usually when the system goes multi-user.
+ */
+ nswdev = 0;
+ nswap = 0;
+ for (swp = swdevt; swp->sw_dev; swp++) {
+ nswdev++;
+ if (swp->sw_nblks > nswap)
+ nswap = swp->sw_nblks;
+ }
+ if (nswdev == 0)
+ panic("swapinit");
+ if (nswdev > 1)
+ nswap = ((nswap + dmmax - 1) / dmmax) * dmmax;
+ nswap *= nswdev;
+ /*
+ * If there are multiple swap areas,
+ * allow more paging operations per second.
+ */
+ if (nswdev > 1)
+ maxpgio = (maxpgio * (2 * nswdev - 1)) / 2;
+ if (error = swfree(0)) {
+ printf("swfree errno %d\n", error); /* XXX */
+ panic("swapinit swfree 0");
+ }
+
+ /*
+ * Now set up swap buffer headers.
+ */
bswlist.av_forw = sp;
for (i=0; i<nswbuf-1; i++, sp++)
sp->av_forw = sp+1;
{
register int ccp;
register struct cblock *cp;
- register struct cdevsw *cdp;
ccp = (int)cfree;
ccp = (ccp+CROUND) & ~CROUND;
cfreelist = cp;
cfreecount += CBSIZE;
}
- ccp = 0;
- for(cdp = cdevsw; cdp->d_open; cdp++)
- ccp++;
- nchrdev = ccp;
}