3 ポイント 投稿者 GN⁺ 2025-08-08 | 1件のコメント | WhatsAppで共有
  • 本記事は、Linuxカーネル向けにRustで開発された最新のGPUドライバーTyr の開発過程とGPUドライバーの動作原理に焦点を当てる
  • GPUドライバー開発において、UMD(ユーザーモードドライバー)KMD(カーネルモードドライバー) の役割分担と相互作用を VkCube の例を通じて説明する
  • UMD は高レベルAPIをGPUが理解できる低レベル命令に変換し、KMD はメモリ割り当て、ジョブスケジューリング、デバイス初期化などの中核的な役割を担う
  • Tyrドライバーが提供する API はPanthorと同一で、デバイスクエリ、メモリ管理、グループ管理、ジョブ提出、Tilerヒープ管理などで構成される
  • 次回の記事では Arm CSFハードウェアアーキテクチャ と主要コンポーネント(例: MCU)およびブート手順について扱う予定である

紹介: Rustベースの最新GPUカーネルドライバー開発

  • 本記事はLinuxカーネルでArm Mali CSFベースのGPUをサポートする、最先端のRust GPUドライバーTyr 開発シリーズの第2回目である
  • 実例として、Vulkan API を使って回転するキューブをレンダリングするシンプルな3Dプログラム、VkCube を選び、GPUドライバーの内部動作方式を説明する
  • VkCubeのシンプルな構成は、GPUドライバーの動作原理を学ぶのに適したケースである

GPUドライバー基礎: UMDとKMDの役割と構造

  • User Mode Driver(UMD)Kernel Mode Driver(KMD) で構成される
    • UMD: panvk(MesaのVulkanドライバー等)のように、一般アプリのAPI(Vulkan、OpenGLなど)を実装する
    • KMD: Tyr など、ハードウェアに対する特権を持つカーネルレベルドライバーとしてLinuxカーネルの一部として動作する
  • カーネルモードGPUドライバーは、UMDと実際のGPUをつなぐ役割を果たし、UMDはAPIコマンドを解釈してGPUが理解できる命令セットに変換する
  • UMDは、シーン構築に必要なジオメトリ、テクスチャ、シェーダーなどのデータを準備し、実行前にKMDへGPUメモリへの割り当てを要求する
  • シェーダー はGPU上で動作する独立したプログラムであり、VkCubeではキューブの配置、カラー付け、回転実装などを担当する。シェーダー実行には外部データ(ジオメトリ、カラー、回転行列など)が必要である
  • UMDは準備したコマンド(例: VkCommandBuffers)をKMDに渡して実行させ、作業が完了すると通知を受け取り結果をメモリに保存できる

KMD(カーネルモードドライバー)の主な責務

  • GPUメモリの割り当てとマッピング(アプリケーションごとの分離を提供)
  • ハードウェアキューへのジョブ提出と、完了タイミングのユーザー通知
  • 非同期・並列なハードウェア環境ではジョブ依存関係の管理が必須で、正しい結果を保証するためにKMDがスケジューリングと依存関係検証の役割を担う
  • デバイス初期化、クロック/電圧レギュレーター制御、スタートアップコード実行、複数クライアントが公平にハードウェアを共有できるようアクセス回転を管理することなども含まれる

複雑性の所在: UMDとKMDの分業

  • GPUドライバーの複雑性は主にUMDに集中している
    • UMD: 高レベルAPIコマンドをハードウェア命令へ変換
    • KMD: UMDが正しく動作できるようメモリ分離、共有、公平なアクセス性などの中核機能を提供

Tyrが提供するドライバーインターフェース(API)構造

  • TyrドライバーAPI(=Panthorと同一)は、主に5つのグループに分類できる
    1. デバイス情報クエリ: DEV_QUERY(IOCTLでGPUハードウェア情報を確認、ROM領域を使用)
    2. メモリ割り当てと分離: VM_CREATE、VM_BIND、VM_DESTROY、VM_GET_STATE、BO_CREATE、BO_MMAP_OFFSET など
    3. スケジューリンググループ管理: GROUP_CREATE、GROUP_DESTROY、GROUP_GET_STATE(詳細説明は今後の記事で予定)
    4. ジョブ提出: GROUP_SUBMIT(デバイスコマンドバッファを通じてGPUへの実行要求)
    5. Tilerヒープ管理: TILER_HEAP_CREATE、TILER_HEAP_DESTROY(タイルドレンダリングGPUのメモリ要件を満たす)
  • これらのAPIは実際に直接描画する作業からは距離があるが、UMDが実コマンド実行を担い、KMDはハードウェアアクセスのために上記インターフェースのみを提供する

