xref: /xnu-11215/iokit/Kernel/IOStartIOKit.cpp (revision 368ad365)
1 /*
2  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_LICENSE_HEADER_START@
5  *
6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
7  *
8  * This file contains Original Code and/or Modifications of Original Code
9  * as defined in and that are subject to the Apple Public Source License
10  * Version 2.0 (the 'License'). You may not use this file except in
11  * compliance with the License. Please obtain a copy of the License at
12  * http://www.opensource.apple.com/apsl/ and read it before using this
13  * file.
14  *
15  * The Original Code and all software distributed under the License are
16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20  * Please see the License for the specific language governing rights and
21  * limitations under the License.
22  *
23  * @APPLE_LICENSE_HEADER_END@
24  */
25 /*
26  * Copyright (c) 1998,1999 Apple Computer, Inc.  All rights reserved.
27  *
28  * HISTORY
29  *
30  */
31 
32 #include <libkern/c++/OSUnserialize.h>
33 #include <IOKit/IORegistryEntry.h>
34 #include <IOKit/IODeviceTreeSupport.h>
35 #include <IOKit/IOCatalogue.h>
36 #include <IOKit/IOUserClient.h>
37 #include <IOKit/IOMemoryDescriptor.h>
38 #include <IOKit/IOPlatformExpert.h>
39 #include <IOKit/IOLib.h>
40 #include <IOKit/IOKitKeys.h>
41 #include <IOKit/IOKitDebug.h>
42 
43 #include <IOKit/assert.h>
44 
45 extern "C" {
46 
47 extern void OSlibkernInit (void);
48 extern void IOLibInit(void);
49 
50 #include <kern/clock.h>
51 
52 void IOKitResetTime( void )
53 {
54 	mach_timespec_t		t;
55 
56 	t.tv_sec = 30;
57 	t.tv_nsec = 0;
58 	IOService::waitForService(
59 		IOService::resourceMatching("IORTC"), &t );
60 #ifndef i386
61 	IOService::waitForService(
62 		IOService::resourceMatching("IONVRAM"), &t );
63 #endif
64 
65     clock_initialize_calendar();
66 }
67 
68 // From <osfmk/kern/debug.c>
69 extern int debug_mode;
70 
71 void StartIOKit( void * p1, void * p2, void * p3, void * p4 )
72 {
73     IOPlatformExpertDevice *	rootNub;
74     int				debugFlags;
75     IORegistryEntry *		root;
76     OSObject *			obj;
77     extern const char *         gIOKernelKmods;
78     OSString *                  errorString = NULL; // must release
79     OSDictionary *              fakeKmods;  // must release
80     OSCollectionIterator *      kmodIter;   // must release
81     OSString *                  kmodName;   // don't release
82 
83     IOLog( iokit_version );
84 
85     if( PE_parse_boot_arg( "io", &debugFlags ))
86 	gIOKitDebug = debugFlags;
87 
88     // Check for the log synchronous bit set in io
89     if (gIOKitDebug & kIOLogSynchronous)
90         debug_mode = true;
91 
92     //
93     // Have to start IOKit environment before we attempt to start
94     // the C++ runtime environment.  At some stage we have to clean up
95     // the initialisation path so that OS C++ can initialise independantly
96     // of iokit basic service initialisation, or better we have IOLib stuff
97     // initialise as basic OS services.
98     //
99     IOLibInit();
100     OSlibkernInit();
101 
102    /*****
103     * Declare the fake kmod_info structs for built-in components
104     * that must be tracked as independent units for dependencies.
105     */
106     fakeKmods = OSDynamicCast(OSDictionary,
107         OSUnserialize(gIOKernelKmods, &errorString));
108 
109     if (!fakeKmods) {
110         if (errorString) {
111             panic("Kernel kmod list syntax error: %s\n",
112                     errorString->getCStringNoCopy());
113             errorString->release();
114         } else {
115             panic("Error loading kernel kmod list.\n");
116         }
117     }
118 
119     kmodIter = OSCollectionIterator::withCollection(fakeKmods);
120     if (!kmodIter) {
121         panic("Can't declare in-kernel kmods.\n");
122     }
123     while ((kmodName = OSDynamicCast(OSString, kmodIter->getNextObject()))) {
124 
125         OSString * kmodVersion = OSDynamicCast(OSString,
126             fakeKmods->getObject(kmodName));
127         if (!kmodVersion) {
128             panic("Can't declare in-kernel kmod; \"%s\" has "
129                 "an invalid version.\n",
130                 kmodName->getCStringNoCopy());
131         }
132         if (KERN_SUCCESS != kmod_create_fake(kmodName->getCStringNoCopy(),
133                 kmodVersion->getCStringNoCopy())) {
134             panic("Failure declaring in-kernel kmod \"%s\".\n",
135                 kmodName->getCStringNoCopy());
136         }
137     }
138 
139     kmodIter->release();
140     fakeKmods->release();
141 
142 
143 
144     root = IORegistryEntry::initialize();
145     assert( root );
146     IOService::initialize();
147     IOCatalogue::initialize();
148     IOUserClient::initialize();
149     IOMemoryDescriptor::initialize();
150 
151     obj = OSString::withCString( iokit_version );
152     assert( obj );
153     if( obj ) {
154         root->setProperty( kIOKitBuildVersionKey, obj );
155 	obj->release();
156     }
157     obj = IOKitDiagnostics::diagnostics();
158     if( obj ) {
159         root->setProperty( kIOKitDiagnosticsKey, obj );
160 	obj->release();
161     }
162 
163     rootNub = new IOPlatformExpertDevice;
164 
165     if( rootNub && rootNub->initWithArgs( p1, p2, p3, p4)) {
166         rootNub->attach( 0 );
167 
168        /* Enter into the catalogue the drivers
169         * provided by BootX.
170         */
171         gIOCatalogue->recordStartupExtensions();
172 
173         rootNub->registerService();
174     }
175 }
176 
177 }; /* extern "C" */
178