Kext loads well after launchd and early os_log entries rarely appear in unified log

Is there a way to ensure a kernel extension in the Auxiliary Kernel Collection loads (and runs its start routines) before launchd?

I'm emitting logs via os_log_t created with an os_log_create (custom subsystem/category) in both my KMOD's start function and the IOService::start() function. Those messages-- which both say "I've been run"-- inconsistently show up in log show --predicate 'subsystem == "com.bluefalconhd.pandora"' --last boot, which makes me think they are running very early. However, I also record timestamps (using mach_absolute_time, etc.) and expose them to user space through an IOExternalMethod. The results (for the most recent boot):

hayes@fortis Pandora/tests main % build/pdtest
Pandora Metadata:
  kmod_start_time:
    Time: 2025-07-22 14:11:32.233
    Mach time: 245612546
    Nanos since boot: 10233856083 (10.23 seconds)
  io_service_start_time:
    Time: 2025-07-22 14:11:32.233
    Mach time: 245613641
    Nanos since boot: 10233901708 (10.23 seconds)
  user_client_init_time:
    Time: 2025-07-22 14:21:42.561
    Mach time: 14893478355
    Nanos since boot: 620561598125 (620.56 seconds)

hayes@fortis Pandora/tests main % ps -p 1 -o lstart=
Tue Jul 22 14:11:27 2025

Everything in the kernel extension appears to be loading after launchd (PID 1) starts. Also, the kext isn't doing anything crazy which could cause that kind of delay.

For reference, here's the Info.plist:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>Pandora</string>
	<key>CFBundleIdentifier</key>
	<string>com.bluefalconhd.Pandora</string>
	<key>CFBundleName</key>
	<string>Pandora</string>
	<key>CFBundlePackageType</key>
	<string>KEXT</string>
	<key>CFBundleVersion</key>
	<string>1.0.7</string>
	<key>IOKitPersonalities</key>
	<dict>
		<key>Pandora</key>
		<dict>
			<key>CFBundleIdentifier</key>
			<string>com.bluefalconhd.Pandora</string>
			<key>IOClass</key>
			<string>Pandora</string>
			<key>IOMatchCategory</key>
			<string>Pandora</string>
			<key>IOProviderClass</key>
			<string>IOResources</string>
			<key>IOResourceMatch</key>
			<string>IOKit</string>
			<key>IOUserClientClass</key>
			<string>PandoraUserClient</string>
		</dict>
	</dict>
	<key>OSBundleLibraries</key>
	<dict>
		<key>com.apple.kpi.dsep</key>
		<string>24.2.0</string>
		<key>com.apple.kpi.iokit</key>
		<string>24.2.0</string>
		<key>com.apple.kpi.libkern</key>
		<string>24.2.0</string>
		<key>com.apple.kpi.mach</key>
		<string>24.2.0</string>
	</dict>
</dict>
</plist>

My questions are:

  • A. Why don't the early logs (from KMOD's start function and IOService::start) consistently appear in the unified log, while logs later in IOExternalMethods do?
  • B. How can I force this kext to load earlier-- ideally before launchd?

Thanks in advance for any guidance!

Kext loads well after launchd and early os_log entries rarely appear in unified log
 
 
Q