Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

USB3 host driver program structure

960 visualizaciones

Publicado el

This presentation describes USB 3 host driver structure.
The host driver has 3 layers: host controller driver, bus driver, and class driver.
Recent days, hobby OS creators must implement USB host driver to support keyboard and mouse.

Publicado en: Software
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

USB3 host driver program structure

  1. 1. USB3ホストドライバのクラス構成 2018/11/10 Kernel/VM 北陸 4 @uchan_nos
  2. 2. 自己紹介 ● @uchan_nos ● 仕事1:サイボウズ SRE チーム ● 仕事2:東京工業大学 特任助教 ● 趣味:osdev-jp コアメンバー ←執筆 校正→
  3. 3. モチベーション ● 最近のPCはレガシーサポートがない → PS/2エミュレーション機能がない → 自作OSでキーボードが扱えない! ● ということで… ● 自作OSでUSBデバイスを使いたい ● 移植は大変だし,勉強を兼ねて自作してみよう ● C++大好きだからC++っぽい書き方をしてみよう
  4. 4. 参考資料 ● カーネル/VM探検隊@関西 8回目 – 3:05 – 3:25 @liva_jy xHCI(USB3.0 HC)デバドラを自作してみよう – https://www.youtube.com/watch?v=dKUSUv2cxhg ● 『USB3.0ホストドライバ自作入門』 – https://uchan.booth.pm/items/1056355 ● 『eXtensible Host Controller Interface for Universal Serial Bus』 ● 『Universal Serial Bus 3.1 Specification』 ● 『Device Class Definition for Human Interface Devices (HID)』
  5. 5. デバイス制御までの道のり xHCの初期化 デバイス検出 デバイス初期化 クラスドライバ xHCリセット,Command Ring設定, Primary Event Ring設定 ポートへの挿入検知,ポートリセット スロット割り当て, DEVICE&CONFIGディスクリプタ取得 エンドポイント有効化, クラス特有の処理の開始
  6. 6. デバイス制御までの道のり xHCの初期化 デバイス検出 デバイス初期化 クラスドライバ xHCリセット,Command Ring設定, Primary Event Ring設定 ポートへの挿入検知,ポートリセット スロット割り当て, DEVICE&CONFIGディスクリプタ取得 エンドポイント有効化, クラス特有の処理の開始 今日のスコープ
  7. 7. USBホストドライバの構成 ホストコントローラドライバ ホストコントローラ(xHC) USBバスドライバ クラスドライバ 特定のUSBクラス のための処理 USB規格に従ったAPI を上位層に提供 ホストコントローラの 詳細を隠蔽 xHCI規格に準拠した ハードウェア実装 USBホストドライバ
  8. 8. USBホストドライバの構成 ホストコントローラドライバ ホストコントローラ(xHC) USBバスドライバ クラスドライバ 特定のUSBクラス のための処理 USB規格に従ったAPI を上位層に提供 ホストコントローラの 詳細を隠蔽 xHCI規格に準拠した ハードウェア実装
  9. 9. USBバスドライバ ● 例えばGET_DESCRIPTOR ● USBデバイスの種類や機能を判別するために デバイス自身が持っているディスクリプタを取得 ● DEVICE:デバイス全体の情報 – USBバージョン,EP0の最大パケット長, CONFIGURATIONの数,など ● CONFIGURATION:特定の機能構成 – インターフェース数,最大消費電力,など USB規格に従ったAPIを上位層に提供
  10. 10. USB規格で規定されたAPI例 ● コントロール転送 – GET_DESCRIPTOR(D2H) ● DEVICE, CONFIGURATIONディスクリプタ等 – SET_CONFIGURATION(H2D) ● コンフィグレーションの選択 – GET_REPORT(D2H) ● HIDデバイスからのデータ入力 ● インタラプト転送,バルク転送,アイソクロナス転送
  11. 11. USBホストドライバの構成 ホストコントローラドライバ ホストコントローラ(xHC) USBバスドライバ クラスドライバ 特定のUSBクラス のための処理 USB規格に従ったAPI を上位層に提供 ホストコントローラの 詳細を隠蔽 xHCI規格に準拠した ハードウェア実装
  12. 12. ホストコントローラドライバ ● レジスタ構成,データ構造の詳 細などを隠蔽したい ホストコントローラの詳細を隠蔽 DCBAAP DCBA0 DCBA1 DCBAn … Slot Ctx EP0 Ctx EP1 OUT Ctx EP15 IN Ctx Transfer Ring xHCのレジスタ メモリ上のデータ構造
  13. 13. バスドライバとxHCドライバの境界 ● 例えばコントロール転送は3ステージからなる ● 具体的なデータフォーマットはUSB規格のスコープ ● xHCI規格は3つのステージからなることだけを規定 Setup Stage Data Stage Setup Stage USBバスドライバ ホストコントローラドライバ 具体的なデータ形式,各ビットの意味 データ転送のハコ
  14. 14. USBホストドライバの構成 ホストコントローラドライバ ホストコントローラ(xHC) USBバスドライバ クラスドライバ 特定のUSBクラス のための処理 USB規格に従ったAPI を上位層に提供 ホストコントローラの 詳細を隠蔽 xHCI規格に準拠した ハードウェア実装
  15. 15. クラスドライバ ● HIDクラス(クラス番号3)は2つの必須パイプと 1つのオプショナルなパイプを規定 特定のUSBクラスのための処理 Control パイプ Interrupt In パイプ Interrupt Out パイプ 必須 オプショナル 必須 HID Human Interface Device
  16. 16. HIDキーボードからの受信 初期状態取得 Interrupt In 発行 Interrupt In 完了 キーの押下状態を取得する キーの状態変化を検知するために, Interrupt In を発行しておく キーの状態が変化すると Interrup In が完了してイベントが発行される (通常は割り込みとして検知する) キー push / release
  17. 17. クラスドライバとバスドライバの境界 ● バスドライバ – コントロール転送,インタラプト転送などの 仕組み(USB規格のAPI)を提供 – デバイスを識別し,適切なクラスドライバを 生成,割り当てるのはバスドライバの役目 ● クラスドライバ – バスドライバが提供するAPIを使って, – クラスが規定するタイミングに従い, – デバイスと具体的なデータ通信を主導する
  18. 18. クラス図
  19. 19. クラス図
  20. 20. クラス図(USBバス& xHCドライバ) バスドライバ ホストコントローラドライバ
  21. 21. クラス図
  22. 22. クラス図(クラスドライバ)
  23. 23. シーケンス(前半)
  24. 24. シーケンス(後半)
  25. 25. まとめ ● 今の時代,自作OSでもUSBドライバが必須 ● USBホスト側のドライバは3層で組むと良さげ – クラスドライバ – バスドライバ – ホストコントローラドライバ ● HIDキーボードの受信方法を紹介 ● 実際のクラス間相互作用を紹介 ● ソースコードはそのうち公開したい…
  26. 26. usb::Device - buf_: uint8_t[256] + ControlIn(int, SetupData, void*, int) + ControlOut(int, SetupData, const void*, int) + InterruptIn(int, void*, int) + InterruptOut(int, const void*, int) + StartInitialize() + IsInitialized(): bool + OnEndpointsConfigured() # OnControlInCompleted(SetupData, const void*, int) # OnControlOutCompleted(SetupData, const void*, int) # OnInterruptInCompleted(const void*, int) # OnInterruptOutCompleted(const void*, int) - InitializePhase1 - InitializePhase2 - InitializePhase3 usb::xhci::Device - slot_id_: uint8_t + ControlIn(int, SetupData, void*, int) + ControlOut(int, SetupData, const void*, int) + InterruptIn(int, void*, int) + InterruptOut(int, const void*, int) + AllocTransferRing(DeviceContextIndex, size_t) + OnTransferEventReceived(const TransferEventTRB&) usb::ClassDriver + SetEndpoint(const EndpointConfig&) + OnEndpointsConfigured() + OnControlInCompleted(SetupData, const void*, int) + OnControlOutCompleted(SetupData, const void*, int) + OnInterruptInCompleted(const void*, int) + OnInterruptOutCompleted(const void*, int) 16 dev_ usb::HIDKeyboardDriver - ep_interrupt_in_: int + SetEndpoint(const EndpointConfig&) + OnEndpointsConfigured() + OnControlInCompleted(SetupData, const void*, int) + OnControlOutCompleted(SetupData, const void*, int) + OnInterruptInCompleted(const void*, int) + OnInterruptOutCompleted(const void*, int) + SubscribeKeyPush(std::function<void (uint8_t)>) usb::xhci::Ring - buf_: TRB* - cycle_bit_: bool - write_index_: size_t + Initialize(size_t) + Push(const TRB&): TRB* 31 transfer_rings_ class_drivers_
  27. 27. main usb::Device InitializePhase1 StartInitialize usb::xhci::Device OnTransferEventReceived ControlIn[GET_DESC, DEVICE] return return xHC Wait<br>CommandCompletionEvent Push[Setup, Data, Status] OnControlInCompleted ControlIn[GET_DESC, CONFIG] return Push[Setup, Data, Status] return return InitializePhase2 OnTransferEventReceived OnControlInCompleted ControlOut[SET_CONFIG] return Push[Setup, Status] return return DEVICEディスクリプタの処理 CONFIGディスクリプタの処理 InitializePhase3 OnTransferEventReceived OnControlOutCompleted SetEndpoint return return return SET_CONFIG<br>完了後の処理 usb::<br>HIDKeyboardDriver <span>new HIDKeyboardDriver</span> IsInitialized true AllocTransferRing Push[ConfigureEndpointCommand] return OnEndpointsConfigured return OnEndpointsConfigured return ControlIn[GET_REPORT, Input Report] Push[Setup, Data, Stage] OnTransferEventReceived OnControlInCompleted OnControlInCompleted InterruptIn Push[Normal] NotifyKeyPush OnTransferEventReceived OnInterruptInCompleted OnInterruptInCompleted Key Pushed キー入力の初期状態取得 エンドポイント有効化

×