結論と今後の計画

  • 今回の記事では、GPUドライバーの全体構造と内部フロー、そしてTyrが提供する主要APIについて確認した
  • この内容を踏まえ、シリーズの次回記事では Arm CSFハードウェアアーキテクチャ、**マイクロコントローラーユニット(MCU)**などの主要コンポーネントとドライバー初期化手順を扱う予定である

1件のコメント

 
GN⁺ 2025-08-08
Hacker News コメント
  • 非常に良い記事でした。ただ、内容が短すぎます。面白くなり始めたところで終わった感じがして、次回が楽しみです。
    • 次回も来週は続編になる予定で、GPUで待機していたコマンドがキューから取り出されて実行されるところを見ることになるでしょう。この記事で扱う抽象化レベルは、ユーザー/カーネル境界でデータを渡す部分で、主にキューとバッファ管理だけなので、実際の演算自体は多くありません。実際に重要なのは、キューに入れられたコマンドが実行されるときに起こることです。GPUからは逆方向に別のコマンド完了シグナルが返されますが、それも気になります。こうした非同期処理の多くはドライバ側ではなくユーザー側コードで扱われ、ドライバは完了シグナルを渡すだけです。
  • RK3588デバイスの1台をデスクトップ用途で使っていますが、panfrostを利用しているところ、時々Firefoxで画面が真っ黒になったり透明な領域ができたりするバグがあります。妙な現象です。
    • RK3588では実際はpanfrostではなく、この投稿で扱われているpanthorドライバが使われています。
  • uring_cmdをioctlの代わりに使う案は検討されていましたか?このプロジェクトはゼロから作る構成なので適用できそうにも見えたので、ほとんど利点がないと見なされた理由が気になります。
    • GPUはすでに独自の非同期コマンドキューを持っているため、ioctlは本来そのコマンドキューへ書き込むための比較的安価な手段です。ですからCPU側にもう一つ非同期キューを作ってその書き込みをスケジュールするのは、使い道が限定的な選択です。もしGPUコマンドキュー自体をuringとしてuserspaceへマッピングする提案であれば、io_uring API仕様を正しくサポートするためにはファームウェアをかなり大幅に変更する必要があり、ハードウェア特性上、そもそも不可能な可能性もあります。
    • 記事で説明されているドライバは、userspaceのMesaライブラリが要求するAPIをそのまま踏襲しています。
  • 非常に興味深く読みました。続編があるか、あるいは論理的に続く内容があるか気になっていました。
    • 本日は初公開の記事なので、今後アップデートが出るのを期待しています。
  • 「Rust GPU driver」というタイトルはクリックを増やしやすいのは分かりますが、実際はArm Mali CSFベースのGPUドライバではないのでしょうか?個人的には、ツール開発のためのメタツールに注目が向けられるのはあまり好みではなく、実際の目的がRustで何かを作ることに聞こえます。記事では「arm maliベースのgpuドライバカーネル」と明示されているのに、わざわざarm maliドライバとは呼んでいません。ドライバを作るということは、OS APIとハードウェアメーカーのAPIを接続するだけの作業で、上位に抽象化レイヤーを追加して構築するフレームワークを作ることではないと考えます。言い方が少し率直すぎた点はご容赦ください。
    • 今回の事例がLinuxで初めて行われたRustベースのGPUドライバの一つであるという点で、Rustが重要なキーワードになっています。
    • 率直な言い方だったことを気にしないでください。あなたの言い方を見る限り、現代のGPUドライバが何であるかをまったく知らないようです。15年前までは使っていましたが、その間にさらに複雑になっていることは承知しています。Linuxカーネルのソースコードを見ても、GPUドライバはコード行数として最大の比重を占める領域です。ほぼすべてのドライバが複数のGPUカードをサポートしています。毎回各GPUカードごとに完全に独立したドライバを別々に作るのが非合理的だという事実を知っているのか疑問です。GPUドライバ作業は、単に2つのAPIを“線でつなぐ”だけの仕事ではありません。実際は想像以上に異なります。反論するなら、あなたが書いたGPUドライバを見せてください。実際に線をいくつかつないで終わったのか確認したいです。
      • Rustが重要な理由は、これがRustインフラをGPUドライバに使った初めて(または初めての1つ)のケースだからです。