2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
32 #include <IOKit/IODeviceTreeSupport.h>
33 #include <IOKit/IOService.h>
34 #include <libkern/c++/OSContainers.h>
35 #include <IOKit/IOCatalogue.h>
36 #include <libkern/c++/OSUnserialize.h>
38 #include <machine/machine_routines.h>
39 #include <mach/kmod.h>
40 #include <mach-o/mach_header.h>
41 #include <kern/host.h>
44 #include <IOKit/IOLib.h>
46 #include <IOKit/assert.h>
50 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
51 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
52 extern void OSRuntimeUnloadCPPForSegment(
53 struct segment_command
* segment
);
58 * At startup these function pointers are set to use the libsa in-kernel
59 * linker for recording and loading kmods. Once the root filesystem
60 * is available, the kmod_load_function pointer gets switched to point
61 * at the kmod_load_extension() function built into the kernel, and the
62 * others are set to zero. Those two functions must *always* be checked
63 * before being invoked.
66 kern_return_t (*kmod_load_function
)(char *extension_name
) =
68 bool (*record_startup_extensions_function
)(void) = 0;
69 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
70 void (*remove_startup_extension_function
)(const char * name
) = 0;
75 * A few parts of IOCatalogue require knowledge of
76 * whether the in-kernel linker is present. This
77 * variable is set by libsa's bootstrap code.
79 int kernelLinkerPresent
= 0;
82 #define super OSObject
83 #define kModuleKey "CFBundleIdentifier"
85 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
89 IOCatalogue
* gIOCatalogue
;
90 const OSSymbol
* gIOClassKey
;
91 const OSSymbol
* gIOProbeScoreKey
;
93 static void UniqueProperties( OSDictionary
* dict
)
97 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
99 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
101 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
102 classSymbol
->release();
105 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
107 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
109 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
110 classSymbol
->release();
114 void IOCatalogue::initialize( void )
117 OSString
* errorString
;
120 extern const char * gIOKernelConfigTables
;
122 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
123 if (!array
&& errorString
) {
124 IOLog("KernelConfigTables syntax error: %s\n",
125 errorString
->getCStringNoCopy());
126 errorString
->release();
129 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
130 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
131 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
);
133 gIOCatalogue
= new IOCatalogue
;
134 assert(gIOCatalogue
);
135 rc
= gIOCatalogue
->init(array
);
140 // Initialize the IOCatalog object.
141 bool IOCatalogue::init(OSArray
* initArray
)
143 IORegistryEntry
* entry
;
146 if ( !super::init() )
153 kernelTables
= OSCollectionIterator::withCollection( array
);
155 lock
= IOLockAlloc();
156 kld_lock
= IOLockAlloc();
158 kernelTables
->reset();
159 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
160 UniqueProperties(dict
);
161 if( 0 == dict
->getObject( gIOClassKey
))
162 IOLog("Missing or bad \"%s\" key\n",
163 gIOClassKey
->getCStringNoCopy());
167 AbsoluteTime deadline
;
168 clock_interval_to_deadline( 1000, kMillisecondScale
);
169 thread_call_func_delayed( ping
, this, deadline
);
172 entry
= IORegistryEntry::getRegistryRoot();
174 entry
->setProperty(kIOCatalogueKey
, this);
179 // Release all resources used by IOCatalogue and deallocate.
180 // This will probably never be called.
181 void IOCatalogue::free( void )
187 kernelTables
->release();
194 static int hackLimit
;
196 enum { kDriversPerIter
= 4 };
198 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
200 IOCatalogue
* self
= (IOCatalogue
*) arg
;
202 OSDictionary
* table
;
205 set
= OSOrderedSet::withCapacity( 1 );
207 IOTakeLock( &self
->lock
);
209 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
210 table
= (OSDictionary
*) self
->array
->getObject(
211 hackLimit
+ newLimit
);
213 set
->setLastObject( table
);
215 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
216 kprintf("enabling %s\n", sym
->getCStringNoCopy());
224 IOService::catalogNewDrivers( set
);
226 hackLimit
+= newLimit
;
229 IOUnlock( &self
->lock
);
231 if( kDriversPerIter
== newLimit
) {
232 AbsoluteTime deadline
;
233 clock_interval_to_deadline( 500, kMillisecondScale
);
234 thread_call_func_delayed( ping
, this, deadline
);
239 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
240 SInt32
* generationCount
)
242 OSDictionary
* nextTable
;
246 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
247 (void *)gIOProbeScoreKey
);
252 kernelTables
->reset();
257 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
259 if( hackIndex
++ > hackLimit
)
262 imports
= OSDynamicCast( OSString
,
263 nextTable
->getObject( gIOProviderClassKey
));
264 if( imports
&& service
->metaCast( imports
))
265 set
->setObject( nextTable
);
268 *generationCount
= getGenerationCount();
275 // Is personality already in the catalog?
276 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
277 SInt32
* generationCount
)
282 UniqueProperties(matching
);
284 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
285 (void *)gIOProbeScoreKey
);
288 kernelTables
->reset();
289 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
291 /* This comparison must be done with only the keys in the
292 * "matching" dict to enable general searches.
294 if ( dict
->isEqualTo(matching
, matching
) )
295 set
->setObject(dict
);
297 *generationCount
= getGenerationCount();
303 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
304 // XXX -- svail: This should be optimized.
305 // esb - There doesn't seem like any reason to do this - it causes problems
306 // esb - when there are more than one loadable driver matching on the same provider class
307 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
309 set
->setObject(dict
);
312 // Add driver config tables to catalog and start matching process.
313 bool IOCatalogue::addDrivers(OSArray
* drivers
,
314 bool doNubMatching
= true )
316 OSCollectionIterator
* iter
;
323 persons
= OSDynamicCast(OSArray
, drivers
);
327 iter
= OSCollectionIterator::withCollection( persons
);
331 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
332 (void *)gIOProbeScoreKey
);
339 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) ) {
342 UniqueProperties( dict
);
344 // Add driver personality to catalogue.
345 count
= array
->getCount();
347 OSDictionary
* driver
;
349 // Be sure not to double up on personalities.
350 driver
= (OSDictionary
*)array
->getObject(count
);
352 /* Unlike in other functions, this comparison must be exact!
353 * The catalogue must be able to contain personalities that
354 * are proper supersets of others.
355 * Do not compare just the properties present in one driver
356 * pesonality or the other.
358 if ( dict
->isEqualTo(driver
) ) {
359 array
->removeObject(count
);
364 ret
= array
->setObject( dict
);
368 AddNewImports( set
, dict
);
370 // Start device matching.
371 if ( doNubMatching
&& (set
->getCount() > 0) ) {
372 IOService::catalogNewDrivers( set
);
383 // Remove drivers from the catalog which match the
384 // properties in the matching dictionary.
385 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
386 bool doNubMatching
= true)
388 OSCollectionIterator
* tables
;
396 set
= OSOrderedSet::withCapacity(10,
398 (void *)gIOProbeScoreKey
);
402 arrayCopy
= OSArray::withCapacity(100);
408 tables
= OSCollectionIterator::withCollection(arrayCopy
);
409 arrayCopy
->release();
415 UniqueProperties( matching
);
418 kernelTables
->reset();
419 arrayCopy
->merge(array
);
420 array
->flushCollection();
422 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
424 /* This comparison must be done with only the keys in the
425 * "matching" dict to enable general searches.
427 if ( dict
->isEqualTo(matching
, matching
) ) {
428 AddNewImports( set
, dict
);
432 array
->setObject(dict
);
434 // Start device matching.
435 if ( doNubMatching
&& (set
->getCount() > 0) ) {
436 IOService::catalogNewDrivers(set
);
447 // Return the generation count.
448 SInt32
IOCatalogue::getGenerationCount( void ) const
450 return( generation
);
453 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
455 return isModuleLoaded(moduleName
->getCStringNoCopy());
458 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
460 kmod_info_t
* k_info
;
465 // Is the module already loaded?
466 k_info
= kmod_lookupbyname_locked((char *)moduleName
);
470 /* To make sure this operation completes even if a bad extension needs
471 * to be removed, take the kld lock for this whole block, spanning the
472 * kmod_load_function() and remove_startup_extension_function() calls.
474 IOLockLock(kld_lock
);
476 // If the module hasn't been loaded, then load it.
477 if (kmod_load_function
!= 0) {
479 ret
= kmod_load_function((char *)moduleName
);
481 if ( ret
!= kIOReturnSuccess
) {
482 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
484 /* If the extension couldn't be loaded this time,
485 * make it unavailable so that no more requests are
486 * made in vain. This also enables other matching
487 * extensions to have a chance.
489 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
490 (*remove_startup_extension_function
)(moduleName
);
492 IOLockUnlock(kld_lock
);
494 } else if (kernelLinkerPresent
) {
495 // If kern linker is here, the driver is actually loaded,
497 IOLockUnlock(kld_lock
);
500 // kern linker isn't here, a request has been queued
501 // but the module isn't necessarily loaded yet, so stall.
502 IOLockUnlock(kld_lock
);
506 IOLog("IOCatalogue: %s cannot be loaded "
507 "(kmod load function not set).\n",
511 IOLockUnlock(kld_lock
);
516 kfree(k_info
, sizeof(kmod_info_t
));
519 /* Lock wasn't taken if we get here. */
523 // Check to see if module has been loaded already.
524 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
526 OSString
* moduleName
= NULL
;
531 moduleName
= OSDynamicCast(OSString
, driver
->getObject(kModuleKey
));
533 return isModuleLoaded(moduleName
);
535 /* If a personality doesn't hold the "CFBundleIdentifier" key
536 * it is assumed to be an "in-kernel" driver.
541 // This function is called after a module has been loaded.
542 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
546 dict
= OSDictionary::withCapacity(2);
547 dict
->setObject(kModuleKey
, moduleName
);
552 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
556 name
= OSString::withCString(moduleName
);
557 moduleHasLoaded(name
);
561 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
563 kmod_info_t
* k_info
= 0;
567 ret
= kIOReturnBadArgument
;
569 name
= moduleName
->getCStringNoCopy();
570 k_info
= kmod_lookupbyname_locked((char *)name
);
571 if ( k_info
&& (k_info
->reference_count
< 1) ) {
573 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
575 kfree(k_info
, sizeof(kmod_info_t
));
579 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
584 kfree(k_info
, sizeof(kmod_info_t
));
590 static IOReturn
_terminateDrivers( OSArray
* array
, OSDictionary
* matching
)
592 OSCollectionIterator
* tables
;
600 return kIOReturnBadArgument
;
602 ret
= kIOReturnSuccess
;
604 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
605 kIORegistryIterateRecursively
);
607 return kIOReturnNoMemory
;
609 UniqueProperties( matching
);
611 // terminate instances.
614 while( (service
= (IOService
*)iter
->getNextObject()) ) {
615 dict
= service
->getPropertyTable();
619 /* Terminate only for personalities that match the matching dictionary.
620 * This comparison must be done with only the keys in the
621 * "matching" dict to enable general matching.
623 if ( !dict
->isEqualTo(matching
, matching
) )
626 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
627 ret
= kIOReturnUnsupported
;
631 } while( !service
&& !iter
->isValid());
634 // remove configs from catalog.
635 if ( ret
!= kIOReturnSuccess
)
638 arrayCopy
= OSArray::withCapacity(100);
640 return kIOReturnNoMemory
;
642 tables
= OSCollectionIterator::withCollection(arrayCopy
);
643 arrayCopy
->release();
645 return kIOReturnNoMemory
;
647 arrayCopy
->merge(array
);
648 array
->flushCollection();
650 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
652 /* Remove from the catalogue's array any personalities
653 * that match the matching dictionary.
654 * This comparison must be done with only the keys in the
655 * "matching" dict to enable general matching.
657 if ( dict
->isEqualTo(matching
, matching
) )
660 array
->setObject(dict
);
668 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
672 ret
= kIOReturnSuccess
;
674 ret
= _terminateDrivers(array
, matching
);
675 kernelTables
->reset();
681 IOReturn
IOCatalogue::terminateDriversForModule(
682 OSString
* moduleName
,
688 dict
= OSDictionary::withCapacity(1);
690 return kIOReturnNoMemory
;
692 dict
->setObject(kModuleKey
, moduleName
);
696 ret
= _terminateDrivers(array
, dict
);
697 kernelTables
->reset();
699 // Unload the module itself.
700 if ( unload
&& ret
== kIOReturnSuccess
) {
701 // Do kmod stop first.
702 ret
= unloadModule(moduleName
);
712 IOReturn
IOCatalogue::terminateDriversForModule(
713 const char * moduleName
,
719 name
= OSString::withCString(moduleName
);
721 return kIOReturnNoMemory
;
723 ret
= terminateDriversForModule(name
, unload
);
729 bool IOCatalogue::startMatching( OSDictionary
* matching
)
737 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
738 (void *)gIOProbeScoreKey
);
743 kernelTables
->reset();
745 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
747 /* This comparison must be done with only the keys in the
748 * "matching" dict to enable general matching.
750 if ( dict
->isEqualTo(matching
, matching
) )
751 AddNewImports(set
, dict
);
753 // Start device matching.
754 if ( set
->getCount() > 0 ) {
755 IOService::catalogNewDrivers(set
);
766 void IOCatalogue::reset(void)
769 OSDictionary
* entry
;
772 IOLog("Resetting IOCatalogue.\n");
775 tables
= OSArray::withArray(array
);
776 array
->flushCollection();
778 count
= tables
->getCount();
780 entry
= (OSDictionary
*)tables
->getObject(count
);
781 if ( entry
&& !entry
->getObject(kModuleKey
) ) {
782 array
->setObject(entry
);
786 kernelTables
->reset();
792 bool IOCatalogue::serialize(OSSerialize
* s
) const
800 ret
= array
->serialize(s
);
807 bool IOCatalogue::recordStartupExtensions(void) {
810 IOLockLock(kld_lock
);
811 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
812 result
= (*record_startup_extensions_function
)();
814 IOLog("Can't record startup extensions; "
815 "kernel linker is not present.\n");
818 IOLockUnlock(kld_lock
);
824 /*********************************************************************
825 *********************************************************************/
826 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
) {
829 IOLockLock(kld_lock
);
830 if (kernelLinkerPresent
&& add_from_mkext_function
) {
831 result
= (*add_from_mkext_function
)(mkext
);
833 IOLog("Can't add startup extensions from archive; "
834 "kernel linker is not present.\n");
837 IOLockUnlock(kld_lock
);
843 /*********************************************************************
844 * This function clears out all references to the in-kernel linker,
845 * frees the list of startup extensions in extensionDict, and
846 * deallocates the kernel's __KLD segment to reclaim that memory.
847 *********************************************************************/
848 kern_return_t
IOCatalogue::removeKernelLinker(void) {
849 kern_return_t result
= KERN_SUCCESS
;
850 extern struct mach_header _mh_execute_header
;
851 struct segment_command
* segment
;
852 char * dt_segment_name
;
853 void * segment_paddress
;
856 /* This must be the very first thing done by this function.
858 IOLockLock(kld_lock
);
861 /* If the kernel linker isn't here, that's automatically
864 if (!kernelLinkerPresent
) {
865 result
= KERN_SUCCESS
;
869 IOLog("Jettisoning kernel linker.\n");
871 kernelLinkerPresent
= 0;
873 /* Set the kmod_load_extension function as the means for loading
874 * a kernel extension.
876 kmod_load_function
= &kmod_load_extension
;
878 record_startup_extensions_function
= 0;
879 add_from_mkext_function
= 0;
880 remove_startup_extension_function
= 0;
883 /* Invoke destructors for the __KLD and __LINKEDIT segments.
884 * Do this for all segments before actually freeing their
885 * memory so that any cross-dependencies (not that there
886 * should be any) are handled.
888 segment
= getsegbynamefromheader(
889 &_mh_execute_header
, "__KLD");
891 IOLog("error removing kernel linker: can't find __KLD segment\n");
892 result
= KERN_FAILURE
;
895 OSRuntimeUnloadCPPForSegment(segment
);
897 segment
= getsegbynamefromheader(
898 &_mh_execute_header
, "__LINKEDIT");
900 IOLog("error removing kernel linker: can't find __LINKEDIT segment\n");
901 result
= KERN_FAILURE
;
904 OSRuntimeUnloadCPPForSegment(segment
);
907 /* Free the memory that was set up by bootx.
909 dt_segment_name
= "Kernel-__KLD";
910 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
911 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
915 dt_segment_name
= "Kernel-__LINKEDIT";
916 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
917 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
924 /* This must be the very last thing done before returning.
926 IOLockUnlock(kld_lock
);