version 1.248, 2005/06/23 00:30:28 |
version 1.248.2.1, 2006/06/21 15:09:37 |
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
__KERNEL_RCSID(0, "$NetBSD$"); |
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#include "fs_nfs.h" |
|
#include "opt_nfsserver.h" |
|
#include "opt_ipsec.h" |
#include "opt_ipsec.h" |
#include "opt_sysv.h" |
#include "opt_kcont.h" |
#include "opt_maxuprc.h" |
|
#include "opt_multiprocessor.h" |
#include "opt_multiprocessor.h" |
|
#include "opt_ntp.h" |
#include "opt_pipe.h" |
#include "opt_pipe.h" |
#include "opt_syscall_debug.h" |
|
#include "opt_systrace.h" |
|
#include "opt_posix.h" |
#include "opt_posix.h" |
#include "opt_kcont.h" |
#include "opt_syscall_debug.h" |
#include "opt_rootfs_magiclinks.h" |
#include "opt_sysv.h" |
|
#include "opt_verified_exec.h" |
|
|
#include "opencrypto.h" |
|
#include "rnd.h" |
#include "rnd.h" |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
Line 132 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 128 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#ifdef P1003_1B_SEMAPHORE |
#ifdef P1003_1B_SEMAPHORE |
#include <sys/ksem.h> |
#include <sys/ksem.h> |
#endif |
#endif |
#ifdef SYSTRACE |
|
#include <sys/systrace.h> |
|
#endif |
|
#include <sys/domain.h> |
#include <sys/domain.h> |
#include <sys/namei.h> |
#include <sys/namei.h> |
#if NOPENCRYPTO > 0 |
|
#include <opencrypto/cryptodev.h> /* XXX really the framework */ |
|
#endif |
|
#if NRND > 0 |
#if NRND > 0 |
#include <sys/rnd.h> |
#include <sys/rnd.h> |
#endif |
#endif |
Line 152 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 142 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#ifdef VERIFIED_EXEC |
#ifdef VERIFIED_EXEC |
#include <sys/verified_exec.h> |
#include <sys/verified_exec.h> |
#endif |
#endif |
|
#include <sys/kauth.h> |
|
#include <net80211/ieee80211_netbsd.h> |
|
|
#include <sys/syscall.h> |
#include <sys/syscall.h> |
#include <sys/sa.h> |
#include <sys/sa.h> |
Line 171 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 163 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <net/if.h> |
#include <net/if.h> |
#include <net/raw_cb.h> |
#include <net/raw_cb.h> |
|
|
/* Components of the first process -- never freed. */ |
extern struct proc proc0; |
struct session session0; |
extern struct lwp lwp0; |
struct pgrp pgrp0; |
extern struct cwdinfo cwdi0; |
struct proc proc0; |
|
struct lwp lwp0; |
|
struct pcred cred0; |
|
struct filedesc0 filedesc0; |
|
struct cwdinfo cwdi0; |
|
struct plimit limit0; |
|
struct pstats pstat0; |
|
struct vmspace vmspace0; |
|
struct sigacts sigacts0; |
|
#ifndef curlwp |
#ifndef curlwp |
struct lwp *curlwp = &lwp0; |
struct lwp *curlwp = &lwp0; |
#endif |
#endif |
struct proc *initproc; |
struct proc *initproc; |
|
|
int nofile = NOFILE; |
|
int maxuprc = MAXUPRC; |
|
int cmask = CMASK; |
|
extern struct user *proc0paddr; |
|
|
|
struct vnode *rootvp, *swapdev_vp; |
struct vnode *rootvp, *swapdev_vp; |
int boothowto; |
int boothowto; |
int cold = 1; /* still working on startup */ |
int cold = 1; /* still working on startup */ |
struct timeval boottime; |
#ifndef __HAVE_TIMECOUNTER |
|
struct timeval boottime; |
|
#endif |
time_t rootfstime; /* recorded root fs time, if known */ |
time_t rootfstime; /* recorded root fs time, if known */ |
|
|
__volatile int start_init_exec; /* semaphore for start_init() */ |
volatile int start_init_exec; /* semaphore for start_init() */ |
|
|
static void check_console(struct proc *p); |
static void check_console(struct lwp *l); |
static void start_init(void *); |
static void start_init(void *); |
void main(void); |
void main(void); |
|
|
extern const struct emul emul_netbsd; /* defined in kern_exec.c */ |
|
|
|
/* |
/* |
* System startup; initialize the world, create process 0, mount root |
* System startup; initialize the world, create process 0, mount root |
* filesystem, and fork to create init and pagedaemon. Most of the |
* filesystem, and fork to create init and pagedaemon. Most of the |
Line 216 extern const struct emul emul_netbsd; /* |
|
Line 195 extern const struct emul emul_netbsd; /* |
|
void |
void |
main(void) |
main(void) |
{ |
{ |
|
#ifdef __HAVE_TIMECOUNTER |
|
struct timeval time; |
|
#endif |
struct lwp *l; |
struct lwp *l; |
struct proc *p; |
struct proc *p; |
struct pdevinit *pdev; |
struct pdevinit *pdev; |
int s, error; |
int s, error; |
u_int i; |
|
rlim_t lim; |
|
extern struct pdevinit pdevinit[]; |
extern struct pdevinit pdevinit[]; |
extern void schedcpu(void *); |
extern void schedcpu(void *); |
#if defined(NFSSERVER) || defined(NFS) |
|
extern void nfs_init(void); |
|
#endif |
|
#ifdef NVNODE_IMPLICIT |
#ifdef NVNODE_IMPLICIT |
int usevnodes; |
int usevnodes; |
#endif |
#endif |
|
|
* The following things must be done before autoconfiguration. |
* The following things must be done before autoconfiguration. |
*/ |
*/ |
evcnt_init(); /* initialize event counters */ |
evcnt_init(); /* initialize event counters */ |
tty_init(); /* initialize tty list */ |
|
#if NRND > 0 |
#if NRND > 0 |
rnd_init(); /* initialize RNG */ |
rnd_init(); /* initialize RNG */ |
#endif |
#endif |
#if NOPENCRYPTO > 0 |
|
/* Initialize crypto subsystem before configuring crypto hardware. */ |
|
(void)crypto_init(); |
|
#endif |
|
/* Initialize the sysctl subsystem. */ |
/* Initialize the sysctl subsystem. */ |
sysctl_init(); |
sysctl_init(); |
|
|
/* Initialize process and pgrp structures. */ |
/* Initialize process and pgrp structures. */ |
procinit(); |
procinit(); |
|
|
#ifdef LKM |
/* Initialize signal-related data structures. */ |
/* Initialize the LKM system. */ |
signal_init(); |
lkm_init(); |
|
#endif |
|
|
|
/* |
|
* Create process 0 (the swapper). |
|
*/ |
|
p = &proc0; |
|
proc0_insert(p, l, &pgrp0, &session0); |
|
|
|
/* |
|
* Set P_NOCLDWAIT so that kernel threads are reparented to |
|
* init(8) when they exit. init(8) can easily wait them out |
|
* for us. |
|
*/ |
|
p->p_flag = P_SYSTEM | P_NOCLDWAIT; |
|
p->p_stat = SACTIVE; |
|
p->p_nice = NZERO; |
|
p->p_emul = &emul_netbsd; |
|
#ifdef __HAVE_SYSCALL_INTERN |
|
(*p->p_emul->e_syscall_intern)(p); |
|
#endif |
|
strncpy(p->p_comm, "swapper", MAXCOMLEN); |
|
|
|
l->l_flag = L_INMEM; |
|
l->l_stat = LSONPROC; |
|
p->p_nrlwps = 1; |
|
|
|
callout_init(&l->l_tsleep_ch); |
|
|
|
/* 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; |
|
fdinit1(&filedesc0); |
|
|
|
/* Create the CWD info. */ |
|
p->p_cwdi = &cwdi0; |
|
cwdi0.cwdi_cmask = cmask; |
|
cwdi0.cwdi_refcnt = 1; |
|
simple_lock_init(&cwdi0.cwdi_slock); |
|
|
|
/* Create the limits structures. */ |
|
p->p_limit = &limit0; |
|
simple_lock_init(&limit0.p_slock); |
|
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_max = maxfiles; |
|
limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = |
|
maxfiles < nofile ? maxfiles : nofile; |
|
|
|
limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; |
|
limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = |
|
maxproc < maxuprc ? maxproc : maxuprc; |
|
|
|
lim = ptoa(uvmexp.free); |
|
limit0.pl_rlimit[RLIMIT_RSS].rlim_max = lim; |
|
limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = lim; |
|
limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = lim / 3; |
|
limit0.pl_corename = defcorename; |
|
limit0.p_refcnt = 1; |
|
|
|
/* |
|
* Initialize proc0's vmspace, which uses the kernel pmap. |
|
* All kernel processes (which never have user space mappings) |
|
* share proc0's vmspace, and thus, the kernel pmap. |
|
*/ |
|
uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS), |
|
trunc_page(VM_MAX_ADDRESS)); |
|
p->p_vmspace = &vmspace0; |
|
|
|
l->l_addr = proc0paddr; /* XXX */ |
|
|
|
p->p_stats = &pstat0; |
/* Create process 0 (the swapper). */ |
|
proc0_init(); |
|
|
/* |
/* |
* Charge root for one process. |
* Charge root for one process. |
|
|
|
|
rqinit(); |
rqinit(); |
|
|
/* Configure virtual memory system, set vm rlimits. */ |
|
uvm_init_limits(p); |
|
|
|
/* Initialize the file systems. */ |
/* Initialize the file systems. */ |
#if defined(NFSSERVER) || defined(NFS) |
|
nfs_init(); /* initialize server/shared data */ |
|
#endif |
|
#ifdef NVNODE_IMPLICIT |
#ifdef NVNODE_IMPLICIT |
/* |
/* |
* If maximum number of vnodes in namei vnode cache is not explicitly |
* If maximum number of vnodes in namei vnode cache is not explicitly |
|
|
#endif |
#endif |
vfsinit(); |
vfsinit(); |
|
|
|
|
|
#ifdef __HAVE_TIMECOUNTER |
|
inittimecounter(); |
|
#ifdef NTP |
|
ntp_init(); |
|
#endif |
|
#endif /* __HAVE_TIMECOUNTER */ |
|
|
/* Configure the system hardware. This will enable interrupts. */ |
/* Configure the system hardware. This will enable interrupts. */ |
configure(); |
configure(); |
|
|
|
|
ksem_init(); |
ksem_init(); |
#endif |
#endif |
|
|
|
/* Initialize kauth. */ |
|
kauth_init(); |
|
|
#ifdef VERIFIED_EXEC |
#ifdef VERIFIED_EXEC |
/* |
/* |
* Initialise the fingerprint operations vectors before |
* Initialise the fingerprint operations vectors before |
|
|
*/ |
*/ |
veriexec_init_fp_ops(); |
veriexec_init_fp_ops(); |
#endif |
#endif |
|
|
/* Attach pseudo-devices. */ |
/* Attach pseudo-devices. */ |
for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++) |
for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++) |
(*pdev->pdev_attach)(pdev->pdev_count); |
(*pdev->pdev_attach)(pdev->pdev_count); |
|
|
/* Initialize system accouting. */ |
/* Initialize system accouting. */ |
acct_init(); |
acct_init(); |
|
|
#ifdef SYSTRACE |
|
systrace_init(); |
|
#endif |
|
/* |
|
* Initialize signal-related data structures, and signal state |
|
* for proc0. |
|
*/ |
|
signal_init(); |
|
p->p_sigacts = &sigacts0; |
|
siginit(p); |
|
|
|
/* Kick off timeout driven events by calling first time. */ |
/* Kick off timeout driven events by calling first time. */ |
schedcpu(NULL); |
schedcpu(NULL); |
|
|
|
|
inittodr(rootfstime); |
inittodr(rootfstime); |
|
|
CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS; |
CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS; |
#ifdef ROOTFS_MAGICLINKS |
|
CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_MAGICLINKS; |
|
#endif |
|
CIRCLEQ_FIRST(&mountlist)->mnt_op->vfs_refcount++; |
CIRCLEQ_FIRST(&mountlist)->mnt_op->vfs_refcount++; |
|
|
/* |
/* |
|
|
*/ |
*/ |
proclist_lock_read(); |
proclist_lock_read(); |
s = splsched(); |
s = splsched(); |
|
#ifdef __HAVE_TIMECOUNTER |
|
getmicrotime(&time); |
|
#else |
|
mono_time = time; |
|
#endif |
|
boottime = time; |
LIST_FOREACH(p, &allproc, p_list) { |
LIST_FOREACH(p, &allproc, p_list) { |
KASSERT((p->p_flag & P_MARKER) == 0); |
KASSERT((p->p_flag & P_MARKER) == 0); |
p->p_stats->p_start = mono_time = boottime = time; |
p->p_stats->p_start = time; |
LIST_FOREACH(l, &p->p_lwps, l_sibling) { |
LIST_FOREACH(l, &p->p_lwps, l_sibling) { |
if (l->l_cpu != NULL) |
if (l->l_cpu != NULL) |
l->l_cpu->ci_schedstate.spc_runtime = time; |
l->l_cpu->ci_schedstate.spc_runtime = time; |
Line 623 setrootfstime(time_t t) |
|
Line 516 setrootfstime(time_t t) |
|
} |
} |
|
|
static void |
static void |
check_console(struct proc *p) |
check_console(struct lwp *l) |
{ |
{ |
struct nameidata nd; |
struct nameidata nd; |
int error; |
int error; |
|
|
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p); |
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", l); |
error = namei(&nd); |
error = namei(&nd); |
if (error == 0) |
if (error == 0) |
vrele(nd.ni_vp); |
vrele(nd.ni_vp); |
Line 688 start_init(void *arg) |
|
Line 581 start_init(void *arg) |
|
* but that's a _lot_ more work, and the benefit from this easy |
* but that's a _lot_ more work, and the benefit from this easy |
* hack makes up for the "good is the enemy of the best" effect. |
* hack makes up for the "good is the enemy of the best" effect. |
*/ |
*/ |
check_console(p); |
check_console(l); |
|
|
/* |
/* |
* Need just enough stack to hold the faked-up "execve()" arguments. |
* Need just enough stack to hold the faked-up "execve()" arguments. |
Line 794 start_init(void *arg) |
|
Line 687 start_init(void *arg) |
|
* Now try to exec the program. If can't for any reason |
* Now try to exec the program. If can't for any reason |
* other than it doesn't exist, complain. |
* other than it doesn't exist, complain. |
*/ |
*/ |
error = sys_execve(LIST_FIRST(&p->p_lwps), &args, retval); |
error = sys_execve(l, &args, retval); |
if (error == 0 || error == EJUSTRETURN) { |
if (error == 0 || error == EJUSTRETURN) { |
KERNEL_PROC_UNLOCK(l); |
KERNEL_PROC_UNLOCK(l); |
return; |
return; |