• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Understanding kexts in the early boot process
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Understanding kexts in the early boot process


  • Subject: Re: Understanding kexts in the early boot process
  • From: David Elliott <email@hidden>
  • Date: Tue, 16 Jun 2009 08:25:47 -0400

On Jun 14, 2009, at 5:51 PM, Shantonu Sen wrote:



On Jun 14, 2009, at 2:38 PM, Thomas Tempelmann wrote:


What I haven't seen yet is the part that links the kexts (apparently
loaded by the boot loader) to the kernel. Does the boot_args struct
have a new parameter (not doc'd in Amit's book) which passes a pointer
to a list of loaded kexts to the kernel, or how does this work?



<http://opensource.apple.com/source/xnu/xnu-1228.12.14/libsa/catalogue.cpp >


This is definitely the file to start with.


Background is this: It appears that a 3rd party boot loader is able to
load two sets of kexts from different locations and get them used by
the kernel. I try to understand how that works, because so far all I
learned was that there's only one single group of kexts that the
kernel sees, not several.



You'd probably have to ask the maintainer of that boot loader.


Well, I'm not sure what bootloader exactly he's referring to, but I can be reasonably sure that it's a derivative of mine which is in turn a derivative of the traditional Darwin x86 "boot".[1]


You can find info (outdated, sorry) on it here:
http://tgwbd.org/darwin/boot.html

The public SVN tree is also available (can be used with SVN client or the latest revision can be browsed online):

http://tgwbd.org/svn/Darwin/boot/branches/public/

Another interesting resource is the BootX bootloader used on PowerPC Macs. As the Apple guys mentioned, the kext or mkext are loaded from disk (or network, but not working in "boot") by the bootloader be it BootX, boot, or boot.efi. The pointers to the in memory blobs are then passed into the kernel through entries in the device tree. These entries are the same regardless of platform.


At any rate, the answer to the question is that the kernel doesn't really see it specifically as "two sets" of kernel extensions. If you look at libsa/catalogue.cpp you will find that it enumerates "/chosen/ memory-map" in gIODTPlane (the device tree plane is a plane that starts out initialized by the bootloader).


A good place to start is the recordStartupExtensions function. For every child node whose name begins with "Driver-" it treats it as a kext bundle whose contents were read into memory by the bootloader and records it. For every child node whose name begins with "DriversPackage-" it treats it as an mkext bundle.

This happens in a loop until all Driver-* and DriversPackage-* entries have been enumerated. So although normally the bootloader with either pass in one DriversPackage-* entry (i.e. Extensions.mkext was determined to be up to date) or multiple Driver-* entries (i.e. Extensions.mkext does not exist or was determined to be out of date) there is no specific requirement kernel-side that this be the case. You can mix and match all you want.


Now, for a little bit of background.

In order to get OS X guest support working with Fusion we needed a way to add some extensions beyond those provided by Apple. Modifying the DVD was not even considered. The final product would have to be able to boot a retail boxed DVD. No tricks of any kind like modifying the filesystem behind the user's back.

As I recall (and it's been a while now), one idea we almost settled on was to unpack the Extensions.mkext within the bootloader and pass the individual drivers to the kernel, removing some we didn't want, adding extras we did want, and modifying plists for some to make them drive more hardware[2]. I worked on this very early and at the time Fusion didn't even have a USB keyboard so if you wanted to type anything you needed PS/2 support in the guest.

So as I began to research how I would implement this I took a look at the way the booter was passing the extensions in, both when it passed in a single mkext and also when it passed in individual drivers. I quickly released that essentially it was just forming a list of the in- memory blobs and passing pointers to the blobs to the kernel through the IODeviceTree.

This led me to the libsa/catalogue.cpp file which revealed to me that the kernel is perfectly happy with any combination of kext (Driver-*) and mkext (DriversPackage-*). I realized I could pass in Extensions.mkext from the root device and still add in extra kexts or even a second mkext. All I needed to do was simply add the additional entries to the device tree. Of course using this method I could only add extra extensions. Modifying existing extensions would not be possible nor would removing them be possible. But removing them isn't really possible anyway if they are present on the root device because eventually kextd will run and will load them.

I would say I probably spent more time discovering this useful tidbit of information than I actually spent implementing it. Once I knew how the kernel interpreted the information the implementation was really rather trivial.

Hopefully that provides a little bit of background on how the extension loading process works and how extra extensions came to be. One thing to be aware of is that the bootloader does NOT do hardware detection to determine which extensions to load. As the Apple guys have mentioned, it uses OSBundleRequired.[3] This is buried in the source somewhere. The "Extra" extensions are loaded exactly the same way that the main ones are. So if .../Extra/Extensions.mkext is determined to be valid it loads. Otherwise .../Extra/Extensions is enumerated for kexts with an appropriate OSBundleRequired. That is in fact why it's Extra/Extensions and not ExtraExtensions or Extra_Extensions. It allowed me to use the same well-exercised code path.

Personally I felt it was quite a hack to be able to load extra extensions beyond those present on the root device. But perhaps I need to choose my language more carefully and explain that that means I thought it was clever, lest I find myself in a room with an ignorant lawyer working for Apple asking me stupid questions again. Shakespeare was right.

-Dave

Footnotes:
1. Apple's boot in turn contains a fair amount of code very clearly derived from BSD and Mach. A fair amount of the support code hasn't changed in decades.


2. Somewhere around the time I figured out how to add extra kernel extensions I also figured out that the CFBundleIdentifier property of a personality can perfectly well refer to some other extension. So it became possible to add support for VMware's PIIX4 by putting the personality dictionary's from the Darwin release of AppleIntelPIIXATA into a new kext's Info.plist (one with a different top-level CFBundleIdentifier). By leaving the CFBundleIdentifier of the personalities themselves set to com.apple.driver.AppleIntelPIIXATA the kernel will load AppleIntelPIIXATA when one of these personalities matches. Assuming AppleIntelPIIXATA's probe method doesn't check for this case and fail probe. And assuming that it is capable of driving the hardware. This allowed me to add support for the PIIX4 by adding a new kext (with no real binary code) with the personalities rather than modifying the plist of the existing extension to add the personalities.

3. It's not particularly interesting except from an archeological standpoint, but there are remnants of code in the booter from an earlier time when it did apparently do some hardware detection to determine which extensions to load. It looks like this may have died with DriverKit which is the Objective-C precursor to the C++ IOKit.

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >Understanding kexts in the early boot process (From: Thomas Tempelmann <email@hidden>)
 >Re: Understanding kexts in the early boot process (From: Michael Smith <email@hidden>)
 >Re: Understanding kexts in the early boot process (From: Thomas Tempelmann <email@hidden>)
 >Re: Understanding kexts in the early boot process (From: Shantonu Sen <email@hidden>)

  • Prev by Date: Re: x87 status word size
  • Next by Date: Re: Understanding kexts in the early boot process
  • Previous by thread: Re: Understanding kexts in the early boot process
  • Next by thread: Re: Understanding kexts in the early boot process
  • Index(es):
    • Date
    • Thread