Ctrl + Alt + F <Num>を押すとどうなりますか?


38

このキーの組み合わせを押して現在の端末を変更すると、Linuxで何が起こるかについての説明を探しています。特に、どのソフトウェアコンポーネントがこのキーの組み合わせをインターセプトし、端末を変更しますか?それはカーネルですか?カーネルの場合、これを処理するソースファイルの場所を指定できますか?

編集:グラフィカル(X11)環境とテキストベース環境の両方でこれがどのように機能するかを理解したいと思います。


1
明確にするために、X11(つまり、グラフィカルセッション)またはテキストコンソールでこれらのキーを押しますか?答えは異なります。
デロバート

回答:


36

それはカーネルです。キーボードはハードウェアであり、そこで発生するすべてがカーネルを通過することに注意してください。VTスイッチングの場合、イベント自体を完全に処理し、ユーザー空間には何も渡しません(ただし、ユーザー空間プログラムがそれらに関連する切り替えが発生したことをユーザー空間プログラムに通知し、おそらくそれに影響を与えることができるioctl関連の手段があると思います。 Xは間違いないでしょう)。

カーネルにはキーマップが組み込まれています。これはで実行中に変更できloadkeys、次で表示できますdumpkeys

[...]
keycode  59 = F1               F13              Console_13       F25             
        alt     keycode  59 = Console_1       
        control alt     keycode  59 = Console_1       
keycode  60 = F2               F14              Console_14       F26             
        alt     keycode  60 = Console_2       
        control alt     keycode  60 = Console_2       
keycode  61 = F3               F15              Console_15       F27             
        alt     keycode  61 = Console_3       
        control alt     keycode  61 = Console_3
[...]   

カーネルソースには、このように見えるデフォルトのキーマップファイルが含まれています。3.12.2ことがありますsrc/drivers/tty/vt/defkeymap.map。また、対応するdefkeymap.cファイルがあることに気付くでしょう(これはで生成できますloadkeys --mktable)。処理はkeyboard.cset_console()からvt.c呼び出します(これらのファイルはすべて同じディレクトリにあります)。

» grep set_console *.c
keyboard.c:     set_console(last_console);
keyboard.c:     set_console(i);
keyboard.c:     set_console(i);
keyboard.c:     set_console(value);
vt.c:int set_console(int nr)
vt_ioctl.c:                     set_console(arg);

そのリストからいくつかのヒットを編集しました。最後の2行目に関数のシグネチャを見ることができます。

これらがスイッチングに関係するものです。あなたが呼び出しのシーケンスを見れば、最終的にあなたが戻ってくるまでkbd_event()の中でkeyboard.c。これは、モジュールのイベントハンドラーとして登録されます。

(3.12.2 drivers/tty/vt/keyboard.c行1473)

MODULE_DEVICE_TABLE(input, kbd_ids);

static struct input_handler kbd_handler = {
    .event      = kbd_event,   <--- function pointer HERE
    .match      = kbd_match,
    .connect    = kbd_connect,
    .disconnect = kbd_disconnect,
    .start      = kbd_start,
    .name       = "kbd",
    .id_table   = kbd_ids,
};  

int __init kbd_init(void)
{

[...]

    error = input_register_handler(&kbd_handler);           

したがって、kbd_event()実際のハードウェアドライバーから何かがバブルアップしたときに呼び出される必要があります(drivers/hid/またはから何かdrivers/input/)。ただし、kbd_event関数ポインタを介して登録されているため、そのファイルの外部と呼ばれることはありません。

カーネルを精査するためのリソース

  • Linuxのクロスリファレンス識別子検索は素晴らしいツールです。
  • インタラクティブLinuxカーネル地図は、クロスリファレンスツールに興味深いグラフィカルなフロントエンドです。
  • 少なくとも1995年にさかのぼる大規模なLinuxカーネルメーリングリスト(LKML)の歴史的なアーカイブがいくつかあります。それらのいくつかは維持されておらず、検索機能が壊れていますが、gmaneは非常にうまく機能しているようです。メーリングリストで多くの質問が寄せられており、開発者間のコミュニケーションの主要な手段でもあります。
  • printkトレースの簡単な手段として、ソースに独自の行を挿入できます(stdioのprintfを含む、すべての標準Cライブラリをカーネルコードで使用できるわけではありません)。printkのものはsyslogになります。

Wolfgang Mauererは、2.6カーネル、Professional Linux Kernel Architectureについてのすばらしい大きな本を執筆しました。 過去10年間の主要な開発者の1人であるGreg Kroah-Hartmanも、いろいろなことをやっています。


1
おかげで、これはまさに私が探していたものです。チェーンの早い段階で何が起こるのか詳しく説明していただけますか?Ctrl + Alt + F1を押すと、keyboard.cのコードはどのように呼び出されますか?keyboard.cは実際の「キーボードドライバ」ではありませんか?
user31765

1
いいえ、そうは思いません。それはすべてttyドライバーの一部であり、そのためkeyboard.cのイベントハンドラーです。「キーボードドライバー」自体はより低いレベルになります- drivers/input/keyboard/非USBのものにはそれらの束があります。USBのものは標準化されているので、1つしかありません(おそらくを含むdrivers/hid/usbhid/usbkbd.c)。キーボードドライバーは、vt / keyboard.cに渡すことができるスキャンコードを生成するためのものであると推測しています(その上部にあるgetkeycode()を参照)。 Documentation/input/input.txtいくつかのヒントがあります(驚くほど古いです、笑)。
goldilocks

PS。カーネル開発者の多くは、一般公開されているLinuxカーネルメールリスト(LKML)に登録されています。P&Qなど(tux.org/lkml)を気にする場合は、お問い合わせください。すぐにフォルダを設定すると、大量のメールが含まれます。
goldilocks

コードを詳細に調べると、set_consoleを呼び出すkeyboard.cには、fn_lastcons()、fn_dec_console()、fn_inc_console()の3つの廃止されていない関数しかありません。1つは最後のコンソールに行き、もう1つは右または左に行きます。したがって、Ctrl + Alt + F <num>を押したときにset_console()がどのように呼び出されるかはまだわかりません。どこかでset_console()のパラメーターとして<num>を渡す必要があると思います。set_console()がvt_ioctl.cにも現れることがわかりますが、それはユーザー空間、例えばchvtからのioctlだけのものではありませんか?私の理解にはまだいくつかの穴があります。
user31765

1
drivers / hidには、より潜在的に関連するものがあります。また、vt.cの「console_callback()」に注目してください。これは切り替えを行うことができ、DECLARE_WORKを介して上部に登録されます。これはスケジューラに関連しています:lxr.free-electrons.com/ident?i = DECLARE_WORK(この相互参照ツールはmakelinux.net/kernel_mapから提供されます。これにより、その関数はvtの「メインループ」になります。明らかに、ここで見つからないリンクは、キーボードイベントがどのように渡されるかです。
goldilocks
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.