Files
retrobsd/sys/kernel/init_main.c
2015-09-26 21:46:11 -07:00

213 lines
5.4 KiB
C

/*
* Copyright (c) 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#include <sys/param.h>
#include <sys/user.h>
#include <sys/fs.h>
#include <sys/mount.h>
#include <sys/map.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <sys/inode.h>
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/fcntl.h>
#include <sys/vm.h>
#include <sys/clist.h>
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/namei.h>
#include <sys/stat.h>
#include <sys/kconfig.h>
u_int swapstart, nswap; /* start and size of swap space */
size_t physmem; /* total amount of physical memory */
int boothowto; /* reboot flags, from boot */
/*
* Initialize hash links for buffers.
*/
static void
bhinit()
{
register int i;
register struct bufhd *bp;
for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++)
bp->b_forw = bp->b_back = (struct buf *)bp;
}
/*
* Initialize the buffer I/O system by freeing
* all buffers and setting all device buffer lists to empty.
*/
static void
binit()
{
register struct buf *bp;
register int i;
caddr_t paddr;
for (bp = bfreelist; bp < &bfreelist[BQUEUES]; bp++)
bp->b_forw = bp->b_back = bp->av_forw = bp->av_back = bp;
paddr = bufdata;
for (i = 0; i < NBUF; i++, paddr += MAXBSIZE) {
bp = &buf[i];
bp->b_dev = NODEV;
bp->b_bcount = 0;
bp->b_addr = paddr;
binshash(bp, &bfreelist[BQ_AGE]);
bp->b_flags = B_BUSY|B_INVAL;
brelse(bp);
}
}
/*
* Initialize clist by freeing all character blocks, then count
* number of character devices. (Once-only routine)
*/
static void
cinit()
{
register int ccp;
register struct cblock *cp;
ccp = (int)cfree;
ccp = (ccp + CROUND) & ~CROUND;
for (cp = (struct cblock *)ccp; cp <= &cfree[NCLIST - 1]; cp++) {
cp->c_next = cfreelist;
cfreelist = cp;
cfreecount += CBSIZE;
}
}
/*
* Initialization code.
* Called from cold start routine as
* soon as a stack and segmentation
* have been established.
* Functions:
* clear and free user core
* turn on clock
* hand craft 0th process
* call all initialization routines
* fork - process 0 to schedule
* - process 1 execute bootstrap
*/
int
main()
{
register struct proc *p;
register int i;
register struct fs *fs = NULL;
int s __attribute__((unused));
startup();
printf ("\n%s", version);
kconfig();
cnidentify();
/*
* Set up system process 0 (swapper).
*/
p = &proc[0];
p->p_addr = (size_t) &u;
p->p_stat = SRUN;
p->p_flag |= SLOAD | SSYS;
p->p_nice = NZERO;
u.u_procp = p; /* init user structure */
u.u_cmask = CMASK;
u.u_lastfile = -1;
for (i = 1; i < NGROUPS; i++)
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;
/* Initialize signal state for process 0 */
siginit (p);
/*
* Initialize tables, protocols, and set up well-known inodes.
*/
#ifdef LOG_ENABLED
loginit();
#endif
coutinit();
cinit();
pqinit();
ihinit();
bhinit();
binit();
nchinit();
clkstart();
pipedev = rootdev;
/* Attach services. */
struct conf_service *svc;
for (svc = conf_service_init; svc->svc_attach != NULL; svc++)
(*svc->svc_attach)();
/* Mount a root filesystem. */
s = spl0();
fs = mountfs (rootdev, (boothowto & RB_RDONLY) ? MNT_RDONLY : 0, 0);
if (! fs)
panic ("No root filesystem found!");
mount[0].m_inodp = (struct inode*) 1; /* XXX */
mount_updname (fs, "/", "root", 1, 4);
time.tv_sec = fs->fs_time;
boottime = time;
/* Find a swap file. */
swapstart = 1;
(*bdevsw[major(swapdev)].d_open)(swapdev, FREAD|FWRITE, S_IFBLK);
nswap = (*bdevsw[major(swapdev)].d_psize)(swapdev);
if (nswap <= 0)
panic ("zero swap size"); /* don't want to panic, but what ? */
mfree (swapmap, nswap, swapstart);
printf ("phys mem = %u kbytes\n", physmem / 1024);
printf ("user mem = %u kbytes\n", MAXMEM / 1024);
printf ("root dev = (%d,%d)\n", major(rootdev), minor(rootdev));
printf ("swap dev = (%d,%d)\n", major(swapdev), minor(swapdev));
printf ("root size = %u kbytes\n", fs->fs_fsize * DEV_BSIZE / 1024);
printf ("swap size = %u kbytes\n", nswap * DEV_BSIZE / 1024);
/* Kick off timeout driven events by calling first time. */
schedcpu (0);
/* Set up the root file system. */
rootdir = iget (rootdev, &mount[0].m_filsys, (ino_t) ROOTINO);
iunlock (rootdir);
u.u_cdir = iget (rootdev, &mount[0].m_filsys, (ino_t) ROOTINO);
iunlock (u.u_cdir);
u.u_rdir = NULL;
/*
* Make init process.
*/
if (newproc (0) == 0) {
/* Parent process with pid 0: swapper.
* No return from sched. */
sched();
}
/* Child process with pid 1: init. */
s = splhigh();
p = u.u_procp;
p->p_dsize = icodeend - icode;
p->p_daddr = USER_DATA_START;
p->p_ssize = 1024; /* one kbyte of stack */
p->p_saddr = USER_DATA_END - 1024;
bcopy ((caddr_t) icode, (caddr_t) USER_DATA_START, icodeend - icode);
/*
* return goes to location 0 of user init code
* just copied out.
*/
return 0;
}