Xinu7/src/serve11/sys/initialize.c

/* initialize.c - nulluser, sysinit */

#include <conf.h>
#include <kernel.h>
#include <proc.h>
#include <sem.h>
#include <sleep.h>
#include <mem.h>
#include <tty.h>
#include <q.h>
#include <io.h>
#include <disk.h>
#include <network.h>

extern	int	main();			/* address of user's main prog	*/

/* Declarations of major kernel variables */

struct	pentry	proctab[NPROC]; /* process table			*/
int	nextproc;		/* next process slot to use in create	*/
struct	sentry	semaph[NSEM];	/* semaphore table			*/
int	nextsem;		/* next semaphore slot to use in screate*/
struct	qent	q[NQENT];	/* q table (see queue.c)		*/
int	nextqueue;		/* next slot in q structure to use	*/
int	*maxaddr;		/* max memory address (set by sizmem)	*/
#ifdef	NDEVS
struct	intmap	intmap[NDEVS];	/* interrupt dispatch table		*/
#endif
struct	mblock	memlist;	/* list of free memory blocks		*/
#ifdef	Ntty
struct  tty     tty[Ntty];	/* SLU buffers and mode control		*/
#endif

/* active system status */

int	numproc;		/* number of live user processes	*/
int	currpid;		/* id of currently running process	*/
int	reboot = 0;		/* non-zero after first boot		*/

int	rdyhead,rdytail;	/* head/tail of ready list (q indexes)	*/
char	vers[] = VERSION;	/* Xinu version printed at startup	*/

/************************************************************************/
/***				NOTE:				      ***/
/***								      ***/
/***   This is where the system begins after the C environment has    ***/
/***   been established.  Interrupts are initially DISABLED, and      ***/
/***   must eventually be enabled explicitly.  This routine turns     ***/
/***   itself into the null process after initialization.  Because    ***/
/***   the null process must always remain ready to run, it cannot    ***/
/***   execute code that might cause it to be suspended, wait for a   ***/
/***   semaphore, or put to sleep, or exit.  In particular, it must   ***/
/***   not do I/O unless it uses kprintf for polled output.           ***/
/***								      ***/
/************************************************************************/

/*------------------------------------------------------------------------
 *  nulluser  -- initialize system and become the null process (id==0)
 *------------------------------------------------------------------------
 */
nulluser()				/* babysit CPU when no one home */
{
	int	userpid;
	char	ps;

	kprintf("\n\nXinu Version %s", vers);
	if (reboot++ < 1)
		kprintf("\n");
	else
		kprintf("   (reboot %d)\n", reboot);
	sysinit();			/* initialize all of Xinu */
	kprintf("%u real mem\n",(unsigned)maxaddr+(unsigned)sizeof(int));
	kprintf("%u avail mem\n",
		(unsigned)maxaddr-(unsigned)(&end)+(unsigned)sizeof(int));
	kprintf("clock %sabled\n\n", clkruns==1?"en":"dis");
	enable();			/* enable interrupts */

	/* create a process to execute the user's main program */

	userpid = create(main,INITSTK,INITPRIO,INITNAME,INITARGS);

#ifdef	NETDAEMON
	/* start the network input daemon process */
	resume(
	  create(NETIN, NETISTK, NETIPRI, NETINAM, NETIARGC, userpid)
	);
#else
	resume( userpid );
#endif

	while (TRUE) {			/* run forever without actually */
		pause();		/*  executing instructions	*/
	}
}

/*------------------------------------------------------------------------
 *  sysinit  --  initialize all Xinu data structures and devices
 *------------------------------------------------------------------------
 */
LOCAL	sysinit()
{
	int	i;
	struct	pentry	*pptr;
	struct	sentry	*sptr;
	struct	mblock	*mptr;

	numproc  = 0;			/* initialize system variables */
	nextproc = NPROC-1;
	nextsem  = NSEM-1;
	nextqueue= NPROC;		/* q[0..NPROC-1] are processes */

	memlist.mnext = mptr =		/* initialize free memory list */
	  (struct mblock *) roundew(&end);
	mptr->mnext = (struct mblock *)NULL;
	mptr->mlen = truncew((unsigned)maxaddr-NULLSTK-(unsigned)&end);

	for (i=0 ; i<NPROC ; i++)	/* initialize process table */
		proctab[i].pstate = PRFREE;

	pptr = &proctab[NULLPROC];	/* initialize null process entry */
	pptr->pstate = PRCURR;
	pptr->pprio = 0;
	strcpy(pptr->pname, "prnull");
	pptr->plimit = ( (int)maxaddr ) - NULLSTK - sizeof(int);
	pptr->pbase = maxaddr;
	*( (int *)pptr->pbase ) = MAGIC;
	pptr->paddr = nulluser;
	pptr->pargs = 0;
	currpid = NULLPROC;

	for (i=0 ; i<NSEM ; i++) {	/* initialize semaphores */
		(sptr = &semaph[i])->sstate = SFREE;
		sptr->sqtail = 1 + (sptr->sqhead = newqueue());
	}

	rdytail = 1 + (rdyhead=newqueue());/* initialize ready list */

#ifdef	MEMMARK
	_mkinit();			/* initialize memory marking */
#endif
#ifdef	RTCLOCK
	clkinit();			/* initialize r.t.clock	*/
#endif
#ifdef	Ndsk
	dskdbp= mkpool(DBUFSIZ,NDBUFF);	/* initialize disk buffers */
	dskrbp= mkpool(DREQSIZ,NDREQ);
#endif
	for ( i=0 ; i<NDEVS ; i++ )	/* initialize devices */
		init(i);
	return(OK);
}