* Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
* @(#)init_main.c 8.1 (Berkeley) %G%
#include <sys/filedesc.h>
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n";
"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n";
* Components of process 0;
struct filedesc0 filedesc0
;
struct proc
*curproc
= &proc0
;
struct proc
*initproc
, *pageproc
;
extern struct user
*proc0paddr
;
extern int (*mountroot
)();
struct vnode
*rootvp
, *swapdev_vp
;
* System startup; initialize the world, create process 0,
* mount root filesystem, and fork to create init and pagedaemon.
* Most of the hard work is done in the lower-level initialization
* routines including startup(), which does memory initialization
register struct filedesc0
*fdp
;
register struct pdevinit
*pdev
;
extern struct pdevinit pdevinit
[];
extern void roundrobin
__P((void *));
extern void schedcpu
__P((void *));
* Initialize curproc before any possible traps/probes
* to simplify trap processing.
* Attempt to find console and initialize
* in case of early panic or other messages.
* set up system process 0 (swapper)
allproc
= (volatile struct proc
*)p
;
p
->p_prev
= (struct proc
**)&allproc
;
pgrp0
.pg_session
= &session0
;
bcopy("swapper", p
->p_comm
, sizeof ("swapper"));
p
->p_ucred
->cr_ngroups
= 1; /* group 0 */
* Create the file descriptor table for process 0.
fdp
->fd_fd
.fd_refcnt
= 1;
fdp
->fd_fd
.fd_cmask
= cmask
;
fdp
->fd_fd
.fd_ofiles
= fdp
->fd_dfiles
;
fdp
->fd_fd
.fd_ofileflags
= fdp
->fd_dfileflags
;
fdp
->fd_fd
.fd_nfiles
= NDFILE
;
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_NPROC
].rlim_cur
= MAXUPRC
;
i
= ptoa(cnt
.v_free_count
);
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;
* Allocate a prototype map so we have something to fork
p
->p_vmspace
= &vmspace0
;
pmap_pinit(&vmspace0
.vm_pmap
);
vm_map_init(&p
->p_vmspace
->vm_map
, round_page(VM_MIN_ADDRESS
),
trunc_page(VM_MAX_ADDRESS
), TRUE
);
vmspace0
.vm_map
.pmap
= &vmspace0
.vm_pmap
;
p
->p_addr
= proc0paddr
; /* XXX */
* We continue to place resource usage info
* and signal actions in the user struct so they're pageable.
p
->p_stats
= &p
->p_addr
->u_stats
;
p
->p_sigacts
= &p
->p_addr
->u_sigacts
;
* Initialize per uid information structure and charge
/* Configure virtual memory system, set vm rlimits. */
/* Initialize the file systems. */
/* Start real time and statistics clocks. */
/* Attach pseudo-devices. */
for (pdev
= pdevinit
; pdev
->pdev_attach
!= NULL
; pdev
++)
(*pdev
->pdev_attach
)(pdev
->pdev_count
);
* Initialize protocols. Block reception of incoming packets
* until everything is ready.
/* kick off timeout driven events by calling first time */
* Set up the root file system and vnode.
panic("cannot mount root");
* Setup rootdir and fdp->fd_fd.fd_cdir to point to it.
if (VFS_ROOT(rootfs
, &rootdir
))
panic("cannot find root vnode");
fdp
->fd_fd
.fd_cdir
= rootdir
;
VREF(fdp
->fd_fd
.fd_cdir
);
fdp
->fd_fd
.fd_rdir
= NULL
;
* 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 swtch() 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;
extern int icode
[]; /* user init code */
extern int szicode
; /* size of icode */
static char initflags
[] = "-sf";
* Now in process 1. Set init flags into icode, get a minimal
* address space, copy out "icode", and return to it to do an
if (boothowto
&RB_FASTBOOT
)
if (vm_allocate(&p
->p_vmspace
->vm_map
, &addr
,
round_page(szicode
+ sizeof(initflags
)), FALSE
) != 0 ||
panic("init: couldn't allocate at zero");
/* need just enough stack to exec from */
addr
= trunc_page(USRSTACK
- PAGE_SIZE
);
if (vm_allocate(&p
->p_vmspace
->vm_map
, &addr
,
PAGE_SIZE
, FALSE
) != KERN_SUCCESS
)
panic("vm_allocate init stack");
p
->p_vmspace
->vm_maxsaddr
= (caddr_t
)addr
;
(void)copyout((caddr_t
)icode
, (caddr_t
)VM_MIN_ADDRESS
,
(void)copyout(initflags
, (caddr_t
)(VM_MIN_ADDRESS
+ szicode
),
return; /* returns to icode */
* Start up pageout daemon (process 2).
p
->p_flag
|= SLOAD
|SSYS
; /* XXX */
bcopy("pagedaemon", curproc
->p_comm
, sizeof ("pagedaemon"));