SSブログ

KEXT、DriverKit、USBDriverKit、IOUSBHost [プログラミング]

Raspberry Pi Picoを手に入れてA/Dコンバータを接続するためだけに使っているPi Zero Wとかを置き換えたい、と思った。ところがmacOS側でVender specificなclassのUSBデバイスを接続するやりかたがよくわからない。Pi Pico側はドキュメントやサンプルコードがすでに揃ってるのに。昔なら使い方は超難しいI/O Kitを呼べばユーザ空間からアクセスできた。今でもI/O Kitは有効らしいけど、どうもプログラマからは隠蔽される方向になってるように思える。またいつ突然使えなくなるとも限らない。Appleにはそうやっていままで何度も煮湯を飲まされた。

なかなかまとまったドキュメントがなくて困ってるんだけどなんとなく雰囲気はわかってきた....

どうやらDriverKitというのはKEXTを廃止するのに従って、KEXTの代わりとなるSystem ExtensionのためのSDKらしい。KEXTはkernel空間で動作するけどSystem extensionはユーザ空間にある。しかしDriverKitの総括的なドキュメントはなくてレファレンスとほんとのoverviewみたいなのだけのようである。2019年のWWDCにSystem Extensions and DriverKitと言うセッションのビデオが残っている。最近のは日本語字幕がつくようになったんだけど、どうもわかりにくい。聞き取れればいいんだけどすっと理解する、というところまで英語力がない。英語の字幕とかわりばんこに見ることになってしまう。

でもこれを見て位置付けはわかった。要するにKEXTはkernel空間で動作するので危ないしプログラミングもめんどくさいのでやめて、System Extensionというユーザ空間で動作するドライバにしたい、ということで、System extensionで使えるI/O Kitコールの代わりにDriverKitを使え、ということらしい。

I/O KitはKernelの中で動作するオブジェクトをMach portを経由してユーザ空間からも使えるようにしたものだけど、Kernel動作がほとんど丸見えになっている。I/O KitはよくできているしOS Xの最初から実装されていて枯れているので、これは使い続けたい、しかしI/O Kitはセキュリティ的に微妙なコールもあるので少なくともサードパーティには使わせないようにする方向にしたい、ということのようである。ビデオではそんなこと言ってないけど本音はそこだよな。 KEXTはkernel空間で動作するようになっていて、これそのものが危ないのでユーザ空間に追い出そう、というのがSystem extensionで、Apple自身のKEXTは山ほどあるくせにそれには目をつむってサードーパーティのKEXTをまず潔く廃止という強権発動に出たということのようである。

ネットワークやファイルシステムのコールもいずれはSystem extenstionになるとすると、それってもとのMach kernelの思想に戻るということだな。OS Xがモノリシックになったのは1回のユーザ空間でのシステムコールに都合4回コンテクストスイッチが入るのでオーバーヘッドがデカすぎる、ということだったと思うんだけど、ハードウェアが速くなったので問題にならなくなったということだな。M1ってコンテクストスイッチを軽くする工夫とかあるんだっけ。キャッシュもでかいし命令ディスパッチ用のバッファもすごく深かったような気がするんだけど。

I/O Kit自身も書き換えられているようである。KernelのIOWorkLoopというオブジェクトは昔はFoundationのNSRunLoopみたいな構造だったのをGCDと同じようなものにしたようである。つまりkernel内でマルチスレッドに書かれているらしい。これもGCDみたいなオーバヘッドの大きなものをkernel内で動かしても気にならなくなった、ということだろう。

DriverKitのレファレンスをパラパラ見ると、IOなんとかというオブジェクトがたくさんある。これの多くはI/O Kitのオブジェクトで、実際にはkernelオブジェクトにMac portで繋がったプロキシのようなものだとすれば、そういう思想はI/O Kitから変化していないらしい。

DriverKitを使ったSystem extensionはdextという拡張子を持って、bundleのかっこうになっているけど、単独でインストールはできなくて、アプリケーションバンドルのなかのサブバンドルとしてインストールされないといけない。dextは専用のentitlementがあってそれに従って動作を制限するけど、そのチェックをすり抜けないようにするためだろう。結構厳しい。

DriverKitの中にはもうすこし特殊化したNetworkingDriverKitや、USBDriverKitなんかがある。Vendor specificなclassのUSBデバイスにはこのUSBDriverKitを使え、ということのようである。

ただし、vendor specificなUSBデバイスはどうせ汎用のドライバは必要なくて、ひとつのアプリケーションだけが使えればいい、Sytstem extensionにしなくてもいいんじゃないか、ということでIOUSBHostがあるみたいである。これはSystem extension用ではなく、アプリケーションのスレッドから直接呼べるようで、dext用のentitlementも必要ないらしい。また、USBDriverKitのオブジェクトはI/O KitのオブジェクトになっていてすなわちそれはサブセットC++のオブジェクトだけど、IOUSBHostのオブジェクトはObjective-CのNSObjectのサブクラスになっていてUSBDriverKitのオブジェクトをラップしているようである。

ただし、IOUSBHostのドキュメントはさらに寂しくてこのレファレンスだけしかみあたらない。サンプルコードもない。USBデバイスのenumerationさえどうすればいいのかわからない。しんどいなあ。IOUSBHostを使うためにはUSBDriverKitを理解しないといけないようである。USBDriverKitもDriverKit本体を知らないと結局わからないし、DriverKitのドキュメントはSystem extension向けに書いてあってKEXTのプログラミングを知ってる人が前提みたいな書き方になってる。

さらにもっとダメなことに、IOUSBHostのレファレンスにはObjective-CのメソッドしかなくてSwiftからどう呼ぶのかわからない。Bridging headerを自分で作ればいいのか、でもそれなら初めから入れておけばいいわけで、なんでないかというとSwiftから呼ぶにはObjective-Cのラッパを書かないといけないのか、このへんすごくダメダメである。KEXTをやめたいというのだけが先走ってるのか、Appleがいったいどうしたいのかわからない。

NSHipsterというサイトがあってここを僕はよくわからないんだけどApple用のプログラミングの本なんかを出してるとこで、ここの関連と思われるサイトnooverviewavailableというのがあって、ここにAppleのドキュメント整備の進捗を%表示してる。残念ながらWWDC2019直後の2019年7月時点しかないけど、そこにはIOUSBHostの進捗は0%になってる。WWDC2019でセッションをあげたくせにドキュメントが無しとはいい度胸してるぜ。

それなら、いっそI/O Kitでええわ、と思ってしまうけど、どう考えてもI/O KitのAPIはいずれ塞がれてDriverKitだけになるのは目に見えている。困った。でもStstem extensionにするか、IOUSBHostにするかって結構問題だよな。IOUSBHostは結局今時点でもAppleのレファレンスとObjective-CヘッダのDoxygenしか頼るものがない。

アナウンスされながらドキュメントが整備されずにいつの間にかなかったことになったFrameworkってあった(はっきり言おう、Accelerate/vecLib/LinearAlgebra。ドキュメントアーカイブからも消えてる。XcodeのSDKに残骸が残ってることが探せばわかる。他にもあったぞ、もう忘れたけど)し、IOUSBHostはまたその伝だったら困るしなぁ。めちゃイマイチだよなぁ。
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。