ubc_init();
main(framep)	void *framep;				/* XXX should go away */{	register struct proc *p;	register struct pdevinit *pdev;	struct timeval rtv;	register int i;	int s;	register_t rval[2];	extern struct pdevinit pdevinit[];	extern void scheduler_start __P((void));	extern void disk_init __P((void));	extern void endtsleep __P((void *));	extern void realitexpire __P((void *));	/*	 * Initialize the current process pointer (curproc) before	 * any possible traps/probes to simplify trap processing.	 */	p = &proc0;	curproc = p;	/*	 * Attempt to find console and initialize	 * in case of early panic or other messages.	 */	config_init();		/* init autoconfiguration data structures */	consinit();	printf(copyright);	printf("\n");	uvm_init();	disk_init();		/* must come before autoconfiguration */	tty_init();		/* initialise tty's */	cpu_startup();	/*	 * Initialize mbuf's.  Do this now because we might attempt to	 * allocate mbufs or mbuf clusters during autoconfiguration.	 */	mbinit();	/* Initalize sockets. */	soinit();	/*	 * Initialize timeouts.	 */	timeout_startup();	cpu_configure();	ubc_init();		/* Initialize the unified buffer cache */	/* Initialize sysctls (must be done before any processes run) */	sysctl_init();	/*	 * Initialize process and pgrp structures.	 */	procinit();	/*	 * Initialize filedescriptors.	 */	filedesc_init();	/*	 * Initialize pipes.	 */	pipe_init();	/*	 * Create process 0 (the swapper).	 */	LIST_INSERT_HEAD(&allproc, p, p_list);	p->p_pgrp = &pgrp0;	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);	LIST_INIT(&pgrp0.pg_members);	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);	pgrp0.pg_session = &session0;	session0.s_count = 1;	session0.s_leader = p;	p->p_flag = P_INMEM | P_SYSTEM | P_NOCLDWAIT;	p->p_stat = SRUN;	p->p_nice = NZERO;	p->p_emul = &emul_native;	bcopy("swapper", p->p_comm, sizeof ("swapper"));	/* Init timeouts. */	timeout_set(&p->p_sleep_to, endtsleep, p);	timeout_set(&p->p_realit_to, realitexpire, p);	/* Create credentials. */	cred0.p_refcnt = 1;	p->p_cred = &cred0;	p->p_ucred = crget();	p->p_ucred->cr_ngroups = 1;	/* group 0 */	/* Create the file descriptor table. */	p->p_fd = &filedesc0.fd_fd;	filedesc0.fd_fd.fd_refcnt = 1;	filedesc0.fd_fd.fd_cmask = cmask;	filedesc0.fd_fd.fd_ofiles = filedesc0.fd_dfiles;	filedesc0.fd_fd.fd_ofileflags = filedesc0.fd_dfileflags;	filedesc0.fd_fd.fd_nfiles = NDFILE;	filedesc0.fd_fd.fd_himap = filedesc0.fd_dhimap;	filedesc0.fd_fd.fd_lomap = filedesc0.fd_dlomap;	/* Create the limits structures. */	p->p_limit = &limit0;	for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)		limit0.pl_rlimit[i].rlim_cur =		    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = MIN(NOFILE_MAX,	    (maxfiles - NOFILE > NOFILE) ?  maxfiles - NOFILE : NOFILE);	limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;	i = ptoa(uvmexp.free);	limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;	limit0.p_refcnt = 1;	/* Allocate a prototype map so we have something to fork. */	uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),	    trunc_page(VM_MAX_ADDRESS));	p->p_vmspace = &vmspace0;	p->p_addr = proc0paddr;				/* XXX */	/*	 * We continue to place resource usage info in the	 * user struct so they're pageable.	 */	p->p_stats = &p->p_addr->u_stats;	/*	 * Charge root for one process.	 */	(void)chgproccnt(0, 1);	rqinit();	/* Configure virtual memory system, set vm rlimits. */	uvm_init_limits(p);	/* Initialize the file systems. */#if defined(NFSSERVER) || defined(NFSCLIENT)	nfs_init();			/* initialize server/shared data */#endif	vfsinit();	/* Start real time and statistics clocks. */	initclocks();#ifdef SYSVSHM	/* Initialize System V style shared memory. */	shminit();#endif#ifdef SYSVSEM	/* Initialize System V style semaphores. */	seminit();#endif#ifdef SYSVMSG	/* Initialize System V style message queues. */	msginit();#endif	/* Attach pseudo-devices. */	randomattach();	for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)		if (pdev->pdev_count > 0)			(*pdev->pdev_attach)(pdev->pdev_count);#ifdef CRYPTO	swcr_init();#endif /* CRYPTO */		/*	 * Initialize protocols.  Block reception of incoming packets	 * until everything is ready.	 */	s = splimp();	ifinit();	domaininit();	splx(s);#ifdef GPROF	/* Initialize kernel profiling. */	kmstartup();#endif	/* Start the scheduler */	scheduler_start();	/* Initialize signal state for process 0. */	signal_init();	p->p_sigacts = &sigacts0;	siginit(p);	dostartuphooks();	/* Configure root/swap devices */	if (md_diskconf)		(*md_diskconf)();	/* Mount the root file system. */	if (vfs_mountroot())		panic("cannot mount root");	CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS;	/* Get the vnode for '/'.  Set filedesc0.fd_fd.fd_cdir to reference it. */	if (VFS_ROOT(mountlist.cqh_first, &rootvnode))		panic("cannot find root vnode");	filedesc0.fd_fd.fd_cdir = rootvnode;	VREF(filedesc0.fd_fd.fd_cdir);	VOP_UNLOCK(rootvnode, 0, p);	filedesc0.fd_fd.fd_rdir = NULL;	uvm_swap_init();	/*	 * Now can look at time, having had a chance to verify the time	 * from the file system.  Reset p->p_rtime as it may have been	 * munched in mi_switch() after the time got set.	 */	p->p_stats->p_start = runtime = mono_time = boottime = time;	p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;	/* Create process 1 (init(8)). */	if (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, start_init, NULL, rval))		panic("fork init");	/* Create process 2, the pageout daemon kernel thread. */	if (kthread_create(uvm_pageout, NULL, NULL, "pagedaemon"))		panic("fork pagedaemon");	/* Create process 3, the reaper daemon kernel thread. */	if (kthread_create(start_reaper, NULL, NULL, "reaper"))		panic("fork reaper");	/* Create process 4, the cleaner daemon kernel thread. */	if (kthread_create(start_cleaner, NULL, NULL, "cleaner"))		panic("fork cleaner");	/* Create process 5, the update daemon kernel thread. */	if (kthread_create(start_update, NULL, NULL, "update"))		panic("fork update");	/* Create process 6, the aiodone daemon kernel thread. */ 	if (kthread_create(uvm_aiodone_daemon, NULL, NULL, "aiodoned"))		panic("fork aiodoned");#ifdef CRYPTO	/* Create process 7, the crypto kernel thread. */	if (kthread_create(start_crypto, NULL, NULL, "crypto"))		panic("crypto thread");#endif /* CRYPTO */	/* Create any other deferred kernel threads. */	kthread_run_deferred_queue();	microtime(&rtv);	srandom((u_long)(rtv.tv_sec ^ rtv.tv_usec));	randompid = 1;	/* The scheduler is an infinite loop. */	uvm_scheduler();	/* NOTREACHED */}