Más contenido relacionado
La actualidad más candente (20)
Similar a Driverについて (20)
Driverについて
- 1. Driverについて
最近の状況の整理
2013.07.06
Bitz Co., Ltd. 村上幸雄
1. はじめに
Apple開発者のサイトでDarwinのソースコードが公開されているが、ドライバ関連で
は、文書とサンプルコードも付属しているので、開発したいものに近いサンプルコードを
基に拡張していう方法もあるが、今回は、Xcodeの新規プロジェクトから製作してみよう
と思う。
• Open Source - Releases
http://www.opensource.apple.com/
• Mac OS X 10.7.5 - Source
http://www.opensource.apple.com/release/mac-os-x-1075/"
Xcodeでドライバの新規プロジェクトを生成する場合、雛形としては、Generic
Kernel ExtensionとIOKit Driverの二種類があるが、その違いについてまとめてみる。
Generic kernel extension template
IOKit driver template
開発言語
C
Embedded C++
実装方法
コールバック関数
I/O Kitクラスの派生クラス
実行方法
明示的に起動と停止
自動
2. kext(generic kernel extension)
新規プロジェクトで、Generic kernel extension templateを選択する。
- 2. プロジェクト名は、Smart Scrollという製品に対するプログラムを作成しようと思っ
たので、サンプルでは、SmartScrollKextとした。
TARGETSのArchitecturesのBuild Active Architecture Onlyは、NOを選択する。
これを設定しておかないと、32bitカーネルで動作している開発機で、64bitドライバを生
成し、テストに失敗してしまうなどのトラブルに遭遇する可能性がある。
SmartScrollKext.cにデバッグ出力を追加する。
#include <sys/systm.h>
#include <mach/mach_types.h>
kern_return_t SmartScrollKext_start(kmod_info_t * ki, void *d);
kern_return_t SmartScrollKext_stop(kmod_info_t *ki, void *d);
kern_return_t SmartScrollKext_start(kmod_info_t * ki, void *d)
{
printf("SmartScrollKext has started.n");
return KERN_SUCCESS;
}
kern_return_t SmartScrollKext_stop(kmod_info_t *ki, void *d)
{
printf("SmartScrollKext has stopped.n");
return KERN_SUCCESS;
}
SmartScrollKext-Info.plistのCFBundleIdentifierをcom.MyCompany.kext.$
{PRODUCT_NAME:rfc1034identifier}に変更する。下記の例では、MyCompanyは著
者の会社のものにしている。
- 3. 一度、プロジェクトをビルドする。Show the Log Navigatorから
SmartScrollKext.kextの出力先を調べて、ターミナル.appで、そのディレクトリに移動
する。
$ cd Build/Products/Debug
そこで以下のコマンドを実行する。
$ kextlibs -xml SmartScrollKext.kext
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.libkern</key>
<string>11.4.2</string>
</dict>
この内容をSmartScrollKext-Info.plistのOSBundleLibrariesに設定する。
再度、ビルドし、生成されたSmartScrollKext.kextを/tmpにコピーする。
$ sudo cp -R SmartScrollKext.kext /tmp
以下のコマンドで、問題がないか確認する。
$ kextutil -n -print-diagnostics /tmp/SmartScrollKext.kext
No kernel file specified; using running kernel for linking.
/tmp/SmartScrollKext.kext appears to be loadable (including linkage for on-disk
libraries).
ログ確認の準備を行う。
$ cd /var/log
$ tail -f kernel.log
- 4. ロードする。
$ sudo kextload /tmp/SmartScrollKext.kext
アンロードする。
$ sudo kextunload /tmp/SmartScrollKext.kext
ログにデバッグ出力が印字されている事を確認する。
Jun 24 00:31:39 マシン名 kernel[0]: SmartScrollKext has started.
Jun 24 00:33:08 マシン名 kernel[0]: SmartScrollKext has stopped.
3. I/O Kitドライバ
新規プロジェクトで、IOKit driver templateを選択する。
プロジェクト名は、前回の流れからSmartScrollDriverとした。
今回も、前回と同様にTARGETSのArchitecturesのBuild Active Architecture Only
は、NOを選択する。
SmartScrollDriver-Info.plistのCFBundleIdentifierをcom.MyCompany.driver.$
{PRODUCT_NAME:rfc1034identifier}に変更する。著者は、MyCompanyに自分の会
社のものにしている。
- 6. #include <IOKit/IOLib.h>
#include "SmartScrollDriver.h"
OSDefineMetaClassAndStructors(jp_co_bitz_driver_SmartScrollDriver,
IOService)
#define super IOService
bool jp_co_bitz_driver_SmartScrollDriver::init(OSDictionary *dict)
{
bool result = super::init(dict);
IOLog("Initializingn");
return result;
}
void jp_co_bitz_driver_SmartScrollDriver::free(void)
{
IOLog("Freeingn");
super::free();
}
IOService *jp_co_bitz_driver_SmartScrollDriver::probe(IOService
*provider,
SInt32 *score)
{
IOService *result = super::probe(provider, score);
IOLog("Probingn");
return result;
}
bool jp_co_bitz_driver_SmartScrollDriver::start(IOService *provider)
{
bool result = super::start(provider);
IOLog("Startingn");
return result;
}
void jp_co_bitz_driver_SmartScrollDriver::stop(IOService *provider)
{
IOLog("Stoppingn");
super::stop(provider);
}
一度、プロジェクトをビルドする。Show the Log Navigatorから
SmartScrollDriver.kextの出力先を調べて、ターミナル.appで、そのディレクトリに移動
する。
$ cd Build/Products/Debug
そこで以下のコマンドを実行する。
- 7. $ kextlibs -xml SmartScrollDriver.kext
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.iokit</key>
<string>11.4.2</string>
<key>com.apple.kpi.libkern</key>
<string>11.4.2</string>
</dict>
この内容をSmartScrollKext-Info.plistのOSBundleLibrariesに設定する。
再度、ビルドし、生成されたSmartScrollDriver.kextを/tmpにコピーする。
$ sudo cp -R SmartScrollDriver.kext /tmp
以下のコマンドで、問題がないか確認する。
$ kextutil -n -t /tmp/SmartScrollDriver.kext
No kernel file specified; using running kernel for linking.
Notice: /tmp/SmartScrollDriver.kext has debug properties set.
/tmp/SmartScrollDriver.kext appears to be loadable (including linkage for on-disk
libraries).
ロードしてみる。
$ sudo kextutil -v /tmp/SmartScrollDriver.kext
Password:
Notice: /tmp/SmartScrollDriver.kext has debug properties set.
/tmp/SmartScrollDriver.kext appears to be loadable (not including linkage for on-disk
libraries).
Loading /tmp/SmartScrollDriver.kext.
/tmp/SmartScrollDriver.kext successfully loaded (or already loaded).
確認する。
$ kextstat | grep jp.co.bitz
162
0 0xb97000
0x4000
3>
0x3000
jp.co.bitz.driver.SmartScrollDriver (1) <4
アンロード。
$ sudo kextunload -v /tmp/SmartScrollDriver.kext
jp.co.bitz.driver.SmartScrollDriver unloaded and personalities removed.
次は、対象と鳴るUSB機器(SmartScroll)が抜き差しされたら、ドライバが反応する
事を確認してみる。
- 9. VendorIDが0x056A、ProductIDが0x0050、DeviceVersionNumberが0x0007な
ので、SmartScrollDriver-Info.plistのIOKitPersonalitiesのSmartScrollDriverに
bcdDeviceとidProduct、idVendorを追加して、7と80、1386を入力する。
この内容でビルドしてドライバーを前回の方法でロードする。
$ sudo cp -R SmartScrollDriver.kext /tmp
$ sudo kextutil -v /tmp/SmartScrollDriver.kext
Notice: /tmp/SmartScrollDriver.kext has debug properties set.
/tmp/SmartScrollDriver.kext appears to be loadable (not including linkage for on-disk
libraries).
Loading /tmp/SmartScrollDriver.kext.
/tmp/SmartScrollDriver.kext successfully loaded (or already loaded).
kernel.logをtailし、USB機器を差し込んで、抜く。
$ tail
Jul 1
Jul 1
Jul 1
Jul 1
Jul 1
Jul 1
Jul 1
-f /var/log/kernel.log
22:30:56 mbc2d kernel[0]:
22:30:56 mbc2d kernel[0]:
22:30:56 mbc2d kernel[0]:
22:30:56 mbc2d kernel[0]:
22:31:14 mbc2d kernel[0]:
22:31:14 mbc2d kernel[0]:
22:31:14 mbc2d kernel[0]:
[SmartScrollDriver]Initializing
[SmartScrollDriver]Probing
No interval found for . Using 8000000
[SmartScrollDriver]Starting
No interval found for . Using 8000000
[SmartScrollDriver]Stopping
[SmartScrollDriver]Freeing
アンロード。
$ sudo kextunload -v /tmp/SmartScrollDriver.kext
jp.co.bitz.driver.SmartScrollDriver unloaded and personalities removed.
抜き差しした際に、ログが出力されている事が分かるはずだ。