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();
153 kernelTables
->reset();
154 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
155 UniqueProperties(dict
);
156 if( 0 == dict
->getObject( gIOClassKey
))
157 IOLog("Missing or bad \"%s\" key\n",
158 gIOClassKey
->getCStringNoCopy());
162 AbsoluteTime deadline
;
163 clock_interval_to_deadline( 1000, kMillisecondScale
);
164 thread_call_func_delayed( ping
, this, deadline
);
167 entry
= IORegistryEntry::getRegistryRoot();
169 entry
->setProperty(kIOCatalogueKey
, this);
174 // Release all resources used by IOCatalogue and deallocate.
175 // This will probably never be called.
176 void IOCatalogue::free( void )
182 kernelTables
->release();
189 static int hackLimit
;
191 enum { kDriversPerIter
= 4 };
193 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
195 IOCatalogue
* self
= (IOCatalogue
*) arg
;
197 OSDictionary
* table
;
200 set
= OSOrderedSet::withCapacity( 1 );
202 IOTakeLock( &self
->lock
);
204 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
205 table
= (OSDictionary
*) self
->array
->getObject(
206 hackLimit
+ newLimit
);
208 set
->setLastObject( table
);
210 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
211 kprintf("enabling %s\n", sym
->getCStringNoCopy());
219 IOService::catalogNewDrivers( set
);
221 hackLimit
+= newLimit
;
224 IOUnlock( &self
->lock
);
226 if( kDriversPerIter
== newLimit
) {
227 AbsoluteTime deadline
;
228 clock_interval_to_deadline( 500, kMillisecondScale
);
229 thread_call_func_delayed( ping
, this, deadline
);
234 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
235 SInt32
* generationCount
)
237 OSDictionary
* nextTable
;
241 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
242 (void *)gIOProbeScoreKey
);
247 kernelTables
->reset();
252 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
254 if( hackIndex
++ > hackLimit
)
257 imports
= OSDynamicCast( OSString
,
258 nextTable
->getObject( gIOProviderClassKey
));
259 if( imports
&& service
->metaCast( imports
))
260 set
->setObject( nextTable
);
263 *generationCount
= getGenerationCount();
270 // Is personality already in the catalog?
271 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
272 SInt32
* generationCount
)
277 UniqueProperties(matching
);
279 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
280 (void *)gIOProbeScoreKey
);
283 kernelTables
->reset();
284 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
285 if ( dict
->isEqualTo(matching
, matching
) )
286 set
->setObject(dict
);
288 *generationCount
= getGenerationCount();
294 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
295 // XXX -- svail: This should be optimized.
296 // esb - There doesn't seem like any reason to do this - it causes problems
297 // esb - when there are more than one loadable driver matching on the same provider class
298 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
300 set
->setObject(dict
);
303 // Add driver config tables to catalog and start matching process.
304 bool IOCatalogue::addDrivers(OSArray
* drivers
,
305 bool doNubMatching
= true )
307 OSCollectionIterator
* iter
;
314 persons
= OSDynamicCast(OSArray
, drivers
);
318 iter
= OSCollectionIterator::withCollection( persons
);
322 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
323 (void *)gIOProbeScoreKey
);
330 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) ) {
333 UniqueProperties( dict
);
335 // Add driver personality to catalogue.
336 count
= array
->getCount();
338 OSDictionary
* driver
;
340 // Be sure not to double up on personalities.
341 driver
= (OSDictionary
*)array
->getObject(count
);
342 if ( dict
->isEqualTo(driver
, driver
) ) {
343 array
->removeObject(count
);
348 ret
= array
->setObject( dict
);
352 AddNewImports( set
, dict
);
354 // Start device matching.
355 if ( doNubMatching
&& (set
->getCount() > 0) ) {
356 IOService::catalogNewDrivers( set
);
361 if ( doNubMatching
) {
362 (IOService::getServiceRoot())->waitQuiet();
363 kmod_send_generic( kIOCatalogMatchIdle
, 0, 0 );
372 // Remove drivers from the catalog which match the
373 // properties in the matching dictionary.
374 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
375 bool doNubMatching
= true)
377 OSCollectionIterator
* tables
;
385 set
= OSOrderedSet::withCapacity(10,
387 (void *)gIOProbeScoreKey
);
391 arrayCopy
= OSArray::withCapacity(100);
397 tables
= OSCollectionIterator::withCollection(arrayCopy
);
398 arrayCopy
->release();
404 UniqueProperties( matching
);
407 kernelTables
->reset();
408 arrayCopy
->merge(array
);
409 array
->flushCollection();
411 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
412 if ( dict
->isEqualTo(matching
, matching
) ) {
413 AddNewImports( set
, dict
);
417 array
->setObject(dict
);
419 // Start device matching.
420 if ( doNubMatching
&& (set
->getCount() > 0) ) {
421 IOService::catalogNewDrivers(set
);
432 // Return the generation count.
433 SInt32
IOCatalogue::getGenerationCount( void ) const
435 return( generation
);
438 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
440 return isModuleLoaded(moduleName
->getCStringNoCopy());
443 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
445 kmod_info_t
* k_info
;
450 // Is the module already loaded?
451 k_info
= kmod_lookupbyname((char *)moduleName
);
455 // If the module hasn't been loaded, then load it.
456 if (kmod_load_function
!= 0) {
457 ret
= kmod_load_function((char *)moduleName
);
458 if ( ret
!= kIOReturnSuccess
) {
459 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
461 /* If the extension couldn't be loaded this time,
462 * make it unavailable so that no more requests are
463 * made in vain. This also enables other matching
464 * extensions to have a chance.
466 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
467 (*remove_startup_extension_function
)(moduleName
);
470 } else if (kernelLinkerPresent
) {
471 // If kern linker is here, the driver is actually loaded,
475 // kern linker isn't here, a request has been queued
476 // but the module isn't necessarily loaded yet, so stall.
480 IOLog("IOCatalogue: %s cannot be loaded "
481 "(kmod load function not set).\n",
491 // Check to see if module has been loaded already.
492 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
494 OSString
* moduleName
= NULL
;
499 moduleName
= OSDynamicCast(OSString
, driver
->getObject(kModuleKey
));
501 return isModuleLoaded(moduleName
);
503 /* If a personality doesn't hold the "CFBundleIdentifier" key
504 * it is assumed to be an "in-kernel" driver.
509 // This function is called after a module has been loaded.
510 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
514 dict
= OSDictionary::withCapacity(2);
515 dict
->setObject(kModuleKey
, moduleName
);
520 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
524 name
= OSString::withCString(moduleName
);
525 moduleHasLoaded(name
);
529 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
531 kmod_info_t
* k_info
;
535 ret
= kIOReturnBadArgument
;
537 name
= moduleName
->getCStringNoCopy();
538 k_info
= kmod_lookupbyname((char *)name
);
539 if ( k_info
&& (k_info
->reference_count
< 1) ) {
541 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) )
544 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
551 static IOReturn
_terminateDrivers( OSArray
* array
, OSDictionary
* matching
)
553 OSCollectionIterator
* tables
;
554 OSCollectionIterator
* props
;
562 return kIOReturnBadArgument
;
564 ret
= kIOReturnSuccess
;
566 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
567 kIORegistryIterateRecursively
);
569 return kIOReturnNoMemory
;
571 UniqueProperties( matching
);
573 props
= OSCollectionIterator::withCollection(matching
);
576 return kIOReturnNoMemory
;
579 // terminate instances.
582 while( (service
= (IOService
*)iter
->getNextObject()) ) {
583 dict
= service
->getPropertyTable();
587 if ( !dict
->isEqualTo(matching
, matching
) )
590 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
591 ret
= kIOReturnUnsupported
;
595 } while( !service
&& !iter
->isValid());
598 // remove configs from catalog.
599 if ( ret
!= kIOReturnSuccess
)
602 arrayCopy
= OSArray::withCapacity(100);
604 return kIOReturnNoMemory
;
606 tables
= OSCollectionIterator::withCollection(arrayCopy
);
607 arrayCopy
->release();
609 return kIOReturnNoMemory
;
611 arrayCopy
->merge(array
);
612 array
->flushCollection();
614 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
615 if ( dict
->isEqualTo(matching
, matching
) )
618 array
->setObject(dict
);
626 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
630 ret
= kIOReturnSuccess
;
632 ret
= _terminateDrivers(array
, matching
);
633 kernelTables
->reset();
639 IOReturn
IOCatalogue::terminateDriversForModule(
640 OSString
* moduleName
,
646 dict
= OSDictionary::withCapacity(1);
648 return kIOReturnNoMemory
;
650 dict
->setObject(kModuleKey
, moduleName
);
654 ret
= _terminateDrivers(array
, dict
);
655 kernelTables
->reset();
657 // Unload the module itself.
658 if ( unload
&& ret
== kIOReturnSuccess
) {
659 // Do kmod stop first.
660 ret
= unloadModule(moduleName
);
670 IOReturn
IOCatalogue::terminateDriversForModule(
671 const char * moduleName
,
677 name
= OSString::withCString(moduleName
);
679 return kIOReturnNoMemory
;
681 ret
= terminateDriversForModule(name
, unload
);
687 bool IOCatalogue::startMatching( OSDictionary
* matching
)
695 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
696 (void *)gIOProbeScoreKey
);
701 kernelTables
->reset();
703 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
704 if ( dict
->isEqualTo(matching
, matching
) )
705 AddNewImports(set
, dict
);
707 // Start device matching.
708 if ( set
->getCount() > 0 ) {
709 IOService::catalogNewDrivers(set
);
720 void IOCatalogue::reset(void)
723 OSDictionary
* entry
;
726 IOLog("Resetting IOCatalogue.\n");
729 tables
= OSArray::withArray(array
);
730 array
->flushCollection();
732 count
= tables
->getCount();
734 entry
= (OSDictionary
*)tables
->getObject(count
);
735 if ( entry
&& !entry
->getObject(kModuleKey
) ) {
736 array
->setObject(entry
);
740 kernelTables
->reset();
746 bool IOCatalogue::serialize(OSSerialize
* s
) const
754 ret
= array
->serialize(s
);
761 bool IOCatalogue::recordStartupExtensions(void) {
764 if (record_startup_extensions_function
) {
765 result
= (*record_startup_extensions_function
)();
767 IOLog("Can't record startup extensions; "
768 "kernel linker is not present.\n");
776 /*********************************************************************
777 *********************************************************************/
778 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
) {
781 if (add_from_mkext_function
) {
782 result
= (*add_from_mkext_function
)(mkext
);
784 IOLog("Can't add startup extensions from archive; "
785 "kernel linker is not present.\n");
793 /*********************************************************************
794 * This function clears out all references to the in-kernel linker,
795 * frees the list of startup extensions in extensionDict, and
796 * deallocates the kernel's __KLD segment to reclaim that memory.
797 *********************************************************************/
798 kern_return_t
IOCatalogue::removeKernelLinker(void) {
799 kern_return_t result
= KERN_SUCCESS
;
800 extern struct mach_header _mh_execute_header
;
801 struct segment_command
* segment
;
802 char * dt_segment_name
;
803 void * segment_paddress
;
806 /* This must be the very first thing done by this function.
811 /* If the kernel linker isn't here, that's automatically
814 if (!kernelLinkerPresent
) {
815 result
= KERN_SUCCESS
;
819 IOLog("Jettisoning kernel linker.\n");
821 kernelLinkerPresent
= 0;
823 /* Set the kmod_load_extension function as the means for loading
824 * a kernel extension.
826 kmod_load_function
= &kmod_load_extension
;
828 record_startup_extensions_function
= 0;
829 add_from_mkext_function
= 0;
830 remove_startup_extension_function
= 0;
833 /* Invoke destructors for the __KLD and __LINKEDIT segments.
834 * Do this for all segments before actually freeing their
835 * memory so that any cross-dependencies (not that there
836 * should be any) are handled.
838 segment
= getsegbynamefromheader(
839 &_mh_execute_header
, "__KLD");
841 result
= KERN_FAILURE
;
844 OSRuntimeUnloadCPPForSegment(segment
);
846 segment
= getsegbynamefromheader(
847 &_mh_execute_header
, "__LINKEDIT");
849 result
= KERN_FAILURE
;
852 OSRuntimeUnloadCPPForSegment(segment
);
855 /* Free the memory that was set up by bootx.
857 dt_segment_name
= "Kernel-__KLD";
858 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
859 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
863 dt_segment_name
= "Kernel-__LINKEDIT";
864 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
865 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
872 /* This must be the very last thing done before returning.