6

Appleの「カーネル拡張」チュートリアルをやろうとしています。プロジェクト ファイルを作成し、Info.plist を作成し、ビルドし、kextlibs を使用して依存関係を学習し、それらを Info.plist に追加し、再ビルドし、/tmp にコピーし、kextutil を使用してテストしました。これまでのところすべて順調です。ただし、kext をロードしようとすると、start/stop/probe 関数が呼び出されないようです。IOLog メッセージが /var/log/system.log に表示されません。

実際、system.log には何も表示されません。sysctl -w debug.kextlog=0x0007780E で kext ロギングを有効にすると、kernel.log が記録されます。kernel.log には、「Kext ch.digorydoo.driver.XinputDevice は依存関係を正常に解決しました」と表示されます。次に、「ロードされていないkextとその他の未使用データをフラッシュしています。」多分私のクラスはすぐにフラッシュされますか?

私のクラスは kextstat の最後に表示されますが、参照はありません。ioclasscount と同じです。ioreg で、自分のクラスが表示されません。

IOProviderClass を IOResources に設定したので、常に参照が必要ですよね? IOMatchCategory を適切に設定しました。

何か助けて?!?! どうもありがとう!

編集: ここに私の 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>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleIdentifier</key>
    <string>ch.digorydoo.driver.${PRODUCT_NAME:rfc1034identifier}</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundlePackageType</key>
    <string>KEXT</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0.0</string>
    <key>IOKitPersonalities</key>
    <dict>
        <key>Generic Xinput Gamepad</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>ch.digorydoo.driver.${PRODUCT_NAME:rfc1034identifier}</string>
            <key>IOProviderClass</key>
            <string>IOResources</string>
            <key>IOMatchCategory</key>
            <string>ch_digorydoo_driver_XinputDevice</string>
            <key>IOClass</key>
            <string>ch_digorydoo_driver_XinputDevice</string>
            <key>IOKitDebug</key>
            <integer>65535</integer>
        </dict>
    </dict>
    <key>OSBundleLibraries</key>
    <dict>
        <key>com.apple.kpi.iokit</key>
        <string>10.8</string>
        <key>com.apple.kpi.libkern</key>
        <string>10.8</string>
        <key>com.apple.kpi.mach</key>
        <string>10.8</string>
    </dict>
</dict>
</plist>
4

1 に答える 1

1

私の単純な KEXT が開始されない理由はまだわかりません。kextutil からの出力は次のとおりです。

$ kextutil -t -n XinputDevice.kext
No kernel file specified; using running kernel for linking.
Notice: XinputDevice.kext has debug properties set.
XinputDevice.kext appears to be loadable (including linkage for on-disk libraries).

KEXTをロードすると、「リンケージを含まないロード可能」と表示されますが、それでもロードされたと表示されることに注意してください。

$ kextutil -v 4 XinputDevice.kext 
Kext library architecture set to i386.
Kext library recording diagnostics for: validation authentication dependencies warnings.
Notice: XinputDevice.kext has debug properties set.
XinputDevice.kext appears to be loadable (not including linkage for on-disk libraries).
Loading XinputDevice.kext.
Reading load info for all kexts.
Reading loaded kext info from kernel.
Adding /private/tmp/XinputDevice.kext to mkext.
/private/tmp/XinputDevice.kext added 29260-byte noncompressed executable to mkext.
Created mkext for architecture i386 containing 1 kexts.
Loading XinputDevice.kext.
(kernel) Received request from user space to load kext ch.digorydoo.driver.XinputDevice.
(kernel) Recorded kext ch.digorydoo.driver.XinputDevice as a candidate for inclusion in prelinked kernel.
(kernel) Loading kext ch.digorydoo.driver.XinputDevice.
(kernel) Allocated link buffer for kext ch.digorydoo.driver.XinputDevice at 0x4d1e6000 (8192 bytes).
(kernel) Kext ch.digorydoo.driver.XinputDevice executable loaded; 2 pages at 0x4d1e6000 (load tag 114).
(kernel) Kext ch.digorydoo.driver.XinputDevice calling module start function.  ####
(kernel) Kext ch.digorydoo.driver.XinputDevice registered class ch_digorydoo_driver_XinputDevice.
(kernel) Kext ch.digorydoo.driver.XinputDevice has IOService subclass ch_digorydoo_driver_XinputDevice; enabling autounload.
(kernel) Kext ch.digorydoo.driver.XinputDevice is now started.
(kernel) Kext ch.digorydoo.driver.XinputDevice sending 1 personality to the IOCatalogue and starting matching.
(kernel) Kext ch.digorydoo.driver.XinputDevice loaded.
Successfully loaded XinputDevice.kext.
XinputDevice.kext successfully loaded (or already loaded).

上記の #### でマークした行には、start 関数が呼び出されたことが示されています。しかし、私の start() は IOLog を呼び出し、/var/log/system.log にメッセージを書き込む必要があるため、そうではありません。

/var/log/kernel.log に表示される内容は次のとおりです。

Jan  5 15:20:00 karaboudjan3 kernel[0]: Kext ch.digorydoo.driver.XinputDevice, v1.0 registered and available for loading.
Jan  5 15:20:00 karaboudjan3 kernel[0]: Kext ch.digorydoo.driver.XinputDevice resolving dependencies.
Jan  5 15:20:00 karaboudjan3 kernel[0]: Kext ch.digorydoo.driver.XinputDevice added dependency com.apple.kpi.mach.
Jan  5 15:20:00 karaboudjan3 kernel[0]: Kext ch.digorydoo.driver.XinputDevice added dependency com.apple.kpi.iokit.
Jan  5 15:20:00 karaboudjan3 kernel[0]: Kext ch.digorydoo.driver.XinputDevice added dependency com.apple.kpi.libkern.
Jan  5 15:20:00 karaboudjan3 kernel[0]: Kext ch.digorydoo.driver.XinputDevice successfully resolved dependencies.
Jan  5 15:20:00 karaboudjan3 kernel[0]: Flushing nonloaded kexts and other unused data.

実際、クラスはロードされますが、インスタンスは作成されません。

$ ioclasscount | grep digory
ch_digorydoo_driver_XinputDevice = 0

$ kextstat | grep digory
  116    0 0x106f000  0x2000     0x1000     ch.digorydoo.driver.XinputDevice (1.0.0) <5 4 3>

クラスが I/O レジストリに表示されない:

$ ioreg | grep Xinput
$ ioreg | grep digory

インスタンスがないということは、init または start の呼び出しがないことを意味するため、IOLog はありません。誰もクラスを使用しない場合、ライブ オブジェクトのレジストリに明らかに表示されません。

私の結論は、チュートリアルが間違っているに違いないということです! プロバイダー クラスが IOResources であっても、クラスがインスタンス化されることはありません。

IOResources を IOUSBDevice に置き換えてみました。私は idProduct や idVendor を提供していないので、どの USB デバイスも一致するはずです。私が間違っていない限り、USB デバイスをリッスンしているデーモンは、クラスをインスタンス化し、probe() を呼び出して、これがデバイスに適したドライバーであるかどうかを確認する必要があります。

残念ながら、まだ system.log にログ メッセージがありません!! USB デバイスを担当するデーモンはどれですか? 私のKEXTがチャンスを得る前に、新しく接続されたデバイスをどういうわけか「食べる」ドライバがあるのでしょうか? デーモンが選択したドライバーを追跡するにはどうすればよいですか?

ヒントは?!?

于 2013-01-05T14:37:28.983 に答える