ハイライト
macOS Big Sur では、PCIDriverKit と SCSIControllerDriverKit が DriverKit に追加されます。 PCI および SCSI コントローラー ドライバーはユーザー空間でシステム拡張機能として書き換えることができ、対応する kext は別のシナリオで放棄されたパスに入ります。
主要内容
PCI または SCSI コントローラー ドライバーを作成するということは、通常、カーネルにアクセスすることを意味していました。 kext はマシン全体のリソースにアクセスできるため、バグによりカーネル パニックが発生する可能性があります。デバッグも時間がかかります。多くの場合、2 台のマシンが連携する必要があり、ドライバーがクラッシュした後に再起動する必要があります。
DriverKit は、この作業をユーザー空間に移動します。ドライバー拡張機能は、特定のハードウェアまたはカーネル インターフェイスに必要なアクセス許可を取得できますが、アクセス許可は資格によって制限され、リソースはシステムの残りの部分から分離されます。ドライバー プロセスがクラッシュしても、カーネルとその他のプロセスは実行を継続します。インストール方法も変更されました。 dext はアプリ バンドル内に残り、アプリは SystemExtensions フレームワークを通じて activateRequest を開始し、管理者の承認を待ちます。
このセッションでは、低レベルのハードウェアにおける DriverKit のカバレッジ ギャップに対処します。 macOS Catalina はすでに USB、シリアル、ネットワーク インターフェイス コントローラー、および HID をサポートしています。 Apple は macOS Big Sur に PCI および SCSI コントローラ ドライバのサポートを追加し、システム拡張機能が同じジョブを完了できる場合、PCI および SCSI コントローラの kext が放棄されたパスに入ることを明確にしました。
スピーチは 2 行に分かれています。最初の行は PCIDriverKit です。PCI デバイスを認証する方法、デバイスを開く方法、構成スペースにアクセスする方法、割り込みと DMA を処理する方法です。 2行目はSCSIControllerDriverKit: 使用方法です。IOUserSCSIParallelInterfaceControllerSCSI dext を書き込み、ユーザースペースによって駆動されるストレージ I/O を実際のワークロードでフルに実行します。
詳細
DriverKit のインストールと認証の境界
(02:28) ドライバー拡張機能をシステム ディレクトリにコピーしないでください。これはアプリ バンドルに残り、アプリは適切なライフサイクル ノードで activityRequest を作成します。一般的な方法は、アプリの起動時にアクティベーションを要求することですが、ユーザーが使用許諾契約に同意するか購入を完了するまで待つこともできます。
DriverKit distribution workflow:
1. Keep the driver extension inside the app bundle.
2. Use the SystemExtensions framework to create an activationRequest.
3. Ask the system to make the extension available.
4. Wait for administrator approval.
5. Sign the dext locally and include all required entitlements during development.
キーポイント:
- dext の配布エントリはシステム ディレクトリではなく App です。
- activateRequest は SystemExtensions フレームワークによって作成されます。
- 管理者の承認は、システム拡張機能のロードの一部です。
- 開発段階では、最初にローカル署名を実行できますが、ドライバーに必要な資格が含まれている必要があります。
(05:39) PCIDriverKit には PCI 資格も必要です。この資格は、Info.plist と同じ IOPCIFamily 一致基準を使用します。これは、ベンダー ID とデバイス ID に対して正確である可能性があります。マスクは、同じベンダーの複数のデバイスをサポートするために使用することもできます。
PCI entitlement shape:
- A list of PCI matching dictionaries.
- Matching criteria follow IOPCIFamily categories.
- A primary match compares primary vendor ID and device ID.
- A mask can remove the device ID part and match all devices from one vendor.
キーポイント:
- 資格は、このデクストがターゲット PCI デバイスにアクセスできるかどうかを決定します。
- デバイス一致ルールと IOPCIFamily は同じ基準セットを使用します。
- マスクを使用して照合範囲を広げると、認可範囲が大きくなり、製品ラインごとに制御する必要があります。
- PCI デバイスをカスタム Ethernet NIC などの他の DriverKit ファミリに接続する必要がある場合は、対応するファミリ資格も追加する必要があります。
PCIDriverKit のデバイス モデル
(07:15) PCIDriverKit の唯一のクラスは次のとおりです。IOPCIDevice。サブクラスには使用されません。ドライバーはそれを PCI プロバイダーとして扱い、それを通じて PCI リソースにアクセスします。 Apple はまた、Open、停止フェーズ中に呼び出されますClose。
PCI driver extension model:
1. Use IOPCIDevice as the PCI provider.
2. Call Open before accessing PCI resources.
3. Treat Open success as exclusive access to the PCI device.
4. Route shared access through one PCI resource manager when multiple clients exist.
5. Call Close in the driver stop routine.
キーポイント:
IOPCIDeviceこれはリソースの入り口であり、ビジネス主導の親クラスではありません。 -Open排他的アクセスを確立します。 PCI リソースは、デバイスを開かずに読み書きしないでください。- 複数のクライアントがリソースを共有する場合、ドライバーは独自にリソース管理層を設計する必要があります。
-
Close成功した場合、デバイスの状態が保存されていると見なすことはできません。 PCI スタックはバス マスタリングとメモリ空間を無効にします。
構成空間、memoryIndex、デバイス メモリ アクセス
(09:25) PCIDriverKit はデバイス マッピングを一律に引き継ぎます。メモリアクセスAPIの使用法memoryIndexそしてオフセット。 32ビットBARでは、memoryIndexBAR インデックスと同じ。 64 ビット BAR は 2 つの BAR を 1 つのメモリ エントリに結合します。memoryIndexメモリエントリにより0からカウントが開始されます。
Memory access model:
- 32-bit BAR2 -> memoryIndex 2.
- 64-bit BAR0 + BAR1 -> memoryIndex 0.
- 64-bit BAR2 + BAR3 -> memoryIndex 1.
- Access device memory by memoryIndex plus offset.
キーポイント:
memoryIndex必ずしも BAR インデックスではなく、メモリ エントリ番号を示します。- 64 ビット BAR はインデックス マッピング関係を変更します。
- 統合された入り口により、Apple は将来デバイス アクセスを最適化できるようになり、dtrace によるメモリ アクセスの観察も容易になります。
- 構成スペースの読み取りと書き込みは基本的に 1 対 1 の移行ですが、最初にセッションが開かれている必要もあります。
(11:02) バス マスタリングとメモリ空間が有効になっている場合、PCIDriverKit は各操作に対して明示的なカーネル API を提供しなくなります。ドライバーは、PCI コマンド レジスタを読み取り、バス マスターとメモリ イネーブル ビットを設定して、それをデバイスに書き戻す必要があります。
Start routine for a typical PCI driver:
1. Open a session with the PCI provider.
2. Read the PCI command register.
3. Set the bus master bit.
4. Set the memory space enable bit.
5. Write the command register back.
6. Perform memory reads or writes only after these bits are set.
キーポイント:
- コマンド レジスタは、デバイスのメモリ アクセスと I/O を可能にする重要なエントリ ポイントです。
- これらのオフセットと定義は、PCIDriverKit フレームワーク ヘッダーにあります。
- プロセスは、対応するビット マスクが削除されることを除いて、バス マスタリングを無効にする場合と同じです。
- 停止ルーチンで呼び出される
Close、ドライバーが PCI デバイスとのセッションを終了することを示します。
割り込みとDMAのユーザー空間処理
(12:06) 割り込みハンドラーは最初に.iigヘッダーファイルで宣言されます。次に、ドライバーは PCI デバイスの割り込みインデックスを列挙し、必要な割り込みタイプ (MSI など) を見つけて、割り込みソースを DispatchQueue に接続します。
Interrupt setup:
1. Declare InterruptOccurred in the .iig header.
2. Iterate through interrupt indexes for the PCI device.
3. Pick the index whose interruptType matches MSI.
4. Choose a DispatchQueue.
5. Create the dispatch source for that interrupt index.
6. Create the interrupt action.
7. Enable the source so the handler is called on interrupt.
キーポイント:
- 割り込みタイプは、ドライバーがどの割り込みインデックスにバインドされるべきかを決定します。
- デフォルトの DispatchQueue を使用することも、割り込み用に別のキューを作成することもできます。
- 割り込みアクションは、ディスパッチ元と処理関数を接続します。
- ハンドラーでは、MMIO を介してデバイス レジスタに書き込むことで割り込みをクリアできます。
(13:43) DMA 転送では、最初にバッファ メモリ記述子を作成し、次にバッファ メモリ記述子を作成する必要があります。IODMACommand。アップルははっきりとこう言っています。IODMACommandシステムが正しいメモリ マッパーを選択できるように、これが PCI デバイス用であることを指定します。
DMA transfer workflow:
1. Create a buffer memory descriptor.
2. Set the buffer length before writing into it.
3. Create the DMA specification for the hardware.
4. Create an IODMACommand for the PCI device.
5. Prepare the buffer memory descriptor with the DMA command.
6. Use physicalAddressSegment to get the address for the PCI device.
7. Call Complete on the DMA command after the transfer.
キーポイント:
- バッファメモリ記述子は、デバイスがアクセスするメモリを記述します。
-
IODMACommand間違ったメモリ マッパーにアクセスしないように、PCI デバイスにバインドします。 -physicalAddressSegment出力アドレスはハードウェアに書き込まれます。 - 転送完了後に呼び出されます
Complete、物理メモリを他のプロセスまたはデバイスで再利用できるようになります。
SCSIControllerDriverKit のクラスとキュー モデル
(16:18) SCSI デクストにはサブクラスが必要ですIOUserSCSIParallelInterfaceController。 Apple はカーネル クラスの近くに API 構造を保持しており、次のように追加しています。User接頭辞。 dext には、純粋な仮想としてマークされたオーバーライド関数が必要です。UserProcessParallelTask、UserDoesHBAPerformAutoSense、UserInitializeController。
SCSI dext skeleton:
1. Subclass IOUserSCSIParallelInterfaceController.
2. Override pure virtual functions.
3. Use UserProcessParallelTask to submit I/O requests to hardware.
4. Use UserDoesHBAPerformAutoSense to report auto-sense support.
5. Use UserInitializeController to initialize controller and dext data structures.
6. Add generic DriverKit, transport-specific, and SCSI controller entitlements.
キーポイント:
- 純粋な仮想関数は、フレームワークが dext を呼び出すためのエントリ ポイントです。
- 非純粋仮想関数は、SCSI ターゲットを作成するかターゲット プロパティを設定するために dext によって呼び出されます。
- SCSI コントローラー ファミリの資格は、フレームワークにアクセスするための前提条件です。
- SCSI コントローラー デバイスは通常 PCIe に基づいているため、PCIDriverKit と互換性があります。
(20:49) Apple は、SCSI デクストが 3 つの DispatchQueue (デフォルト キュー、割り込みキュー、補助キュー) を使用することを推奨しています。デフォルト キューはカーネルからの呼び出しを処理します。割り込みキューは、特に割り込みと I/O タイムアウトを処理します。補助キューは、SCSI ターゲットの作成に使用されます。
Recommended SCSI queues:
- Default Queue: UserInitializeController, UserProcessParallelTask, and other kernel-originated calls.
- Interrupt Queue: hardware interrupts and IOTimeoutHandlers.
- Auxiliary Queue: SCSI target creation.
キーポイント:
- DriverKit のディスパッチ キューはシリアルです。
- 割り込みと I/O を別のキューに入れて、互いの待機を減らします。
- ターゲットを作成すると、dext への複数のカーネル コールバックがトリガーされるため、デフォルト キューでブロックしないでください。
-
UserMapHBADataI/O パスでの前処理を避けるために、コントローラー固有の taskData を事前に作成することが適しています。
SCSI I/O パス、電源、終端
(23:44) SCSIControllerDriverKit は、I/O パスの責任分担を変更します。カーネル呼び出しUserProcessParallelTaskI/O を送信して配置するSCSIUserParallelTaskコピーは dex に送信されます。カーネルは準備を担当しますIODMACommand物理セグメントを生成する場合、dext はパフォーマンス パス上のカーネルに対してこれらの IPC を開始する必要はありません。
SCSI I/O path:
1. Kernel calls UserProcessParallelTask.
2. Dext receives a SCSIUserParallelTask copy.
3. Kernel has already prepared IODMACommand and physical segments.
4. Dext uses fBufferIOVMAddr as the start physical address.
5. Dext posts the request to hardware.
6. Interrupt handler processes completion.
7. Dext calls ParallelTaskCompletion with SCSIUserParallelResponse.
キーポイント:
- デクストが取得できない
SCSIParallelTaskオブジェクト、あなたが得るものはSCSIUserParallelTask。 fBufferIOVMAddrカーネルが生成する連続した物理セグメントの開始アドレスです。- ハードウェアが複数のセグメントを必要とする場合、dext は独自に ScatterGatherList を準備できます。
-
ParallelTaskCompletionI/O 完了コールバックであり、応答にはステータス、転送されたバイト数、およびセンス データが含まれます。
(28:15) オーバーライドによる電源管理SetPowerState仕上げる。 DriverKit は、オフ、オン、低電力の 3 つの電源状態をサポートします。 PCIe デバイスは主にオフとオンを処理します。オフはスリープまたは PCI 一時停止に対応し、オンはシステム ウェイクに対応します。
SCSI dext lifecycle:
1. Override SetPowerState for hardware-specific power transitions.
2. Use delayed acknowledgement when hardware reset or rescan needs time.
3. Override Stop for termination.
4. Close outstanding PCI session in Stop.
5. Cancel dispatch queues and sources.
6. Let the kernel handle outstanding I/O requests during termination.
キーポイント:
SetPowerState最初に戻って、ハードウェアが復元された後にスーパー ディスパッチを通じて確認応答を完了することができます。- この例では、移行時にハード リセットが開始され、SCSI ターゲットの再スキャンがトリガーされます。
-
StopPCI セッションを閉じ、キューとソースをキャンセルします。 - Dext は未処理の I/O を完了する責任を負いません。この部分は終了時にカーネルによって処理されます。
パフォーマンスの境界
(31:55) Apple は、4Gbps ファイバー チャネル ホスト バス アダプターを使用して、RAID ディスク アレイを Thunderbolt 3 経由で MacBook Pro に接続します。デモでは、Final Cut Pro がこの外部 SCSI ディスクから Apple ProRes ビデオを再生し、フレーム落ちの警告。
Demo setup:
- 4 Gbps Fibre Channel host bus adapter.
- RAID disk array.
- Thunderbolt 3 connection to a MacBook Pro.
- ExampleSCSIDext running as a user-space DriverKit extension.
- Final Cut Pro library stored on the external SCSI disk.
- ProRes playback at around 350 MB/s disk throughput.
キーポイント:
- デモの目的は、ユーザー空間のデクストがプロのワークロードに耐えられるかどうかを検証することです。
- この SCSI デバイスは、PCIe ベースのコントローラーを通じて動作します。
- セッションのパフォーマンス デモンストレーションは、抽象的な約束ではなく、具体的なデモに依存します。
- Apple は、カーネルの前処理 DMA と I/O パス IPC の削減におけるパフォーマンス パスの最適化に重点を置いています。
重要ポイント
1. PCIe デバイス用の DriverKit 移行テンプレートを作成する
何をすべきか: 既存の PCIe キーを選択し、デバイスと一致させ、Open / Close、コマンド レジスタ、およびメモリ アクセスは、まず PCIDriverKit に移動されます。
実行する価値がある理由: セッションでは、PCI kext がシステム拡張機能で置き換えられる場合には廃止されたパスに入ることが明確に述べられています。早期の移行により、資格、BAR マッピング、および DMA の違いを事前に検出できます。
開始方法: まずベンダー ID とデバイス ID を整理し、PCI 一致辞書を書き出してから、開始ルーチンをオープンするように変更します。IOPCIDevice、バスマスタリングとメモリスペースを有効にし、パスしますmemoryIndexMMIOにアクセスしてください。
2. SCSI コントローラの dex プロトタイプを作成します
やるべきこと: を使用するIOUserSCSIParallelInterfaceController最小限の SCSI デクストを構築し、初期化、I/O 送信、割り込み完了、停止まで実行します。
実行する価値がある理由: SCSIControllerDriverKit は過去のものを置き換える責任がありますIOSCSIParallelInterfaceControllerkext ルート。ファイバー チャネル、RAID コントローラー、シリアル アタッチド SCSI などのデバイスに適しています。
開始方法: まず純粋な仮想関数をオーバーライドし、デフォルト、割り込み、補助の 3 つのキューを作成します。UserProcessParallelTask読み込むSCSIUserParallelTask、ハードウェアが完了した後に呼び出されますParallelTaskCompletion。
3.ドライバーのインストールおよび回復コンソールを作成します
何をすべきか: dex をアプリにパッケージ化し、アクティベーション ステータス、管理者の承認ステータス、エラー ログ、および再アクティベーション ポータルを提供します。
実行する価値がある理由: DriverKit のインストール アクションは、システム ディレクトリをアプリにコピーしてアクティベーションリクエストを開始することから変わります。ユーザーと管理者は、拡張機能が利用可能かどうかを知る必要があります。
開始方法: SystemExtensions フレームワークを使用して、アプリの起動時に activityRequest を作成し、それぞれの承認、失敗、再試行を記録します。ドライバーがクラッシュすると、ユーザーはデバイスを再接続するか、拡張機能を再アクティブ化するように求められます。
4. DMA および割り込み診断ツールを作成する
やるべきこと: 開発部門に文書を作成するmemoryIndex、割り込みタイプ、DMA 準備/完了のタイミング、完了ステータス。
実行する価値がある理由: PCIDriverKit は、統合 API の下でデバイス メモリ アクセスを受け取ります。 Apple はまた、これが dtrace を使用してマルチスレッド環境での PCI 問題を観察するのに役立つとも述べました。
開始方法: まず、割り込みを独立した DispatchQueue に入れ、次に各 DMA 転送のバッファ長、physicalAddressSegment、および完了時間を記録し、ハードウェア ログと合わせます。
5. Kext の代替可能性チェックリストを作成する
何をすべきか: チームの既存のカーネル拡張機能の表を作成し、それらが DriverKit がすでにサポートしている USB、シリアル、ネットワーク インターフェイス コントローラー、HID、PCI、または SCSI コントローラー ファミリに属しているかどうかを示します。
実行する価値がある理由: Apple は、DriverKit のサポート範囲を kext の非推奨までに制限しています。サポートされているファミリーに属するドライバーは、移行計画で優先される必要があります。
開始方法: デバイス ファミリごとにグループ化し、資格、プロバイダー クラス、I/O パス、インストール方法を 1 つずつ確認し、移行リスクとしてまだカーネルのみの動作に依存している点をリストします。
関連セッション
- Endpoint Security アプリを構築する — macOS System Extension に関しても、もともとカーネルに依存していたセキュリティ機能がユーザー空間に移動されます。
- DriverKit を使用してオーディオ ドライバーを作成する — アプリのパッケージ化や Core Audio HAL インタラクションなど、オーディオ ドライバーへの DriverKit の実装について引き続き説明します。
- DriverKit を使用してドライバーを iPad に持ち込む — DriverKit の iPad への拡張と、既存の Mac DriverKit ドライバーのマルチプラットフォーム移行について説明します。
- Core Media IO を使用してカメラ拡張機能を作成する - カメラ システム拡張機能を紹介します。これは、さまざまなハードウェア拡張機能がレガシー プラグインからユーザー空間にどのように移行されるかを比較するのに適しています。
コメント
GitHub Issues · utterances