* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
* %sccs.include.redist.c%
* @(#)init_main.c 7.43 (Berkeley) %G%
"Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll 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
;
* 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)
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_OFILE
].rlim_cur
= NOFILE
;
limit0
.pl_rlimit
[RLIMIT_NPROC
].rlim_cur
= MAXUPRC
;
* 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
;
* configure virtual memory system,
* Initialize the file systems.
* Get vnodes for swapdev and rootdev.
if (bdevvp(swapdev
, &swapdev_vp
) || bdevvp(rootdev
, &rootvp
))
panic("can't setup bdevvp's");
* Initialize tables, protocols, and set up well-known inodes.
* Block reception of incoming packets
* until protocols have been initialized.
/* kick off timeout driven events by calling first time */
enablertclock(); /* enable realtime clock interrupts */
* 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.
boottime
= p
->p_stats
->p_start
= time
;
if (fork(p
, (void *) NULL
, rval
))
static char initflags
[] = "-sf";
char *ip
= initflags
+ 1;
extern int icode
[]; /* user init code */
extern int szicode
; /* size of icode */
* Now in process 1. Set init flags into icode,
* get a minimal address space, copy out "icode",
* and return to it to do an exec of init.
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
)0, (unsigned)szicode
);
(void) copyout(initflags
, (caddr_t
)szicode
, sizeof(initflags
));
return; /* returns to icode */
* Start up pageout daemon (process 2).
if (fork(p
, (void *) NULL
, rval
))
p
->p_flag
|= SLOAD
|SSYS
; /* XXX */
bcopy("pagedaemon", curproc
->p_comm
, sizeof ("pagedaemon"));