Driverについて
Click here to load reader
-
Upload
yukio-murakami -
Category
Technology
-
view
288 -
download
2
description
Transcript of Driverについて
Driverについて最近の状況の整理
2013.07.06Bitz Co., Ltd. 村上幸雄
1. はじめにApple開発者のサイトでDarwinのソースコードが公開されているが、ドライバ関連で
は、文書とサンプルコードも付属しているので、開発したいものに近いサンプルコードを基に拡張していう方法もあるが、今回は、Xcodeの新規プロジェクトから製作してみようと思う。
• Open Source - Releaseshttp://www.opensource.apple.com/• Mac OS X 10.7.5 - Sourcehttp://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を選択する。
プロジェクト名は、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は著者の会社のものにしている。
一度、プロジェクトをビルドする。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.kextNo 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
ロードする。
$ 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に自分の会社のものにしている。
SmartScrollDriver-Info.plistのIOKitPersonalitiesにSmartScrollDriver辞書型を追加して、以下の内容に設定する。
Name Value
CFBundleIdentifier com.MyCompany.driver.${PRODUCT_NAME:rfc1034identifier}
IOClass com_MyCompany_driver_SmartScrollDriver
IOKitDebug 65535
IOProviderClass IOResources
IOMatchCategory com_MyCompany_driver_SmartScrollDriver
IOClassは、このドライバの起点となるクラス名の様だ。ようするに、この名前のクラスを実装する事になる。IOProviderClassは、ドライバがぶら下がるnubクラス名。テンプレートのSmartScrollDriver.hとSmartScrollDriver.cppは空なので中身を実装
する。メソッドが呼ばれたらにデバッグ出力するだけだ。
#include <IOKit/IOService.h>class jp_co_bitz_driver_SmartScrollDriver : public IOService { OSDeclareDefaultStructors(jp_co_bitz_driver_SmartScrollDriver)public: virtual bool init(OSDictionary *dictionary = 0); virtual void free(void); virtual IOService *probe(IOService *provider, SInt32 *score); virtual bool start(IOService *provider); virtual void stop(IOService *provider);};
#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("Initializing\n"); return result;}
void jp_co_bitz_driver_SmartScrollDriver::free(void){ IOLog("Freeing\n"); super::free();}
IOService *jp_co_bitz_driver_SmartScrollDriver::probe(IOService *provider, SInt32 *score){ IOService *result = super::probe(provider, score); IOLog("Probing\n"); return result;}
bool jp_co_bitz_driver_SmartScrollDriver::start(IOService *provider){ bool result = super::start(provider); IOLog("Starting\n"); return result;}
void jp_co_bitz_driver_SmartScrollDriver::stop(IOService *provider){ IOLog("Stopping\n"); super::stop(provider);}
一度、プロジェクトをビルドする。Show the Log NavigatorからSmartScrollDriver.kextの出力先を調べて、ターミナル.appで、そのディレクトリに移動する。
$ cd Build/Products/Debug
そこで以下のコマンドを実行する。
$ 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.kextNo 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.kextPassword: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 0x3000 jp.co.bitz.driver.SmartScrollDriver (1) <4 3>
アンロード。
$ sudo kextunload -v /tmp/SmartScrollDriver.kextjp.co.bitz.driver.SmartScrollDriver unloaded and personalities removed.
次は、対象と鳴るUSB機器(SmartScroll)が抜き差しされたら、ドライバが反応する事を確認してみる。
DarwinのソースコードのIOUSBFamily-(バージョン番号).tar.gzのExamplesにあるVendorSpecific Driverのプロジェクトを開いて、Info.plistを確認する。
IOProviderClassをIOUSBDeviceにして、bcdDeviceとiDProduct、idVendorを対象機器の値にすれば、抜き差しに反応しそうだ!以前の開発環境に含まれていたUSB Proberを持っていたら、それを使って、
SmartScrollの情報を確認する。
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.kextNotice: /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 -f /var/log/kernel.logJul 1 22:30:56 mbc2d kernel[0]: [SmartScrollDriver]InitializingJul 1 22:30:56 mbc2d kernel[0]: [SmartScrollDriver]ProbingJul 1 22:30:56 mbc2d kernel[0]: No interval found for . Using 8000000Jul 1 22:30:56 mbc2d kernel[0]: [SmartScrollDriver]StartingJul 1 22:31:14 mbc2d kernel[0]: No interval found for . Using 8000000Jul 1 22:31:14 mbc2d kernel[0]: [SmartScrollDriver]StoppingJul 1 22:31:14 mbc2d kernel[0]: [SmartScrollDriver]Freeing
アンロード。
$ sudo kextunload -v /tmp/SmartScrollDriver.kextjp.co.bitz.driver.SmartScrollDriver unloaded and personalities removed.
抜き差しした際に、ログが出力されている事が分かるはずだ。