1a9643ea8Slogwang /*-
2a9643ea8Slogwang * Copyright (c) 1995 Terrence R. Lambert
3a9643ea8Slogwang * All rights reserved.
4a9643ea8Slogwang *
5a9643ea8Slogwang * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
6a9643ea8Slogwang * The Regents of the University of California. All rights reserved.
7a9643ea8Slogwang * (c) UNIX System Laboratories, Inc.
8a9643ea8Slogwang * All or some portions of this file are derived from material licensed
9a9643ea8Slogwang * to the University of California by American Telephone and Telegraph
10a9643ea8Slogwang * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11a9643ea8Slogwang * the permission of UNIX System Laboratories, Inc.
12a9643ea8Slogwang *
13a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without
14a9643ea8Slogwang * modification, are permitted provided that the following conditions
15a9643ea8Slogwang * are met:
16a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright
17a9643ea8Slogwang * notice, this list of conditions and the following disclaimer.
18a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright
19a9643ea8Slogwang * notice, this list of conditions and the following disclaimer in the
20a9643ea8Slogwang * documentation and/or other materials provided with the distribution.
21a9643ea8Slogwang * 3. All advertising materials mentioning features or use of this software
22a9643ea8Slogwang * must display the following acknowledgement:
23a9643ea8Slogwang * This product includes software developed by the University of
24a9643ea8Slogwang * California, Berkeley and its contributors.
25a9643ea8Slogwang * 4. Neither the name of the University nor the names of its contributors
26a9643ea8Slogwang * may be used to endorse or promote products derived from this software
27a9643ea8Slogwang * without specific prior written permission.
28a9643ea8Slogwang *
29a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31a9643ea8Slogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32a9643ea8Slogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33a9643ea8Slogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34a9643ea8Slogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35a9643ea8Slogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36a9643ea8Slogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37a9643ea8Slogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38a9643ea8Slogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39a9643ea8Slogwang * SUCH DAMAGE.
40a9643ea8Slogwang *
41a9643ea8Slogwang * @(#)init_main.c 8.9 (Berkeley) 1/21/94
42a9643ea8Slogwang */
43a9643ea8Slogwang
44a9643ea8Slogwang #include <sys/cdefs.h>
45a9643ea8Slogwang __FBSDID("$FreeBSD$");
46a9643ea8Slogwang
47a9643ea8Slogwang #include "opt_ddb.h"
48a9643ea8Slogwang
49a9643ea8Slogwang #include <sys/param.h>
50a9643ea8Slogwang #include <sys/kernel.h>
51a9643ea8Slogwang #include <sys/exec.h>
52a9643ea8Slogwang #include <sys/file.h>
53a9643ea8Slogwang #include <sys/filedesc.h>
54a9643ea8Slogwang #include <sys/jail.h>
55a9643ea8Slogwang #include <sys/ktr.h>
56a9643ea8Slogwang #include <sys/lock.h>
57a9643ea8Slogwang #include <sys/mount.h>
58a9643ea8Slogwang #include <sys/mutex.h>
59a9643ea8Slogwang #include <sys/syscallsubr.h>
60a9643ea8Slogwang #include <sys/sysctl.h>
61a9643ea8Slogwang #include <sys/proc.h>
62a9643ea8Slogwang #include <sys/resourcevar.h>
63a9643ea8Slogwang #include <sys/systm.h>
64a9643ea8Slogwang #include <sys/signalvar.h>
65a9643ea8Slogwang #include <sys/sysent.h>
66a9643ea8Slogwang #include <sys/reboot.h>
67a9643ea8Slogwang #include <sys/sched.h>
68a9643ea8Slogwang #include <sys/sx.h>
69a9643ea8Slogwang #include <sys/sysproto.h>
70a9643ea8Slogwang #include <sys/vmmeter.h>
71a9643ea8Slogwang #include <sys/unistd.h>
72a9643ea8Slogwang #include <sys/malloc.h>
73a9643ea8Slogwang #include <sys/conf.h>
74a9643ea8Slogwang #include <sys/cpuset.h>
75*22ce4affSfengbojiang #include <sys/eventhandler.h>
76a9643ea8Slogwang
77a9643ea8Slogwang #include <machine/cpu.h>
78a9643ea8Slogwang
79a9643ea8Slogwang #include <security/audit/audit.h>
80a9643ea8Slogwang #include <security/mac/mac_framework.h>
81a9643ea8Slogwang
82a9643ea8Slogwang #include <vm/vm.h>
83a9643ea8Slogwang #include <vm/vm_param.h>
84a9643ea8Slogwang #include <vm/pmap.h>
85a9643ea8Slogwang #include <vm/vm_map.h>
86a9643ea8Slogwang #include <sys/copyright.h>
87a9643ea8Slogwang
88a9643ea8Slogwang #include <ddb/ddb.h>
89a9643ea8Slogwang #include <ddb/db_sym.h>
90a9643ea8Slogwang
91a9643ea8Slogwang void mi_startup(void); /* Should be elsewhere */
92a9643ea8Slogwang
93a9643ea8Slogwang /* Components of the first process -- never freed. */
94a9643ea8Slogwang struct proc proc0;
95a9643ea8Slogwang struct prison prison0;
96a9643ea8Slogwang struct thread0_storage thread0_st __aligned(16);
97a9643ea8Slogwang struct vmspace vmspace0;
98a9643ea8Slogwang struct proc *initproc;
99a9643ea8Slogwang #if 0
100a9643ea8Slogwang int boothowto = 0; /* initialized so that it can be patched */
101a9643ea8Slogwang SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
102a9643ea8Slogwang int bootverbose;
103a9643ea8Slogwang SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
104a9643ea8Slogwang #endif
105a9643ea8Slogwang
106a9643ea8Slogwang //#define VERBOSE_SYSINIT
107a9643ea8Slogwang
108a9643ea8Slogwang
109a9643ea8Slogwang /*
110a9643ea8Slogwang * This ensures that there is at least one entry so that the sysinit_set
111a9643ea8Slogwang * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never
112a9643ea8Slogwang * executed.
113a9643ea8Slogwang */
114a9643ea8Slogwang SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL);
115a9643ea8Slogwang
116a9643ea8Slogwang /*
117a9643ea8Slogwang * The sysinit table itself. Items are checked off as the are run.
118a9643ea8Slogwang * If we want to register new sysinit types, add them to newsysinit.
119a9643ea8Slogwang */
120a9643ea8Slogwang SET_DECLARE(sysinit_set, struct sysinit);
121a9643ea8Slogwang struct sysinit **sysinit, **sysinit_end;
122a9643ea8Slogwang struct sysinit **newsysinit, **newsysinit_end;
123a9643ea8Slogwang
124a9643ea8Slogwang /*
125a9643ea8Slogwang * Merge a new sysinit set into the current set, reallocating it if
126a9643ea8Slogwang * necessary. This can only be called after malloc is running.
127a9643ea8Slogwang */
128a9643ea8Slogwang void
sysinit_add(struct sysinit ** set,struct sysinit ** set_end)129a9643ea8Slogwang sysinit_add(struct sysinit **set, struct sysinit **set_end)
130a9643ea8Slogwang {
131a9643ea8Slogwang struct sysinit **newset;
132a9643ea8Slogwang struct sysinit **sipp;
133a9643ea8Slogwang struct sysinit **xipp;
134a9643ea8Slogwang int count;
135a9643ea8Slogwang
136a9643ea8Slogwang count = set_end - set;
137a9643ea8Slogwang if (newsysinit)
138a9643ea8Slogwang count += newsysinit_end - newsysinit;
139a9643ea8Slogwang else
140a9643ea8Slogwang count += sysinit_end - sysinit;
141a9643ea8Slogwang newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
142a9643ea8Slogwang if (newset == NULL)
143a9643ea8Slogwang panic("cannot malloc for sysinit");
144a9643ea8Slogwang xipp = newset;
145a9643ea8Slogwang if (newsysinit)
146a9643ea8Slogwang for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
147a9643ea8Slogwang *xipp++ = *sipp;
148a9643ea8Slogwang else
149a9643ea8Slogwang for (sipp = sysinit; sipp < sysinit_end; sipp++)
150a9643ea8Slogwang *xipp++ = *sipp;
151a9643ea8Slogwang for (sipp = set; sipp < set_end; sipp++)
152a9643ea8Slogwang *xipp++ = *sipp;
153a9643ea8Slogwang if (newsysinit)
154a9643ea8Slogwang free(newsysinit, M_TEMP);
155a9643ea8Slogwang newsysinit = newset;
156a9643ea8Slogwang newsysinit_end = newset + count;
157a9643ea8Slogwang }
158a9643ea8Slogwang
159a9643ea8Slogwang
160a9643ea8Slogwang /*
161a9643ea8Slogwang * System startup; initialize the world, create process 0, mount root
162a9643ea8Slogwang * filesystem, and fork to create init and pagedaemon. Most of the
163a9643ea8Slogwang * hard work is done in the lower-level initialization routines including
164a9643ea8Slogwang * startup(), which does memory initialization and autoconfiguration.
165a9643ea8Slogwang *
166a9643ea8Slogwang * This allows simple addition of new kernel subsystems that require
167a9643ea8Slogwang * boot time initialization. It also allows substitution of subsystem
168a9643ea8Slogwang * (for instance, a scheduler, kernel profiler, or VM system) by object
169a9643ea8Slogwang * module. Finally, it allows for optional "kernel threads".
170a9643ea8Slogwang */
171a9643ea8Slogwang void
mi_startup(void)172a9643ea8Slogwang mi_startup(void)
173a9643ea8Slogwang {
174a9643ea8Slogwang
175a9643ea8Slogwang register struct sysinit **sipp; /* system initialization*/
176a9643ea8Slogwang register struct sysinit **xipp; /* interior loop of sort*/
177a9643ea8Slogwang register struct sysinit *save; /* bubble*/
178a9643ea8Slogwang struct sysinit **temp;
179a9643ea8Slogwang int size;
180a9643ea8Slogwang
181a9643ea8Slogwang #ifdef VERBOSE_SYSINIT
182a9643ea8Slogwang int last;
183a9643ea8Slogwang int verbose;
184a9643ea8Slogwang #endif
185a9643ea8Slogwang
186a9643ea8Slogwang if (sysinit == NULL) {
187a9643ea8Slogwang sysinit = SET_BEGIN(sysinit_set);
188a9643ea8Slogwang sysinit_end = SET_LIMIT(sysinit_set);
189a9643ea8Slogwang size = (uintptr_t)sysinit_end - (uintptr_t)sysinit;
190a9643ea8Slogwang temp = malloc(size, M_DEVBUF, M_WAITOK);
191a9643ea8Slogwang memcpy(temp, sysinit, size);
192a9643ea8Slogwang sysinit = temp;
193a9643ea8Slogwang sysinit_end = (struct sysinit **)(((uint8_t *)sysinit) + size);
194a9643ea8Slogwang }
195a9643ea8Slogwang
196a9643ea8Slogwang restart:
197a9643ea8Slogwang /*
198a9643ea8Slogwang * Perform a bubble sort of the system initialization objects by
199a9643ea8Slogwang * their subsystem (primary key) and order (secondary key).
200a9643ea8Slogwang */
201a9643ea8Slogwang for (sipp = sysinit; sipp < sysinit_end; sipp++) {
202a9643ea8Slogwang for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
203a9643ea8Slogwang if ((*sipp)->subsystem < (*xipp)->subsystem ||
204a9643ea8Slogwang ((*sipp)->subsystem == (*xipp)->subsystem &&
205a9643ea8Slogwang (*sipp)->order <= (*xipp)->order))
206a9643ea8Slogwang continue; /* skip*/
207a9643ea8Slogwang save = *sipp;
208a9643ea8Slogwang *sipp = *xipp;
209a9643ea8Slogwang *xipp = save;
210a9643ea8Slogwang }
211a9643ea8Slogwang }
212a9643ea8Slogwang
213a9643ea8Slogwang #ifdef VERBOSE_SYSINIT
214a9643ea8Slogwang last = SI_SUB_COPYRIGHT;
215a9643ea8Slogwang verbose = 0;
216a9643ea8Slogwang #ifndef DDB
217a9643ea8Slogwang printf("VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n");
218a9643ea8Slogwang #endif
219a9643ea8Slogwang #endif
220a9643ea8Slogwang
221a9643ea8Slogwang /*
222a9643ea8Slogwang * Traverse the (now) ordered list of system initialization tasks.
223a9643ea8Slogwang * Perform each task, and continue on to the next task.
224a9643ea8Slogwang *
225a9643ea8Slogwang * The last item on the list is expected to be the scheduler,
226a9643ea8Slogwang * which will not return.
227a9643ea8Slogwang */
228a9643ea8Slogwang for (sipp = sysinit; sipp < sysinit_end; sipp++) {
229a9643ea8Slogwang
230a9643ea8Slogwang if ((*sipp)->subsystem == SI_SUB_DUMMY)
231a9643ea8Slogwang continue; /* skip dummy task(s)*/
232a9643ea8Slogwang
233a9643ea8Slogwang if ((*sipp)->subsystem == SI_SUB_DONE)
234a9643ea8Slogwang continue;
235a9643ea8Slogwang
236a9643ea8Slogwang #ifdef VERBOSE_SYSINIT
237a9643ea8Slogwang if ((*sipp)->subsystem > last) {
238a9643ea8Slogwang verbose = 1;
239a9643ea8Slogwang last = (*sipp)->subsystem;
240a9643ea8Slogwang printf("subsystem %x\n", last);
241a9643ea8Slogwang }
242a9643ea8Slogwang if (verbose) {
243a9643ea8Slogwang #ifdef DDB
244a9643ea8Slogwang const char *name;
245a9643ea8Slogwang c_db_sym_t sym;
246a9643ea8Slogwang db_expr_t offset;
247a9643ea8Slogwang
248a9643ea8Slogwang sym = db_search_symbol((vm_offset_t)(*sipp)->func,
249a9643ea8Slogwang DB_STGY_PROC, &offset);
250a9643ea8Slogwang db_symbol_values(sym, &name, NULL);
251a9643ea8Slogwang if (name != NULL)
252a9643ea8Slogwang printf(" %s(%p)... ", name, (*sipp)->udata);
253a9643ea8Slogwang else
254a9643ea8Slogwang #endif
255a9643ea8Slogwang printf(" %p(%p)... ", (*sipp)->func,
256a9643ea8Slogwang (*sipp)->udata);
257a9643ea8Slogwang }
258a9643ea8Slogwang #endif
259a9643ea8Slogwang
260a9643ea8Slogwang /* Call function */
261a9643ea8Slogwang (*((*sipp)->func))((*sipp)->udata);
262a9643ea8Slogwang
263a9643ea8Slogwang #ifdef VERBOSE_SYSINIT
264a9643ea8Slogwang if (verbose)
265a9643ea8Slogwang printf("done.\n");
266a9643ea8Slogwang #endif
267a9643ea8Slogwang
268a9643ea8Slogwang /* Check off the one we're just done */
269a9643ea8Slogwang (*sipp)->subsystem = SI_SUB_DONE;
270a9643ea8Slogwang
271a9643ea8Slogwang /* Check if we've installed more sysinit items via KLD */
272a9643ea8Slogwang if (newsysinit != NULL) {
273a9643ea8Slogwang if (sysinit != SET_BEGIN(sysinit_set))
274a9643ea8Slogwang free(sysinit, M_TEMP);
275a9643ea8Slogwang sysinit = newsysinit;
276a9643ea8Slogwang sysinit_end = newsysinit_end;
277a9643ea8Slogwang newsysinit = NULL;
278a9643ea8Slogwang newsysinit_end = NULL;
279a9643ea8Slogwang goto restart;
280a9643ea8Slogwang }
281a9643ea8Slogwang }
282a9643ea8Slogwang
283a9643ea8Slogwang }
284a9643ea8Slogwang
285a9643ea8Slogwang static int
null_fetch_syscall_args(struct thread * td __unused)286*22ce4affSfengbojiang null_fetch_syscall_args(struct thread *td __unused)
287a9643ea8Slogwang {
288a9643ea8Slogwang
289a9643ea8Slogwang panic("null_fetch_syscall_args");
290a9643ea8Slogwang }
291a9643ea8Slogwang
292a9643ea8Slogwang static void
null_set_syscall_retval(struct thread * td __unused,int error __unused)293a9643ea8Slogwang null_set_syscall_retval(struct thread *td __unused, int error __unused)
294a9643ea8Slogwang {
295a9643ea8Slogwang
296a9643ea8Slogwang panic("null_set_syscall_retval");
297a9643ea8Slogwang }
298a9643ea8Slogwang
299a9643ea8Slogwang struct sysentvec null_sysvec = {
300a9643ea8Slogwang .sv_size = 0,
301a9643ea8Slogwang .sv_table = NULL,
302a9643ea8Slogwang .sv_transtrap = NULL,
303a9643ea8Slogwang .sv_fixup = NULL,
304a9643ea8Slogwang .sv_sendsig = NULL,
305a9643ea8Slogwang .sv_sigcode = NULL,
306a9643ea8Slogwang .sv_szsigcode = NULL,
307a9643ea8Slogwang .sv_name = "null",
308a9643ea8Slogwang .sv_coredump = NULL,
309a9643ea8Slogwang .sv_imgact_try = NULL,
310a9643ea8Slogwang .sv_minsigstksz = 0,
311a9643ea8Slogwang .sv_minuser = VM_MIN_ADDRESS,
312a9643ea8Slogwang .sv_maxuser = VM_MAXUSER_ADDRESS,
313a9643ea8Slogwang .sv_usrstack = USRSTACK,
314a9643ea8Slogwang .sv_psstrings = PS_STRINGS,
315a9643ea8Slogwang .sv_stackprot = VM_PROT_ALL,
316a9643ea8Slogwang .sv_copyout_strings = NULL,
317a9643ea8Slogwang .sv_setregs = NULL,
318a9643ea8Slogwang .sv_fixlimit = NULL,
319a9643ea8Slogwang .sv_maxssiz = NULL,
320a9643ea8Slogwang .sv_flags = 0,
321a9643ea8Slogwang .sv_set_syscall_retval = null_set_syscall_retval,
322a9643ea8Slogwang .sv_fetch_syscall_args = null_fetch_syscall_args,
323a9643ea8Slogwang .sv_syscallnames = NULL,
324a9643ea8Slogwang .sv_schedtail = NULL,
325a9643ea8Slogwang .sv_thread_detach = NULL,
326a9643ea8Slogwang .sv_trap = NULL,
327a9643ea8Slogwang
328a9643ea8Slogwang };
329a9643ea8Slogwang
330a9643ea8Slogwang /*
331a9643ea8Slogwang ***************************************************************************
332a9643ea8Slogwang ****
333a9643ea8Slogwang **** The two following SYSINIT's are proc0 specific glue code. I am not
334a9643ea8Slogwang **** convinced that they can not be safely combined, but their order of
335a9643ea8Slogwang **** operation has been maintained as the same as the original init_main.c
336a9643ea8Slogwang **** for right now.
337a9643ea8Slogwang ****
338a9643ea8Slogwang **** These probably belong in init_proc.c or kern_proc.c, since they
339a9643ea8Slogwang **** deal with proc0 (the fork template process).
340a9643ea8Slogwang ****
341a9643ea8Slogwang ***************************************************************************
342a9643ea8Slogwang */
343a9643ea8Slogwang /* ARGSUSED*/
344a9643ea8Slogwang static void
proc0_init(void * dummy __unused)345a9643ea8Slogwang proc0_init(void *dummy __unused)
346a9643ea8Slogwang {
347a9643ea8Slogwang struct proc *p;
348a9643ea8Slogwang struct thread *td;
349a9643ea8Slogwang
350a9643ea8Slogwang vm_paddr_t pageablemem;
351a9643ea8Slogwang int i;
352a9643ea8Slogwang
353a9643ea8Slogwang GIANT_REQUIRED;
354a9643ea8Slogwang
355a9643ea8Slogwang p = &proc0;
356a9643ea8Slogwang td = &thread0;
357a9643ea8Slogwang init_param1();
358a9643ea8Slogwang init_param2(physmem);
359a9643ea8Slogwang
360a9643ea8Slogwang /*
361a9643ea8Slogwang * Initialize magic number and osrel.
362a9643ea8Slogwang */
363a9643ea8Slogwang p->p_magic = P_MAGIC;
364a9643ea8Slogwang
365a9643ea8Slogwang #if 0
366a9643ea8Slogwang p->p_osrel = osreldate;
367a9643ea8Slogwang
368a9643ea8Slogwang
369a9643ea8Slogwang /*
370a9643ea8Slogwang * Initialize thread and process structures.
371a9643ea8Slogwang */
372a9643ea8Slogwang procinit(); /* set up proc zone */
373a9643ea8Slogwang threadinit(); /* set up UMA zones */
374a9643ea8Slogwang
375a9643ea8Slogwang /*
376a9643ea8Slogwang * Initialise scheduler resources.
377a9643ea8Slogwang * Add scheduler specific parts to proc, thread as needed.
378a9643ea8Slogwang */
379a9643ea8Slogwang schedinit(); /* scheduler gets its house in order */
380a9643ea8Slogwang /*
381a9643ea8Slogwang * Initialize sleep queue hash table
382a9643ea8Slogwang */
383a9643ea8Slogwang sleepinit();
384a9643ea8Slogwang
385a9643ea8Slogwang /*
386a9643ea8Slogwang * additional VM structures
387a9643ea8Slogwang */
388a9643ea8Slogwang vm_init2();
389a9643ea8Slogwang
390a9643ea8Slogwang /*
391a9643ea8Slogwang * Create process 0 (the swapper).
392a9643ea8Slogwang */
393a9643ea8Slogwang LIST_INSERT_HEAD(&allproc, p, p_list);
394a9643ea8Slogwang LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
395a9643ea8Slogwang mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
396a9643ea8Slogwang p->p_pgrp = &pgrp0;
397a9643ea8Slogwang LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
398a9643ea8Slogwang LIST_INIT(&pgrp0.pg_members);
399a9643ea8Slogwang LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
400a9643ea8Slogwang
401a9643ea8Slogwang pgrp0.pg_session = &session0;
402a9643ea8Slogwang
403a9643ea8Slogwang mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
404a9643ea8Slogwang refcount_init(&session0.s_count, 1);
405a9643ea8Slogwang session0.s_leader = p;
406a9643ea8Slogwang #endif
407a9643ea8Slogwang p->p_sysent = &null_sysvec;
408a9643ea8Slogwang p->p_flag = P_SYSTEM | P_INMEM;
409a9643ea8Slogwang p->p_state = PRS_NORMAL;
410a9643ea8Slogwang p->p_klist = knlist_alloc(&p->p_mtx);
411a9643ea8Slogwang STAILQ_INIT(&p->p_ktr);
412a9643ea8Slogwang p->p_nice = NZERO;
413a9643ea8Slogwang td->td_tid = PID_MAX + 1;
414a9643ea8Slogwang #if 0
415a9643ea8Slogwang LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash);
416a9643ea8Slogwang #endif
417a9643ea8Slogwang td->td_state = TDS_RUNNING;
418a9643ea8Slogwang td->td_pri_class = PRI_TIMESHARE;
419a9643ea8Slogwang td->td_user_pri = PUSER;
420a9643ea8Slogwang td->td_base_user_pri = PUSER;
421a9643ea8Slogwang td->td_priority = PVM;
422a9643ea8Slogwang td->td_base_pri = PUSER;
423a9643ea8Slogwang td->td_oncpu = 0;
424a9643ea8Slogwang td->td_flags = TDF_INMEM|TDP_KTHREAD;
425a9643ea8Slogwang td->td_proc = p;
426a9643ea8Slogwang #if 0
427a9643ea8Slogwang td->td_cpuset = cpuset_thread0();
428a9643ea8Slogwang prison0.pr_cpuset = cpuset_ref(td->td_cpuset);
429a9643ea8Slogwang #endif
430a9643ea8Slogwang p->p_peers = 0;
431a9643ea8Slogwang p->p_leader = p;
432a9643ea8Slogwang
433a9643ea8Slogwang
434a9643ea8Slogwang strncpy(p->p_comm, "kernel", sizeof (p->p_comm));
435a9643ea8Slogwang strncpy(td->td_name, "swapper", sizeof (td->td_name));
436a9643ea8Slogwang
437a9643ea8Slogwang callout_init(&p->p_itcallout, CALLOUT_MPSAFE);
438a9643ea8Slogwang callout_init_mtx(&p->p_limco, &p->p_mtx, 0);
439a9643ea8Slogwang callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
440a9643ea8Slogwang
441a9643ea8Slogwang /* Create credentials. */
442a9643ea8Slogwang p->p_ucred = crget();
443a9643ea8Slogwang p->p_ucred->cr_ngroups = 1; /* group 0 */
444a9643ea8Slogwang p->p_ucred->cr_uidinfo = uifind(0);
445a9643ea8Slogwang p->p_ucred->cr_ruidinfo = uifind(0);
446a9643ea8Slogwang p->p_ucred->cr_prison = &prison0;
447a9643ea8Slogwang
448a9643ea8Slogwang #ifdef AUDIT
449a9643ea8Slogwang audit_cred_kproc0(p->p_ucred);
450a9643ea8Slogwang #endif
451a9643ea8Slogwang #ifdef MAC
452a9643ea8Slogwang mac_cred_create_swapper(p->p_ucred);
453a9643ea8Slogwang #endif
454a9643ea8Slogwang
455a9643ea8Slogwang td->td_ucred = crhold(p->p_ucred);
456a9643ea8Slogwang #if 0
457a9643ea8Slogwang
458a9643ea8Slogwang /* Create sigacts. */
459a9643ea8Slogwang p->p_sigacts = sigacts_alloc();
460a9643ea8Slogwang
461a9643ea8Slogwang /* Initialize signal state for process 0. */
462a9643ea8Slogwang siginit(&proc0);
463a9643ea8Slogwang #endif
464a9643ea8Slogwang
465a9643ea8Slogwang /* Create the file descriptor table. */
466*22ce4affSfengbojiang p->p_fd = fdinit(NULL, false, NULL);
467a9643ea8Slogwang p->p_fdtol = NULL;
468a9643ea8Slogwang
469a9643ea8Slogwang
470a9643ea8Slogwang /* Create the limits structures. */
471a9643ea8Slogwang p->p_limit = lim_alloc();
472a9643ea8Slogwang for (i = 0; i < RLIM_NLIMITS; i++)
473a9643ea8Slogwang p->p_limit->pl_rlimit[i].rlim_cur =
474a9643ea8Slogwang p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
475a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur =
476a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
477a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
478a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
479a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_DATA].rlim_cur = dfldsiz;
480a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_DATA].rlim_max = maxdsiz;
481a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_cur = dflssiz;
482a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_max = maxssiz;
483a9643ea8Slogwang /* Cast to avoid overflow on i386/PAE. */
484*22ce4affSfengbojiang pageablemem = ptoa((vm_paddr_t)vm_free_count());
485a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_cur =
486a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = pageablemem;
487a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = pageablemem / 3;
488a9643ea8Slogwang p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = pageablemem;
489a9643ea8Slogwang p->p_cpulimit = RLIM_INFINITY;
490a9643ea8Slogwang
491a9643ea8Slogwang #if 0
492a9643ea8Slogwang p->p_stats = pstats_alloc();
493a9643ea8Slogwang
494a9643ea8Slogwang /* Allocate a prototype map so we have something to fork. */
495a9643ea8Slogwang pmap_pinit0(vmspace_pmap(&vmspace0));
496a9643ea8Slogwang p->p_vmspace = &vmspace0;
497a9643ea8Slogwang vmspace0.vm_refcnt = 1;
498a9643ea8Slogwang
499a9643ea8Slogwang /*
500a9643ea8Slogwang * proc0 is not expected to enter usermode, so there is no special
501a9643ea8Slogwang * handling for sv_minuser here, like is done for exec_new_vmspace().
502a9643ea8Slogwang */
503a9643ea8Slogwang vm_map_init(&vmspace0.vm_map, vmspace_pmap(&vmspace0),
504a9643ea8Slogwang p->p_sysent->sv_minuser, p->p_sysent->sv_maxuser);
505a9643ea8Slogwang #endif
506a9643ea8Slogwang
507a9643ea8Slogwang /*
508a9643ea8Slogwang * Call the init and ctor for the new thread and proc. We wait
509a9643ea8Slogwang * to do this until all other structures are fairly sane.
510a9643ea8Slogwang */
511a9643ea8Slogwang EVENTHANDLER_INVOKE(process_init, p);
512a9643ea8Slogwang EVENTHANDLER_INVOKE(thread_init, td);
513a9643ea8Slogwang EVENTHANDLER_INVOKE(process_ctor, p);
514a9643ea8Slogwang EVENTHANDLER_INVOKE(thread_ctor, td);
515a9643ea8Slogwang
516a9643ea8Slogwang #if 0
517a9643ea8Slogwang /*
518a9643ea8Slogwang * Charge root for one process.
519a9643ea8Slogwang */
520a9643ea8Slogwang (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
521a9643ea8Slogwang #endif
522a9643ea8Slogwang }
523a9643ea8Slogwang SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL);
524a9643ea8Slogwang
525a9643ea8Slogwang /* ARGSUSED*/
526a9643ea8Slogwang static void
proc0_post(void * dummy __unused)527a9643ea8Slogwang proc0_post(void *dummy __unused)
528a9643ea8Slogwang {
529*22ce4affSfengbojiang #if 0
530a9643ea8Slogwang struct timespec ts;
531a9643ea8Slogwang /*
532a9643ea8Slogwang * Give the ``random'' number generator a thump.
533a9643ea8Slogwang */
534a9643ea8Slogwang nanotime(&ts);
535a9643ea8Slogwang srandom(ts.tv_sec ^ ts.tv_nsec);
536*22ce4affSfengbojiang #endif
537a9643ea8Slogwang }
538a9643ea8Slogwang SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL);
539