|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
24: * The Regents of the University of California. All rights reserved.
25: * (c) UNIX System Laboratories, Inc.
26: * All or some portions of this file are derived from material licensed
27: * to the University of California by American Telephone and Telegraph
28: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
29: * the permission of UNIX System Laboratories, Inc.
30: *
31: * Redistribution and use in source and binary forms, with or without
32: * modification, are permitted provided that the following conditions
33: * are met:
34: * 1. Redistributions of source code must retain the above copyright
35: * notice, this list of conditions and the following disclaimer.
36: * 2. Redistributions in binary form must reproduce the above copyright
37: * notice, this list of conditions and the following disclaimer in the
38: * documentation and/or other materials provided with the distribution.
39: * 3. All advertising materials mentioning features or use of this software
40: * must display the following acknowledgement:
41: * This product includes software developed by the University of
42: * California, Berkeley and its contributors.
43: * 4. Neither the name of the University nor the names of its contributors
44: * may be used to endorse or promote products derived from this software
45: * without specific prior written permission.
46: *
47: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57: * SUCH DAMAGE.
58: *
59: * @(#)init_main.c 8.16 (Berkeley) 5/14/95
60: */
61:
62: /*
63: *
64: * Mach Operating System
65: * Copyright (c) 1987 Carnegie-Mellon University
66: * All rights reserved. The CMU software License Agreement specifies
67: * the terms and conditions for use and redistribution.
68: */
69: /*
70: * HISTORY
71: * 16-Apr-98 A. Ramesh at Apple
72: * Created for Apple Core from DR2 init_main.c.
73: */
74:
75: #include <quota.h>
76:
77: #include <sys/param.h>
78: #include <sys/filedesc.h>
79: #include <sys/kernel.h>
80: #include <sys/mount.h>
81: #include <sys/proc.h>
82: #include <sys/systm.h>
83: #include <sys/vnode.h>
84: #include <sys/conf.h>
85: #include <sys/buf.h>
86: #include <sys/clist.h>
87: #include <sys/user.h>
88: #include <ufs/ufs/quota.h>
89:
90: #include <sys/malloc.h>
91: #include <sys/dkstat.h>
92:
93: #include <machine/spl.h>
94: #include <kern/thread.h>
95: #include <kern/task.h>
96: #include <kern/ast.h>
97:
98: #include <mach/vm_param.h>
99:
100: #include <vm/vm_map.h>
101: #include <vm/vm_kern.h>
102:
103: #include <sys/ux_exception.h>
104:
105: #include <sys/reboot.h>
106: #include <mach/exception_types.h>
107: #include <dev/busvar.h>
108:
109: char copyright[] =
110: "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n";
111:
112: extern void ux_handler();
113:
114: /* Components of the first process -- never freed. */
115: struct proc proc0;
116: struct session session0;
117: struct pgrp pgrp0;
118: struct pcred cred0;
119: struct filedesc filedesc0;
120: struct plimit limit0;
121: struct pstats pstats0;
122: struct sigacts sigacts0;
123: struct proc *kernproc, *initproc;
124:
125:
126: long cp_time[CPUSTATES];
127: long dk_seek[DK_NDRIVE];
128: long dk_time[DK_NDRIVE];
129: long dk_wds[DK_NDRIVE];
130: long dk_wpms[DK_NDRIVE];
131: long dk_xfer[DK_NDRIVE];
132: long dk_bps[DK_NDRIVE];
133:
134: int dk_busy;
135: int dk_ndrive;
136:
137: long tk_cancc;
138: long tk_nin;
139: long tk_nout;
140: long tk_rawcc;
141:
142: /* Global variables to make pstat happy. We do swapping differently */
143: int nswdev, nswap;
144: int nswapmap;
145: void *swapmap;
146: struct swdevt swdevt[1];
147:
148: dev_t rootdev; /* device of the root */
149: dev_t dumpdev; /* device to take dumps on */
150: long dumplo; /* offset into dumpdev */
151: long hostid;
152: char hostname[MAXHOSTNAMELEN];
153: int hostnamelen;
154: char domainname[MAXDOMNAMELEN];
155: int domainnamelen;
156:
157: char rootdevice[16]; /* hfs device names have at least 9 chars */
158: struct timeval boottime; /* GRODY! This has to go... */
159: #if FIXME /* [ */
160: struct timeval time;
161: #endif /* FIXME ] */
162:
163: #ifdef KMEMSTATS
164: struct kmemstats kmemstats[M_LAST];
165: #endif
166:
167: int lbolt; /* awoken once a second */
168: struct vnode *rootvp;
169: int boothowto = RB_DEBUG;
170:
171: vm_map_t bsd_pageable_map;
172: vm_map_t mb_map;
173:
174: int cmask = CMASK;
175:
176: int parse_bsd_args(void);
177: extern int bsd_hardclockinit;
178:
179: /*
180: * Initialization code.
181: * Called from cold start routine as
182: * soon as a stack and segmentation
183: * have been established.
184: * Functions:
185: * clear and free user core
186: * turn on clock
187: * hand craft 0th process
188: * call all initialization routines
189: * fork - process 0 to schedule
190: * - process 1 execute bootstrap
191: * - process 2 to page out
192: */
193:
194: /*
195: * Sets the name for the given task.
196: */
197: void proc_name(s, p)
198: char *s;
199: struct proc *p;
200: {
201: int length = strlen(s);
202:
203: bcopy(s, p->p_comm,
204: length >= sizeof(p->p_comm) ? sizeof(p->p_comm) :
205: length + 1);
206: }
207:
208:
209: /* To allow these values to be patched, they're globals here */
210: #include <machine/vmparam.h>
211: struct rlimit vm_initial_limit_stack = { DFLSSIZ, MAXSSIZ };
212: struct rlimit vm_initial_limit_data = { DFLDSIZ, MAXDSIZ };
213: struct rlimit vm_initial_limit_core = { DFLCSIZ, MAXCSIZ };
214:
215: extern thread_t first_thread;
216:
217: #define SPL_DEBUG 0
218: #if SPL_DEBUG
219: #define dprintf(x) printf x
220: #else SPL_DEBUG
221: #define dprintf(x)
222: #endif /* SPL_DEBUG */
223:
224: void
225: bsd_init()
226: {
227: register struct proc *p;
228: extern struct ucred *rootcred;
229: register int i;
230: int s;
231: thread_t th;
232: extern void bsdinit_task();
233: extern void netisr_thread();
234: void lightning_bolt(void );
235: kern_return_t ret;
236: boolean_t funnel_state;
237: extern thread_t cloneproc();
238:
239: extern int (*mountroot) __P((void));
240:
241: funnel_state = thread_set_funneled(TRUE);
242:
243: printf(copyright);
244:
245: kmeminit();
246:
247: parse_bsd_args();
248:
249: bsd_bufferinit();
250:
251: /*
252: * Initialize process and pgrp structures.
253: */
254: procinit();
255:
256: kernproc = &proc0;
257:
258: p = kernproc;
259:
260: /* kernel_task->proc = kernproc; */
261: set_bsdtask_info(kernel_task,(void *)kernproc);
262: p->p_pid = 0;
263:
264: /* give kernproc a name */
265: proc_name("kernel_task", p);
266:
267: if (current_task() != kernel_task)
268: printf("We are in for problem, current task in not kernel task\n");
269:
270: /*
271: * Create process 0.
272: */
273: LIST_INSERT_HEAD(&allproc, p, p_list);
274: p->p_pgrp = &pgrp0;
275: LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
276: LIST_INIT(&pgrp0.pg_members);
277: LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
278:
279: pgrp0.pg_session = &session0;
280: session0.s_count = 1;
281: session0.s_leader = p;
282:
283: p->task = kernel_task;
284:
285: p->p_stat = SRUN;
286: p->p_flag = P_INMEM|P_SYSTEM;
287: p->p_nice = NZERO;
288: p->p_pptr = p;
289: simple_lock_init(&p->siglock);
290: p->sigwait = FALSE;
291: p->sigwait_thread = THREAD_NULL;
292: p->exit_thread = THREAD_NULL;
293:
294: /* Create credentials. */
295: lockinit(&cred0.pc_lock, PLOCK, "proc0 cred", 0, 0);
296: cred0.p_refcnt = 1;
297: p->p_cred = &cred0;
298: p->p_ucred = crget();
299: p->p_ucred->cr_ngroups = 1; /* group 0 */
300:
301: /* Create the file descriptor table. */
302: filedesc0.fd_refcnt = 1+1; /* +1 so shutdown will not _FREE_ZONE */
303: p->p_fd = &filedesc0;
304: filedesc0.fd_cmask = cmask;
305:
306: /* Create the limits structures. */
307: p->p_limit = &limit0;
308: for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
309: limit0.pl_rlimit[i].rlim_cur =
310: limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
311: limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
312: limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
313: limit0.pl_rlimit[RLIMIT_STACK] = vm_initial_limit_stack;
314: limit0.pl_rlimit[RLIMIT_DATA] = vm_initial_limit_data;
315: limit0.pl_rlimit[RLIMIT_CORE] = vm_initial_limit_core;
316: limit0.p_refcnt = 1;
317:
318: p->p_stats = &pstats0;
319: p->p_sigacts = &sigacts0;
320:
321: /*
322: * Charge root for one process.
323: */
324: (void)chgproccnt(0, 1);
325:
326:
327: /*
328: * Allocate a kernel submap for pageable memory
329: * for temporary copying (table(), execve()).
330: */
331: {
332: vm_offset_t min, max;
333:
334: ret = kmem_suballoc(kernel_map,
335: &min,
336: (vm_size_t)512*1024,
337: TRUE,
338: TRUE,
339: &bsd_pageable_map);
340: if (ret != KERN_SUCCESS)
341: panic("Failed to allocare bsd pageable map\n");
342: }
343:
344: /*
345: * Initialize the calendar by
346: * reading the BBC, if not already set.
347: */
348: IOKitResetTime();
349:
350: mapfs_init();
351:
352: /* Initialize the file systems. */
353: vfsinit();
354:
355: /* Initialize mbuf's. */
356: mbinit();
357:
358: /* Initialize syslog */
359: log_init();
360:
361: /* Initialize SysV shm */
362: shminit();
363:
364: /*
365: * Initialize protocols. Block reception of incoming packets
366: * until everything is ready.
367: */
368: s = splimp();
369: sysctl_register_fixed();
370: dlil_init();
371: socketinit();
372: domaininit();
373: splx(s);
374:
375: /*
376: * Create kernel idle cpu processes. This must be done
377: * before a context switch can occur (and hence I/O can
378: * happen in the binit() call).
379: */
380: p->p_fd->fd_cdir = NULL;
381: p->p_fd->fd_rdir = NULL;
382:
383:
384: #ifdef GPROF
385: /* Initialize kernel profiling. */
386: kmstartup();
387: #endif
388:
389: /* kick off timeout driven events by calling first time */
390: lightning_bolt();
391:
392: /*
393: * Start up netisr thread now in case we are doing an nfs_mountroot.
394: */
395: (void) kernel_thread(kernel_task, netisr_thread);
396:
397: bsd_autoconf();
398:
399: /*
400: * We attach the loopback interface *way* down here to ensure
401: * it happens after autoconf(), otherwise it becomes the
402: * "primary" interface.
403: */
404: #include <loop.h>
405: #if NLOOP > 0
406: loopattach(); /* XXX */
407: #endif
408:
409:
410: /* Mount the root file system. */
411: while( TRUE) {
412: int err;
413:
414: setconf();
415: /* read the time after clock_initialize_calendar()
416: * and before nfs mount */
417: microtime(&time);
418:
419: if (0 == (err = vfs_mountroot()))
420: break;
421: printf("cannot mount root, errno = %d\n", err);
422: boothowto |= RB_ASKNAME;
423: }
424:
425: mountlist.cqh_first->mnt_flag |= MNT_ROOTFS;
426:
427: /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
428: if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
429: panic("cannot find root vnode");
430: filedesc0.fd_cdir = rootvnode;
431: VREF(rootvnode);
432: VOP_UNLOCK(rootvnode, 0, p);
433:
434:
435: /*
436: * Now can look at time, having had a chance to verify the time
437: * from the file system. Reset p->p_rtime as it may have been
438: * munched in mi_switch() after the time got set.
439: */
440: p->p_stats->p_start = boottime = time;
441: p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
442:
443: #ifdef DEVFS
444: {
445: extern void devfs_kernel_mount(char * str);
446:
447: devfs_kernel_mount("/dev");
448: }
449: #endif DEVFS
450:
451: /* Initialize signal state for process 0. */
452: siginit(p);
453:
454: vnode_pager_bootstrap();
455: /* printf("vnode pager initialized\n"); */
456:
457: /* printf("Launching user process\n"); */
458:
459: bsd_utaskbootstrap();
460:
461: (void) thread_set_funneled(funnel_state);
462: }
463:
464: void
465: bsdinit_task()
466: {
467: struct proc *p = current_proc();
468: struct uthread *ut;
469: kern_return_t kr;
470: thread_act_t th_act;
471: boolean_t funnel_state;
472:
473: funnel_state = thread_set_funneled(TRUE);
474:
475: #if FIXME /* [ */
476:
477: ipc_port_t master_bootstrap_port;
478: task_t bootstrap_task;
479: thread_act_t bootstrap_thr_act;
480: ipc_port_t root_device_port;
481:
482: master_bootstrap_port = ipc_port_alloc_kernel();
483: if (master_bootstrap_port == IP_NULL)
484: panic("can't allocate master bootstrap port");
485: task_set_special_port(bootstrap_task,
486: TASK_BOOTSTRAP_PORT,
487: ipc_port_make_send(master_bootstrap_port));
488: printf("setting bootstrap port \n");
489: printf("Setting exception port for the init task\n");
490: (void) task_set_exception_ports(get_threadtask(th),
491: EXC_MASK_ALL &
492: ~(EXC_MASK_SYSCALL |
493: EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT),
494: ux_exception_port,
495: EXCEPTION_DEFAULT, 0);
496:
497: #endif /* FIXME ] */
498: proc_name("init", p);
499:
500: ux_handler_init();
501: /* port_reference(ux_exception_port);*/
502:
503: th_act = current_act();
504: (void) task_set_exception_ports(get_threadtask(th_act),
505: EXC_MASK_ALL &
506: ~(EXC_MASK_SYSCALL |
507: EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT),
508: ux_exception_port,
509: EXCEPTION_DEFAULT, 0);
510:
511:
512:
513:
514: ut = (uthread_t)get_bsdthread_info(th_act);
515: ut->uu_ar0 = (void *)get_user_regs(th_act);
516:
517: bsd_hardclockinit = 1; /* Start bsd hardclock */
518: load_init_program(p);
519:
520: (void) thread_set_funneled(funnel_state);
521:
522: }
523:
524: void
525: lightning_bolt()
526: {
527: thread_wakeup(&lbolt);
528: timeout(lightning_bolt,0,hz);
529: }
530:
531: bsd_autoconf(){
532: extern kern_return_t IOKitBSDInit( void );
533:
534: kminit();
535:
536: /*
537: * Early startup for bsd pseudodevices.
538: */
539: {
540: struct pseudo_init *pi;
541:
542: for (pi = pseudo_inits; pi->ps_func; pi++)
543: (*pi->ps_func) (pi->ps_count);
544: }
545:
546: return( IOKitBSDInit());
547: }
548:
549:
550: #include <sys/disklabel.h> // for MAXPARTITIONS
551:
552: setconf()
553: {
554: extern kern_return_t IOFindBSDRoot( char * rootName,
555: dev_t * root, u_int32_t * flags );
556:
557: extern int (*mountroot) __P((void));
558: extern int nfs_mountroot(); /* nfs_vfsops.c */
559:
560: u_int32_t flags;
561: kern_return_t err;
562:
563: err = IOFindBSDRoot( rootdevice, &rootdev, &flags );
564: if( err) {
565: printf("setconf: IOFindBSDRoot returned an error (%d); setting rootdevice to 'sd0a'.\n", err); /* XXX DEBUG TEMP */
566: rootdev = makedev( 6, 0 );
567: strcpy( rootdevice, "sd0a" );
568: flags = 0;
569: }
570:
571: /* if network device then force nfs root */
572: if( flags & 1 ) {
573: printf("mounting nfs root\n");
574: mountroot = nfs_mountroot;
575: } else {
576: /* otherwise have vfs determine root filesystem */
577: printf("probing for root file system\n");
578: mountroot = NULL;
579: }
580:
581: }
582:
583: bsd_utaskbootstrap()
584: {
585: thread_act_t th_act;
586:
587: th_act = cloneproc(kernproc);
588: initproc = pfind(1);
589: thread_hold(th_act);
590: (void) thread_stop_wait(getshuttle_thread(th_act));
591: thread_ast_set(th_act,AST_BSD_INIT);
592: thread_release(th_act);
593: thread_unstop(getshuttle_thread(th_act));
594: (void) thread_resume(th_act);
595: }
596:
597: parse_bsd_args()
598: {
599: extern char init_args[];
600: char namep[16];
601: extern int boothowto;
602: extern int srv;
603: extern int ncl;
604: extern int bufpages;
605: extern int nbuf;
606:
607: int len;
608:
609: if (PE_parse_boot_arg("-s", namep)) {
610: boothowto |= RB_SINGLE;
611: len = strlen(init_args);
612: if(len != 0)
613: strcat(init_args," -s");
614: else
615: strcat(init_args,"-s");
616: }
617: if (PE_parse_boot_arg("-b", namep)) {
618: boothowto |= RB_NOBOOTRC;
619: len = strlen(init_args);
620: if(len != 0)
621: strcat(init_args," -b");
622: else
623: strcat(init_args,"-b");
624: }
625:
626: if (PE_parse_boot_arg("-F", namep)) {
627: len = strlen(init_args);
628: if(len != 0)
629: strcat(init_args," -F");
630: else
631: strcat(init_args,"-F");
632: }
633:
634: if (PE_parse_boot_arg("-v", namep)) {
635: len = strlen(init_args);
636: if(len != 0)
637: strcat(init_args," -v");
638: else
639: strcat(init_args,"-v");
640: }
641:
642: PE_parse_boot_arg("srv", &srv);
643: PE_parse_boot_arg("ncl", &ncl);
644: PE_parse_boot_arg("nbuf", &nbuf);
645: PE_parse_boot_arg("bufpages", &bufpages);
646:
647: return 0;
648: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.