昨日、TrueOS(FreeBSDバリアント)の新しいインスタンスをインストールし、USBキーボードを接続しました(LogitechG510)。インストール環境、初回起動時、および新しいインスタンスが再起動するまでは正常に機能しました。この時点で、BSDの起動時モジュールのロードフェーズで認識されたときから、スクロールロックが機能しなくなったため、入力の送信が完全に停止したようです。ただし、LCD画面とバックライトがオンになっていて、別のキーボードを接続すると、ステータスの変化(Caps/NumLockなど)が追跡され、Windows/Linuxとラップトップで正常に機能します。 。
BIOSでレガシーUSBとハンドオフのオン/オフを切り替えたり、さまざまなポートを使用したりするさまざまな組み合わせを試しましたが、まったく役に立ちませんでした。別のUSBキーボード(以下のログの「ベンダー0x1241 USBキーボード」)はどちらの方法でも正常に機能します。 USBマウスは常に機能しています。 PS/2ポートはありません。
ここで何が起こっているのか、そしてそれを修正する方法はありますか?ありがとう!
% dmesg | grep kb
kbd1 at kbdmux0
atkbdc0: <Keyboard controller (i8042)> at port 0x60,0x64 on isa0
atkbd0: <AT Keyboard> irq 1 on atkbdc0
kbd0 at atkbd0
atkbd0: [GIANT-LOCKED]
ukbd0 on uhub5
ukbd0: <vendor 0x1241 USB Keyboard, class 0/0, rev 1.10/2.80, addr 2> on usbus6
kbd2 at ukbd0
ukbd1 on uhub0
ukbd1: <Logitech G510 Gaming Keyboard, class 0/0, rev 2.00/1.65, addr 2> on usbus0
kbd3 at ukbd1
% ll /dev/*kb*
crw------- 1 root wheel 0x47 Oct 31 10:46 /dev/atkbd0
lrwxr-xr-x 1 root wheel 6 Oct 31 10:46 /dev/kbd0 -> atkbd0
lrwxr-xr-x 1 root wheel 7 Oct 31 10:46 /dev/kbd1 -> kbdmux0
lrwxr-xr-x 1 root wheel 5 Oct 31 10:46 /dev/kbd2 -> ukbd0
lrwxr-xr-x 1 root wheel 5 Oct 31 10:46 /dev/kbd3 -> ukbd1
crw------- 1 root wheel 0x25 Oct 31 10:46 /dev/kbdmux0
crw------- 1 root wheel 0x62 Oct 31 10:46 /dev/ukbd0
crw------- 1 root wheel 0x6a Oct 31 10:46 /dev/ukbd1
何が起こっているのかは実際には非常に単純です。真のNキーロールオーバーと、これらすべての追加のゲームおよびその他のキーを提供するために、LogitechはUSB経由でキーボード入力イベントを報告する方法を調整しました。 FreeBSDカーネルに組み込まれているUSB入力レポート解析ライブラリはこれをサポートしていません。カーネルメッセージ出力をフィルタリングしなかった場合は、次のようなメッセージが表示されます。
hid_get_item:255に切り捨てられたアイテム(991)の数 hid_get_item:255に切り捨てられたアイテム(257)の数
hid_get_item:364:255に切り捨てられたアイテムの数
USB入力レポートプロトコルにより、USBHIDはそれぞれ最大65531キーの2つのセットを持つことができます。現在のUSB規格では、キー4のコードが定義されています(A a)から231(⌘ Right GUI)最初のセット。 「ゲーミングキーボード」にはそれよりもはるかに多くのキーがあり、そのほとんどは標準化されたキーコードに対応しておらず、実際にはどのような場合でも2番目のセットに入る可能性があります。
USB HID 概念的には、キーボードアクティビティを巨大なビットマップとして報告します。キーごとに1ビットで、キーボードのすべてのキーの現在のアップ/ダウン状態を記述します。これは確かに8つの修飾キーの場合であり、コード224から231で、通常他のキーは反転配列の形式で報告されます。デバイスからUSBホストへのネットワーク経由のキーボード入力レポートは、ビットマップ1に設定されているのビットのインデックスで構成されます。
この逆配列形式はスペースを節約します。現在この回答を入力している126キーのマルチメディアキーボードでは、キーボード全体をビットマップ形式でレポートするには、入力レポートごとに16バイトが必要です。ただし、反転配列では、使用するバイトはわずか8バイトで、そのうち6バイトは非修飾キーの配列インデックスです。
この逆配列形式の問題は、何も得られないことです。
残念ながら、ゲーミングキーボードは256をはるかに超えるキーコードを報告できる必要があります。前述のログの抜粋からわかるように、Logitechゲーミングキーボードのキーコードは、ある場合は最大257、別の場合は最大991です。これは、257キーと991キーがあるという意味ではありません。これは、キーコード値の範囲が非常に広いことを意味します。
FreeBSDカーネル、より具体的にはFreeBSDカーネルにリンクされているlibusbのカットダウンバージョンの制限は、やや微妙です。よく報告されるように、ビットマップサイズの制限ではありません。これらは、USB用語で入力項目のレポート数として知られているものに対する制限です。 FreeBSDは、レポート数を255に制限し、実際のレポート数が255より大きい場合、前述のメッセージを出力します。
これは、キーボード入力の両方ストレートビットマップ形式と反転配列形式に影響を及ぼします。
これは、後者よりも前者の方が問題です。これが問題になる場合、ビットマップ形式ではなく逆配列形式を使用するのは賢明な人ではありません。同じサイズのビットマップは、真のNキーロールオーバーで8倍のキーコードを表すことができるため、255個の配列インデックスを持つ逆配列は同等のビットマップ形式よりもはるかに少ないスペース効率が高くなります。
したがって、Logitechは、追加のすべてのキーを機能させるために、257または991キーコードの範囲のキーコードを報告したいと考えています。 (このように分割される理由は、さまざまなタイプのキーのコードがグループ化されるさまざまな「ページ」、および入力項目が複数の「ページ」にまたがることができない方法に関連しています。これは、この範囲を超えるUSBアルカナです。答え。)そしてそれは人々に6キー以上のロールオーバーを与えたいと思っています。
そのために、ビットマップと大量のレポートカウントを使用するUSB 入力レポート記述子形式に切り替えます。 (USBを使用すると、HIDは複数の入力レポート形式を使用でき、それらを切り替えることができます。)FreeBSDカーネルはこれを嫌い、問題が発生します。
ローカル修正は、Logitechキーボードに「ブート」入力レポート記述子形式の使用を強制することです。これは6キーのロールオーバーを提供し、「ネイティブ」レポート記述子の代わりにキーボードの追加キーのコードを送信できません。フォーマット。これは、すべてのシステムでbootstrap usbconfig
コマンドを使用して実行でき、add_quirk UQ_KBD_BOOTPROTO
サブコマンド。
この問題は、FreeBSDカーネルに組み込まれ、カーネルによって一致するUSBデバイスに魔法のように適用される、既存の定義済みの癖のリストにこの癖を入れることです。
サービスの修正は、カーネル内の削減されたlibusbを修正して、レポート数を255に制限しないようにすることです。FreeBSDメーリングリストの1つで簡単かつ表面的に議論されていますが、誰もこれを行っていません。