2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
29 #include <IOKit/IODeviceTreeSupport.h>
30 #include <IOKit/IOService.h>
31 #include <libkern/c++/OSContainers.h>
32 #include <IOKit/IOCatalogue.h>
33 #include <libkern/c++/OSUnserialize.h>
35 #include <machine/machine_routines.h>
36 #include <mach/kmod.h>
37 #include <mach-o/mach_header.h>
40 #include <IOKit/IOLib.h>
42 #include <IOKit/assert.h>
46 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
47 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
48 extern void OSRuntimeUnloadCPPForSegment(
49 struct segment_command
* segment
);
54 * At startup these function pointers are set to use the libsa in-kernel
55 * linker for recording and loading kmods. Once the root filesystem
56 * is available, the kmod_load_function pointer gets switched to point
57 * at the kmod_load_extension() function built into the kernel, and the
58 * others are set to zero. Those two functions must *always* be checked
59 * before being invoked.
62 kern_return_t (*kmod_load_function
)(char *extension_name
) =
64 bool (*record_startup_extensions_function
)(void) = 0;
65 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
66 void (*remove_startup_extension_function
)(const char * name
) = 0;
71 * A few parts of IOCatalogue require knowledge of
72 * whether the in-kernel linker is present. This
73 * variable is set by libsa's bootstrap code.
75 int kernelLinkerPresent
= 0;
78 #define super OSObject
79 #define kModuleKey "CFBundleIdentifier"
81 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
85 IOCatalogue
* gIOCatalogue
;
86 const OSSymbol
* gIOClassKey
;
87 const OSSymbol
* gIOProbeScoreKey
;
89 static void UniqueProperties( OSDictionary
* dict
)
93 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
95 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
97 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
98 classSymbol
->release();
101 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
103 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
105 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
106 classSymbol
->release();
110 void IOCatalogue::initialize( void )
113 OSString
* errorString
;
116 extern const char * gIOKernelConfigTables
;
118 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
119 if (!array
&& errorString
) {
120 IOLog("KernelConfigTables syntax error: %s\n",
121 errorString
->getCStringNoCopy());
122 errorString
->release();
125 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
126 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
127 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
);
129 gIOCatalogue
= new IOCatalogue
;
130 assert(gIOCatalogue
);
131 rc
= gIOCatalogue
->init(array
);
136 // Initialize the IOCatalog object.
137 bool IOCatalogue::init(OSArray
* initArray
)
139 IORegistryEntry
* entry
;
142 if ( !super::init() )
149 kernelTables
= OSCollectionIterator::withCollection( array
);
151 lock
= IOLockAlloc();
152 kld_lock
= IOLockAlloc();
154 kernelTables
->reset();
155 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
156 UniqueProperties(dict
);
157 if( 0 == dict
->getObject( gIOClassKey
))
158 IOLog("Missing or bad \"%s\" key\n",
159 gIOClassKey
->getCStringNoCopy());
163 AbsoluteTime deadline
;
164 clock_interval_to_deadline( 1000, kMillisecondScale
);
165 thread_call_func_delayed( ping
, this, deadline
);
168 entry
= IORegistryEntry::getRegistryRoot();
170 entry
->setProperty(kIOCatalogueKey
, this);
175 // Release all resources used by IOCatalogue and deallocate.
176 // This will probably never be called.
177 void IOCatalogue::free( void )
183 kernelTables
->release();
190 static int hackLimit
;
192 enum { kDriversPerIter
= 4 };
194 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
196 IOCatalogue
* self
= (IOCatalogue
*) arg
;
198 OSDictionary
* table
;
201 set
= OSOrderedSet::withCapacity( 1 );
203 IOTakeLock( &self
->lock
);
205 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
206 table
= (OSDictionary
*) self
->array
->getObject(
207 hackLimit
+ newLimit
);
209 set
->setLastObject( table
);
211 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
212 kprintf("enabling %s\n", sym
->getCStringNoCopy());
220 IOService::catalogNewDrivers( set
);
222 hackLimit
+= newLimit
;
225 IOUnlock( &self
->lock
);
227 if( kDriversPerIter
== newLimit
) {
228 AbsoluteTime deadline
;
229 clock_interval_to_deadline( 500, kMillisecondScale
);
230 thread_call_func_delayed( ping
, this, deadline
);
235 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
236 SInt32
* generationCount
)
238 OSDictionary
* nextTable
;
242 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
243 (void *)gIOProbeScoreKey
);
248 kernelTables
->reset();
253 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
255 if( hackIndex
++ > hackLimit
)
258 imports
= OSDynamicCast( OSString
,
259 nextTable
->getObject( gIOProviderClassKey
));
260 if( imports
&& service
->metaCast( imports
))
261 set
->setObject( nextTable
);
264 *generationCount
= getGenerationCount();
271 // Is personality already in the catalog?
272 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
273 SInt32
* generationCount
)
278 UniqueProperties(matching
);
280 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
281 (void *)gIOProbeScoreKey
);
284 kernelTables
->reset();
285 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
286 if ( dict
->isEqualTo(matching
, matching
) )
287 set
->setObject(dict
);
289 *generationCount
= getGenerationCount();
295 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
296 // XXX -- svail: This should be optimized.
297 // esb - There doesn't seem like any reason to do this - it causes problems
298 // esb - when there are more than one loadable driver matching on the same provider class
299 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
301 set
->setObject(dict
);
304 // Add driver config tables to catalog and start matching process.
305 bool IOCatalogue::addDrivers(OSArray
* drivers
,
306 bool doNubMatching
= true )
308 OSCollectionIterator
* iter
;
315 persons
= OSDynamicCast(OSArray
, drivers
);
319 iter
= OSCollectionIterator::withCollection( persons
);
323 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
324 (void *)gIOProbeScoreKey
);
331 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) ) {
334 UniqueProperties( dict
);
336 // Add driver personality to catalogue.
337 count
= array
->getCount();
339 OSDictionary
* driver
;
341 // Be sure not to double up on personalities.
342 driver
= (OSDictionary
*)array
->getObject(count
);
343 if ( dict
->isEqualTo(driver
, driver
) ) {
344 array
->removeObject(count
);
349 ret
= array
->setObject( dict
);
353 AddNewImports( set
, dict
);
355 // Start device matching.
356 if ( doNubMatching
&& (set
->getCount() > 0) ) {
357 IOService::catalogNewDrivers( set
);
368 // Remove drivers from the catalog which match the
369 // properties in the matching dictionary.
370 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
371 bool doNubMatching
= true)
373 OSCollectionIterator
* tables
;
381 set
= OSOrderedSet::withCapacity(10,
383 (void *)gIOProbeScoreKey
);
387 arrayCopy
= OSArray::withCapacity(100);
393 tables
= OSCollectionIterator::withCollection(arrayCopy
);
394 arrayCopy
->release();
400 UniqueProperties( matching
);
403 kernelTables
->reset();
404 arrayCopy
->merge(array
);
405 array
->flushCollection();
407 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
408 if ( dict
->isEqualTo(matching
, matching
) ) {
409 AddNewImports( set
, dict
);
413 array
->setObject(dict
);
415 // Start device matching.
416 if ( doNubMatching
&& (set
->getCount() > 0) ) {
417 IOService::catalogNewDrivers(set
);
428 // Return the generation count.
429 SInt32
IOCatalogue::getGenerationCount( void ) const
431 return( generation
);
434 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
436 return isModuleLoaded(moduleName
->getCStringNoCopy());
439 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
441 kmod_info_t
* k_info
;
446 // Is the module already loaded?
447 k_info
= kmod_lookupbyname((char *)moduleName
);
451 /* To make sure this operation completes even if a bad extension needs
452 * to be removed, take the kld lock for this whole block, spanning the
453 * kmod_load_function() and remove_startup_extension_function() calls.
455 IOLockLock(kld_lock
);
457 // If the module hasn't been loaded, then load it.
458 if (kmod_load_function
!= 0) {
460 ret
= kmod_load_function((char *)moduleName
);
462 if ( ret
!= kIOReturnSuccess
) {
463 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
465 /* If the extension couldn't be loaded this time,
466 * make it unavailable so that no more requests are
467 * made in vain. This also enables other matching
468 * extensions to have a chance.
470 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
471 (*remove_startup_extension_function
)(moduleName
);
473 IOLockUnlock(kld_lock
);
475 } else if (kernelLinkerPresent
) {
476 // If kern linker is here, the driver is actually loaded,
478 IOLockUnlock(kld_lock
);
481 // kern linker isn't here, a request has been queued
482 // but the module isn't necessarily loaded yet, so stall.
483 IOLockUnlock(kld_lock
);
487 IOLog("IOCatalogue: %s cannot be loaded "
488 "(kmod load function not set).\n",
492 IOLockUnlock(kld_lock
);
496 /* Lock wasn't taken if we get here. */
500 // Check to see if module has been loaded already.
501 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
503 OSString
* moduleName
= NULL
;
508 moduleName
= OSDynamicCast(OSString
, driver
->getObject(kModuleKey
));
510 return isModuleLoaded(moduleName
);
512 /* If a personality doesn't hold the "CFBundleIdentifier" key
513 * it is assumed to be an "in-kernel" driver.
518 // This function is called after a module has been loaded.
519 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
523 dict
= OSDictionary::withCapacity(2);
524 dict
->setObject(kModuleKey
, moduleName
);
529 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
533 name
= OSString::withCString(moduleName
);
534 moduleHasLoaded(name
);
538 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
540 kmod_info_t
* k_info
;
544 ret
= kIOReturnBadArgument
;
546 name
= moduleName
->getCStringNoCopy();
547 k_info
= kmod_lookupbyname((char *)name
);
548 if ( k_info
&& (k_info
->reference_count
< 1) ) {
550 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) )
553 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
560 static IOReturn
_terminateDrivers( OSArray
* array
, OSDictionary
* matching
)
562 OSCollectionIterator
* tables
;
563 OSCollectionIterator
* props
;
571 return kIOReturnBadArgument
;
573 ret
= kIOReturnSuccess
;
575 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
576 kIORegistryIterateRecursively
);
578 return kIOReturnNoMemory
;
580 UniqueProperties( matching
);
582 props
= OSCollectionIterator::withCollection(matching
);
585 return kIOReturnNoMemory
;
588 // terminate instances.
591 while( (service
= (IOService
*)iter
->getNextObject()) ) {
592 dict
= service
->getPropertyTable();
596 if ( !dict
->isEqualTo(matching
, matching
) )
599 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
600 ret
= kIOReturnUnsupported
;
604 } while( !service
&& !iter
->isValid());
607 // remove configs from catalog.
608 if ( ret
!= kIOReturnSuccess
)
611 arrayCopy
= OSArray::withCapacity(100);
613 return kIOReturnNoMemory
;
615 tables
= OSCollectionIterator::withCollection(arrayCopy
);
616 arrayCopy
->release();
618 return kIOReturnNoMemory
;
620 arrayCopy
->merge(array
);
621 array
->flushCollection();
623 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
624 if ( dict
->isEqualTo(matching
, matching
) )
627 array
->setObject(dict
);
635 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
639 ret
= kIOReturnSuccess
;
641 ret
= _terminateDrivers(array
, matching
);
642 kernelTables
->reset();
648 IOReturn
IOCatalogue::terminateDriversForModule(
649 OSString
* moduleName
,
655 dict
= OSDictionary::withCapacity(1);
657 return kIOReturnNoMemory
;
659 dict
->setObject(kModuleKey
, moduleName
);
663 ret
= _terminateDrivers(array
, dict
);
664 kernelTables
->reset();
666 // Unload the module itself.
667 if ( unload
&& ret
== kIOReturnSuccess
) {
668 // Do kmod stop first.
669 ret
= unloadModule(moduleName
);
679 IOReturn
IOCatalogue::terminateDriversForModule(
680 const char * moduleName
,
686 name
= OSString::withCString(moduleName
);
688 return kIOReturnNoMemory
;
690 ret
= terminateDriversForModule(name
, unload
);
696 bool IOCatalogue::startMatching( OSDictionary
* matching
)
704 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
705 (void *)gIOProbeScoreKey
);
710 kernelTables
->reset();
712 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
713 if ( dict
->isEqualTo(matching
, matching
) )
714 AddNewImports(set
, dict
);
716 // Start device matching.
717 if ( set
->getCount() > 0 ) {
718 IOService::catalogNewDrivers(set
);
729 void IOCatalogue::reset(void)
732 OSDictionary
* entry
;
735 IOLog("Resetting IOCatalogue.\n");
738 tables
= OSArray::withArray(array
);
739 array
->flushCollection();
741 count
= tables
->getCount();
743 entry
= (OSDictionary
*)tables
->getObject(count
);
744 if ( entry
&& !entry
->getObject(kModuleKey
) ) {
745 array
->setObject(entry
);
749 kernelTables
->reset();
755 bool IOCatalogue::serialize(OSSerialize
* s
) const
763 ret
= array
->serialize(s
);
770 bool IOCatalogue::recordStartupExtensions(void) {
773 IOLockLock(kld_lock
);
774 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
775 result
= (*record_startup_extensions_function
)();
777 IOLog("Can't record startup extensions; "
778 "kernel linker is not present.\n");
781 IOLockUnlock(kld_lock
);
787 /*********************************************************************
788 *********************************************************************/
789 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
) {
792 IOLockLock(kld_lock
);
793 if (kernelLinkerPresent
&& add_from_mkext_function
) {
794 result
= (*add_from_mkext_function
)(mkext
);
796 IOLog("Can't add startup extensions from archive; "
797 "kernel linker is not present.\n");
800 IOLockUnlock(kld_lock
);
806 /*********************************************************************
807 * This function clears out all references to the in-kernel linker,
808 * frees the list of startup extensions in extensionDict, and
809 * deallocates the kernel's __KLD segment to reclaim that memory.
810 *********************************************************************/
811 kern_return_t
IOCatalogue::removeKernelLinker(void) {
812 kern_return_t result
= KERN_SUCCESS
;
813 extern struct mach_header _mh_execute_header
;
814 struct segment_command
* segment
;
815 char * dt_segment_name
;
816 void * segment_paddress
;
819 /* This must be the very first thing done by this function.
821 IOLockLock(kld_lock
);
824 /* If the kernel linker isn't here, that's automatically
827 if (!kernelLinkerPresent
) {
828 result
= KERN_SUCCESS
;
832 IOLog("Jettisoning kernel linker.\n");
834 kernelLinkerPresent
= 0;
836 /* Set the kmod_load_extension function as the means for loading
837 * a kernel extension.
839 kmod_load_function
= &kmod_load_extension
;
841 record_startup_extensions_function
= 0;
842 add_from_mkext_function
= 0;
843 remove_startup_extension_function
= 0;
846 /* Invoke destructors for the __KLD and __LINKEDIT segments.
847 * Do this for all segments before actually freeing their
848 * memory so that any cross-dependencies (not that there
849 * should be any) are handled.
851 segment
= getsegbynamefromheader(
852 &_mh_execute_header
, "__KLD");
854 result
= KERN_FAILURE
;
857 OSRuntimeUnloadCPPForSegment(segment
);
859 segment
= getsegbynamefromheader(
860 &_mh_execute_header
, "__LINKEDIT");
862 result
= KERN_FAILURE
;
865 OSRuntimeUnloadCPPForSegment(segment
);
868 /* Free the memory that was set up by bootx.
870 dt_segment_name
= "Kernel-__KLD";
871 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
872 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
876 dt_segment_name
= "Kernel-__LINKEDIT";
877 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
878 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
885 /* This must be the very last thing done before returning.
887 IOLockUnlock(kld_lock
);