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>
38 #include <kern/host.h>
41 #include <IOKit/IOLib.h>
43 #include <IOKit/assert.h>
47 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
48 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
49 extern void OSRuntimeUnloadCPPForSegment(
50 struct segment_command
* segment
);
55 * At startup these function pointers are set to use the libsa in-kernel
56 * linker for recording and loading kmods. Once the root filesystem
57 * is available, the kmod_load_function pointer gets switched to point
58 * at the kmod_load_extension() function built into the kernel, and the
59 * others are set to zero. Those two functions must *always* be checked
60 * before being invoked.
63 kern_return_t (*kmod_load_function
)(char *extension_name
) =
65 bool (*record_startup_extensions_function
)(void) = 0;
66 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
67 void (*remove_startup_extension_function
)(const char * name
) = 0;
72 * A few parts of IOCatalogue require knowledge of
73 * whether the in-kernel linker is present. This
74 * variable is set by libsa's bootstrap code.
76 int kernelLinkerPresent
= 0;
79 #define super OSObject
80 #define kModuleKey "CFBundleIdentifier"
82 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
86 IOCatalogue
* gIOCatalogue
;
87 const OSSymbol
* gIOClassKey
;
88 const OSSymbol
* gIOProbeScoreKey
;
90 static void UniqueProperties( OSDictionary
* dict
)
94 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
96 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
98 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
99 classSymbol
->release();
102 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
104 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
106 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
107 classSymbol
->release();
111 void IOCatalogue::initialize( void )
114 OSString
* errorString
;
117 extern const char * gIOKernelConfigTables
;
119 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
120 if (!array
&& errorString
) {
121 IOLog("KernelConfigTables syntax error: %s\n",
122 errorString
->getCStringNoCopy());
123 errorString
->release();
126 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
127 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
128 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
);
130 gIOCatalogue
= new IOCatalogue
;
131 assert(gIOCatalogue
);
132 rc
= gIOCatalogue
->init(array
);
137 // Initialize the IOCatalog object.
138 bool IOCatalogue::init(OSArray
* initArray
)
140 IORegistryEntry
* entry
;
143 if ( !super::init() )
150 kernelTables
= OSCollectionIterator::withCollection( array
);
152 lock
= IOLockAlloc();
153 kld_lock
= IOLockAlloc();
155 kernelTables
->reset();
156 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
157 UniqueProperties(dict
);
158 if( 0 == dict
->getObject( gIOClassKey
))
159 IOLog("Missing or bad \"%s\" key\n",
160 gIOClassKey
->getCStringNoCopy());
164 AbsoluteTime deadline
;
165 clock_interval_to_deadline( 1000, kMillisecondScale
);
166 thread_call_func_delayed( ping
, this, deadline
);
169 entry
= IORegistryEntry::getRegistryRoot();
171 entry
->setProperty(kIOCatalogueKey
, this);
176 // Release all resources used by IOCatalogue and deallocate.
177 // This will probably never be called.
178 void IOCatalogue::free( void )
184 kernelTables
->release();
191 static int hackLimit
;
193 enum { kDriversPerIter
= 4 };
195 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
197 IOCatalogue
* self
= (IOCatalogue
*) arg
;
199 OSDictionary
* table
;
202 set
= OSOrderedSet::withCapacity( 1 );
204 IOTakeLock( &self
->lock
);
206 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
207 table
= (OSDictionary
*) self
->array
->getObject(
208 hackLimit
+ newLimit
);
210 set
->setLastObject( table
);
212 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
213 kprintf("enabling %s\n", sym
->getCStringNoCopy());
221 IOService::catalogNewDrivers( set
);
223 hackLimit
+= newLimit
;
226 IOUnlock( &self
->lock
);
228 if( kDriversPerIter
== newLimit
) {
229 AbsoluteTime deadline
;
230 clock_interval_to_deadline( 500, kMillisecondScale
);
231 thread_call_func_delayed( ping
, this, deadline
);
236 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
237 SInt32
* generationCount
)
239 OSDictionary
* nextTable
;
243 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
244 (void *)gIOProbeScoreKey
);
249 kernelTables
->reset();
254 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
256 if( hackIndex
++ > hackLimit
)
259 imports
= OSDynamicCast( OSString
,
260 nextTable
->getObject( gIOProviderClassKey
));
261 if( imports
&& service
->metaCast( imports
))
262 set
->setObject( nextTable
);
265 *generationCount
= getGenerationCount();
272 // Is personality already in the catalog?
273 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
274 SInt32
* generationCount
)
279 UniqueProperties(matching
);
281 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
282 (void *)gIOProbeScoreKey
);
285 kernelTables
->reset();
286 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
288 /* This comparison must be done with only the keys in the
289 * "matching" dict to enable general searches.
291 if ( dict
->isEqualTo(matching
, matching
) )
292 set
->setObject(dict
);
294 *generationCount
= getGenerationCount();
300 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
301 // XXX -- svail: This should be optimized.
302 // esb - There doesn't seem like any reason to do this - it causes problems
303 // esb - when there are more than one loadable driver matching on the same provider class
304 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
306 set
->setObject(dict
);
309 // Add driver config tables to catalog and start matching process.
310 bool IOCatalogue::addDrivers(OSArray
* drivers
,
311 bool doNubMatching
= true )
313 OSCollectionIterator
* iter
;
320 persons
= OSDynamicCast(OSArray
, drivers
);
324 iter
= OSCollectionIterator::withCollection( persons
);
328 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
329 (void *)gIOProbeScoreKey
);
336 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) ) {
339 UniqueProperties( dict
);
341 // Add driver personality to catalogue.
342 count
= array
->getCount();
344 OSDictionary
* driver
;
346 // Be sure not to double up on personalities.
347 driver
= (OSDictionary
*)array
->getObject(count
);
349 /* Unlike in other functions, this comparison must be exact!
350 * The catalogue must be able to contain personalities that
351 * are proper supersets of others.
352 * Do not compare just the properties present in one driver
353 * pesonality or the other.
355 if ( dict
->isEqualTo(driver
) ) {
356 array
->removeObject(count
);
361 ret
= array
->setObject( dict
);
365 AddNewImports( set
, dict
);
367 // Start device matching.
368 if ( doNubMatching
&& (set
->getCount() > 0) ) {
369 IOService::catalogNewDrivers( set
);
380 // Remove drivers from the catalog which match the
381 // properties in the matching dictionary.
382 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
383 bool doNubMatching
= true)
385 OSCollectionIterator
* tables
;
393 set
= OSOrderedSet::withCapacity(10,
395 (void *)gIOProbeScoreKey
);
399 arrayCopy
= OSArray::withCapacity(100);
405 tables
= OSCollectionIterator::withCollection(arrayCopy
);
406 arrayCopy
->release();
412 UniqueProperties( matching
);
415 kernelTables
->reset();
416 arrayCopy
->merge(array
);
417 array
->flushCollection();
419 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
421 /* This comparison must be done with only the keys in the
422 * "matching" dict to enable general searches.
424 if ( dict
->isEqualTo(matching
, matching
) ) {
425 AddNewImports( set
, dict
);
429 array
->setObject(dict
);
431 // Start device matching.
432 if ( doNubMatching
&& (set
->getCount() > 0) ) {
433 IOService::catalogNewDrivers(set
);
444 // Return the generation count.
445 SInt32
IOCatalogue::getGenerationCount( void ) const
447 return( generation
);
450 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
452 return isModuleLoaded(moduleName
->getCStringNoCopy());
455 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
457 kmod_info_t
* k_info
;
462 // Is the module already loaded?
463 k_info
= kmod_lookupbyname_locked((char *)moduleName
);
467 /* To make sure this operation completes even if a bad extension needs
468 * to be removed, take the kld lock for this whole block, spanning the
469 * kmod_load_function() and remove_startup_extension_function() calls.
471 IOLockLock(kld_lock
);
473 // If the module hasn't been loaded, then load it.
474 if (kmod_load_function
!= 0) {
476 ret
= kmod_load_function((char *)moduleName
);
478 if ( ret
!= kIOReturnSuccess
) {
479 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
481 /* If the extension couldn't be loaded this time,
482 * make it unavailable so that no more requests are
483 * made in vain. This also enables other matching
484 * extensions to have a chance.
486 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
487 (*remove_startup_extension_function
)(moduleName
);
489 IOLockUnlock(kld_lock
);
491 } else if (kernelLinkerPresent
) {
492 // If kern linker is here, the driver is actually loaded,
494 IOLockUnlock(kld_lock
);
497 // kern linker isn't here, a request has been queued
498 // but the module isn't necessarily loaded yet, so stall.
499 IOLockUnlock(kld_lock
);
503 IOLog("IOCatalogue: %s cannot be loaded "
504 "(kmod load function not set).\n",
508 IOLockUnlock(kld_lock
);
513 kfree(k_info
, sizeof(kmod_info_t
));
516 /* Lock wasn't taken if we get here. */
520 // Check to see if module has been loaded already.
521 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
523 OSString
* moduleName
= NULL
;
528 moduleName
= OSDynamicCast(OSString
, driver
->getObject(kModuleKey
));
530 return isModuleLoaded(moduleName
);
532 /* If a personality doesn't hold the "CFBundleIdentifier" key
533 * it is assumed to be an "in-kernel" driver.
538 // This function is called after a module has been loaded.
539 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
543 dict
= OSDictionary::withCapacity(2);
544 dict
->setObject(kModuleKey
, moduleName
);
549 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
553 name
= OSString::withCString(moduleName
);
554 moduleHasLoaded(name
);
558 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
560 kmod_info_t
* k_info
= 0;
564 ret
= kIOReturnBadArgument
;
566 name
= moduleName
->getCStringNoCopy();
567 k_info
= kmod_lookupbyname_locked((char *)name
);
568 if ( k_info
&& (k_info
->reference_count
< 1) ) {
570 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
572 kfree(k_info
, sizeof(kmod_info_t
));
576 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
581 kfree(k_info
, sizeof(kmod_info_t
));
587 static IOReturn
_terminateDrivers( OSArray
* array
, OSDictionary
* matching
)
589 OSCollectionIterator
* tables
;
597 return kIOReturnBadArgument
;
599 ret
= kIOReturnSuccess
;
601 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
602 kIORegistryIterateRecursively
);
604 return kIOReturnNoMemory
;
606 UniqueProperties( matching
);
608 // terminate instances.
611 while( (service
= (IOService
*)iter
->getNextObject()) ) {
612 dict
= service
->getPropertyTable();
616 /* Terminate only for personalities that match the matching dictionary.
617 * This comparison must be done with only the keys in the
618 * "matching" dict to enable general matching.
620 if ( !dict
->isEqualTo(matching
, matching
) )
623 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
624 ret
= kIOReturnUnsupported
;
628 } while( !service
&& !iter
->isValid());
631 // remove configs from catalog.
632 if ( ret
!= kIOReturnSuccess
)
635 arrayCopy
= OSArray::withCapacity(100);
637 return kIOReturnNoMemory
;
639 tables
= OSCollectionIterator::withCollection(arrayCopy
);
640 arrayCopy
->release();
642 return kIOReturnNoMemory
;
644 arrayCopy
->merge(array
);
645 array
->flushCollection();
647 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
649 /* Remove from the catalogue's array any personalities
650 * that match the matching dictionary.
651 * This comparison must be done with only the keys in the
652 * "matching" dict to enable general matching.
654 if ( dict
->isEqualTo(matching
, matching
) )
657 array
->setObject(dict
);
665 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
669 ret
= kIOReturnSuccess
;
671 ret
= _terminateDrivers(array
, matching
);
672 kernelTables
->reset();
678 IOReturn
IOCatalogue::terminateDriversForModule(
679 OSString
* moduleName
,
685 dict
= OSDictionary::withCapacity(1);
687 return kIOReturnNoMemory
;
689 dict
->setObject(kModuleKey
, moduleName
);
693 ret
= _terminateDrivers(array
, dict
);
694 kernelTables
->reset();
696 // Unload the module itself.
697 if ( unload
&& ret
== kIOReturnSuccess
) {
698 // Do kmod stop first.
699 ret
= unloadModule(moduleName
);
709 IOReturn
IOCatalogue::terminateDriversForModule(
710 const char * moduleName
,
716 name
= OSString::withCString(moduleName
);
718 return kIOReturnNoMemory
;
720 ret
= terminateDriversForModule(name
, unload
);
726 bool IOCatalogue::startMatching( OSDictionary
* matching
)
734 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
735 (void *)gIOProbeScoreKey
);
740 kernelTables
->reset();
742 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
744 /* This comparison must be done with only the keys in the
745 * "matching" dict to enable general matching.
747 if ( dict
->isEqualTo(matching
, matching
) )
748 AddNewImports(set
, dict
);
750 // Start device matching.
751 if ( set
->getCount() > 0 ) {
752 IOService::catalogNewDrivers(set
);
763 void IOCatalogue::reset(void)
766 OSDictionary
* entry
;
769 IOLog("Resetting IOCatalogue.\n");
772 tables
= OSArray::withArray(array
);
773 array
->flushCollection();
775 count
= tables
->getCount();
777 entry
= (OSDictionary
*)tables
->getObject(count
);
778 if ( entry
&& !entry
->getObject(kModuleKey
) ) {
779 array
->setObject(entry
);
783 kernelTables
->reset();
789 bool IOCatalogue::serialize(OSSerialize
* s
) const
797 ret
= array
->serialize(s
);
804 bool IOCatalogue::recordStartupExtensions(void) {
807 IOLockLock(kld_lock
);
808 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
809 result
= (*record_startup_extensions_function
)();
811 IOLog("Can't record startup extensions; "
812 "kernel linker is not present.\n");
815 IOLockUnlock(kld_lock
);
821 /*********************************************************************
822 *********************************************************************/
823 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
) {
826 IOLockLock(kld_lock
);
827 if (kernelLinkerPresent
&& add_from_mkext_function
) {
828 result
= (*add_from_mkext_function
)(mkext
);
830 IOLog("Can't add startup extensions from archive; "
831 "kernel linker is not present.\n");
834 IOLockUnlock(kld_lock
);
840 /*********************************************************************
841 * This function clears out all references to the in-kernel linker,
842 * frees the list of startup extensions in extensionDict, and
843 * deallocates the kernel's __KLD segment to reclaim that memory.
844 *********************************************************************/
845 kern_return_t
IOCatalogue::removeKernelLinker(void) {
846 kern_return_t result
= KERN_SUCCESS
;
847 extern struct mach_header _mh_execute_header
;
848 struct segment_command
* segment
;
849 char * dt_segment_name
;
850 void * segment_paddress
;
853 /* This must be the very first thing done by this function.
855 IOLockLock(kld_lock
);
858 /* If the kernel linker isn't here, that's automatically
861 if (!kernelLinkerPresent
) {
862 result
= KERN_SUCCESS
;
866 IOLog("Jettisoning kernel linker.\n");
868 kernelLinkerPresent
= 0;
870 /* Set the kmod_load_extension function as the means for loading
871 * a kernel extension.
873 kmod_load_function
= &kmod_load_extension
;
875 record_startup_extensions_function
= 0;
876 add_from_mkext_function
= 0;
877 remove_startup_extension_function
= 0;
880 /* Invoke destructors for the __KLD and __LINKEDIT segments.
881 * Do this for all segments before actually freeing their
882 * memory so that any cross-dependencies (not that there
883 * should be any) are handled.
885 segment
= getsegbynamefromheader(
886 &_mh_execute_header
, "__KLD");
888 IOLog("error removing kernel linker: can't find __KLD segment\n");
889 result
= KERN_FAILURE
;
892 OSRuntimeUnloadCPPForSegment(segment
);
894 segment
= getsegbynamefromheader(
895 &_mh_execute_header
, "__LINKEDIT");
897 IOLog("error removing kernel linker: can't find __LINKEDIT segment\n");
898 result
= KERN_FAILURE
;
901 OSRuntimeUnloadCPPForSegment(segment
);
904 /* Free the memory that was set up by bootx.
906 dt_segment_name
= "Kernel-__KLD";
907 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
908 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
912 dt_segment_name
= "Kernel-__LINKEDIT";
913 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
914 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
921 /* This must be the very last thing done before returning.
923 IOLockUnlock(kld_lock
);