xref: /xnu-11215/iokit/Kernel/IOStartIOKit.cpp (revision 14e3d835)
1 /*
2  * Copyright (c) 1998-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) 1998,1999 Apple Computer, Inc.  All rights reserved.
24  *
25  * HISTORY
26  *
27  */
28 
29 #include <libkern/c++/OSUnserialize.h>
30 #include <libkern/version.h>
31 #include <IOKit/IORegistryEntry.h>
32 #include <IOKit/IODeviceTreeSupport.h>
33 #include <IOKit/IOCatalogue.h>
34 #include <IOKit/IOUserClient.h>
35 #include <IOKit/IOMemoryDescriptor.h>
36 #include <IOKit/IOPlatformExpert.h>
37 #include <IOKit/IOLib.h>
38 #include <IOKit/IOKitKeys.h>
39 #include <IOKit/IOKitDebug.h>
40 
41 #include <IOKit/assert.h>
42 
43 #include "IOKitKernelInternal.h"
44 
45 extern "C" {
46 
47 extern void OSlibkernInit (void);
48 
49 #include <kern/clock.h>
50 
51 void IOKitResetTime( void )
52 {
53 	mach_timespec_t		t;
54 
55 	t.tv_sec = 30;
56 	t.tv_nsec = 0;
57 	IOService::waitForService(
58 		IOService::resourceMatching("IORTC"), &t );
59 #ifndef i386
60 	IOService::waitForService(
61 		IOService::resourceMatching("IONVRAM"), &t );
62 #endif
63 
64     clock_initialize_calendar();
65 }
66 
67 // From <osfmk/kern/debug.c>
68 extern int debug_mode;
69 
70 void StartIOKit( void * p1, void * p2, void * p3, void * p4 )
71 {
72     IOPlatformExpertDevice *	rootNub;
73     int				debugFlags;
74     IORegistryEntry *		root;
75     OSObject *			obj;
76     extern const char *         gIOKernelKmods;
77     OSString *                  errorString = NULL; // must release
78     OSDictionary *              fakeKmods;  // must release
79     OSCollectionIterator *      kmodIter;   // must release
80     OSString *                  kmodName;   // don't release
81 
82     if( PE_parse_boot_arg( "io", &debugFlags ))
83 	gIOKitDebug = debugFlags;
84 
85     // Check for the log synchronous bit set in io
86     if (gIOKitDebug & kIOLogSynchronous)
87         debug_mode = true;
88 
89     //
90     // Have to start IOKit environment before we attempt to start
91     // the C++ runtime environment.  At some stage we have to clean up
92     // the initialisation path so that OS C++ can initialise independantly
93     // of iokit basic service initialisation, or better we have IOLib stuff
94     // initialise as basic OS services.
95     //
96     IOLibInit();
97     OSlibkernInit();
98 
99    /*****
100     * Declare the fake kmod_info structs for built-in components
101     * that must be tracked as independent units for dependencies.
102     */
103     fakeKmods = OSDynamicCast(OSDictionary,
104         OSUnserialize(gIOKernelKmods, &errorString));
105 
106     if (!fakeKmods) {
107         if (errorString) {
108             panic("Kernel kmod list syntax error: %s\n",
109                     errorString->getCStringNoCopy());
110             errorString->release();
111         } else {
112             panic("Error loading kernel kmod list.\n");
113         }
114     }
115 
116     kmodIter = OSCollectionIterator::withCollection(fakeKmods);
117     if (!kmodIter) {
118         panic("Can't declare in-kernel kmods.\n");
119     }
120     while ((kmodName = OSDynamicCast(OSString, kmodIter->getNextObject()))) {
121 
122         OSString * kmodVersion = OSDynamicCast(OSString,
123             fakeKmods->getObject(kmodName));
124         if (!kmodVersion) {
125             panic("Can't declare in-kernel kmod; \"%s\" has "
126                 "an invalid version.\n",
127                 kmodName->getCStringNoCopy());
128         }
129 
130 	// empty version strings get replaced with current kernel version
131 	const char *vers = (strlen(kmodVersion->getCStringNoCopy())
132 				 ? kmodVersion->getCStringNoCopy()
133 				 : osrelease);
134 
135         if (KERN_SUCCESS != kmod_create_fake(kmodName->getCStringNoCopy(), vers)) {
136             panic("Failure declaring in-kernel kmod \"%s\".\n",
137                 kmodName->getCStringNoCopy());
138         }
139     }
140 
141     kmodIter->release();
142     fakeKmods->release();
143 
144 
145 
146     root = IORegistryEntry::initialize();
147     assert( root );
148     IOService::initialize();
149     IOCatalogue::initialize();
150     IOUserClient::initialize();
151     IOMemoryDescriptor::initialize();
152 
153     obj = OSString::withCString( version );
154     assert( obj );
155     if( obj ) {
156         root->setProperty( kIOKitBuildVersionKey, obj );
157 	obj->release();
158     }
159     obj = IOKitDiagnostics::diagnostics();
160     if( obj ) {
161         root->setProperty( kIOKitDiagnosticsKey, obj );
162 	obj->release();
163     }
164 
165     rootNub = new IOPlatformExpertDevice;
166 
167     if( rootNub && rootNub->initWithArgs( p1, p2, p3, p4)) {
168         rootNub->attach( 0 );
169 
170        /* Enter into the catalogue the drivers
171         * provided by BootX.
172         */
173         gIOCatalogue->recordStartupExtensions();
174 
175         rootNub->registerService();
176     }
177 }
178 
179 }; /* extern "C" */
180