Co się stanie po naciśnięciu Ctrl + Alt + F <Num>?


38

Szukam wyjaśnienia tego, co dzieje się w systemie Linux po naciśnięciu tej kombinacji klawiszy w celu zmiany bieżącego terminala. W szczególności, jaki komponent oprogramowania przechwytuje tę kombinację klawiszy i zmienia terminal? Czy to jądro? Jeśli jest to jądro, czy możesz podać lokalizację pliku źródłowego, który to obsługuje?

Edycja: Chcę zrozumieć, jak to działa zarówno w środowisku graficznym (X11), jak i tekstowym.


1
Aby to wyjaśnić, czy naciskasz te klawisze w X11 (czyli sesji graficznej) czy w konsoli tekstowej? Odpowiedź jest inna.
derobert

Odpowiedzi:


36

To jest jądro. Pamiętaj, że klawiatura jest sprzętem i wszystko, co się tam dzieje, przechodzi przez jądro; w przypadku przełączania VT obsługuje to zdarzenie całkowicie sam i nie przekazuje niczego do przestrzeni użytkownika (uważam jednak, że istnieją środki związane z ioctl, za pomocą których programy przestrzeni użytkownika mogą być powiadamiane o wystąpieniu przełączenia z nimi związanego i być może na to wpływają, co X bez wątpienia robi).

Jądro ma wbudowaną mapę klawiszy ; można to zmodyfikować podczas pracy z loadkeysi przeglądać za pomocą 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
[...]   

Źródło jądra zawiera domyślny plik mapy klawiszy, który wygląda dokładnie tak; dla 3.12.2 to src/drivers/tty/vt/defkeymap.map. Zauważysz również, że istnieje odpowiedni plik defkeymap.c (można go wygenerować loadkeys --mktable). Obsługa jest w keyboard.c(wszystkie te pliki znajdują się w tym samym katalogu), który wywołuje set_console()zvt.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);

Zredagowałem niektóre hity z tej listy; możesz zobaczyć podpis funkcji w drugim ostatnim wierszu.

Są to rzeczy związane z przełączaniem. Jeśli spojrzeć na sekwencji połączeń, w końcu wrócisz do kbd_event()w keyboard.c. Jest to zarejestrowane jako moduł obsługi zdarzeń dla modułu:

(3.12.2 drivers/tty/vt/keyboard.cwiersz 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);           

Dlatego kbd_event()powinien zostać wywołany, gdy coś wyskoczy z faktycznego sterownika sprzętowego (prawdopodobnie coś z drivers/hid/lub drivers/input/). Jednak nie zobaczysz go nazywanego kbd_eventpoza tym plikiem, ponieważ jest on rejestrowany za pomocą wskaźnika funkcji.

Niektóre zasoby do kontroli jądra

  • Linux Odsyłacze Identifier Search jest doskonałym narzędziem.
  • Interactive Linux Kernel mapa to ciekawy graficzny front-end do przekroju narzędzia referencyjnego.
  • Istnieje kilka historycznych archiwów ogromnej listy mailingowej jądra systemu Linux (LKML), która sięga co najmniej 1995 roku; niektóre z nich nie są utrzymywane i mają zepsute funkcje wyszukiwania, ale gmane jeden działa bardzo dobrze. Ludzie zadawali wiele pytań na liście mailowej i jest to również główny środek komunikacji między programistami.
  • Możesz wstrzyknąć własne printklinie do źródła jako prosty sposób śledzenia (nie wszystkie standardowe biblioteki C lib mogą być używane w kodzie jądra, w tym printf ze stdio). printk rzeczy kończy się w syslog.

Wolfgang Mauerer napisał świetną dużą książkę o jądrze 2.6, Professional Linux Kernel Architecture , która przechodzi przez wiele źródeł. Greg Kroah-Hartman , jeden z głównych twórców ostatniej dekady, również ma wiele do zrobienia.


1
Dzięki, właśnie tego szukałem. Czy możesz wyjaśnić, co dzieje się wcześniej w łańcuchu? Jak wywoływany jest kod w keyboard.c, gdy naciskamy Ctrl + Alt + F1? keyboard.c nie jest tak naprawdę „sterownikiem klawiatury”, prawda?
user31765

1
Nie, nie sądzę. Wszystko to jest częścią sterownika tty, dla którego keyboard.cbyłby to moduł obsługi zdarzeń; sam „sterownik klawiatury” byłby na niższym poziomie - jest ich kilka drivers/input/keyboard/dla rzeczy innych niż USB. USB jest standaryzowany, więc byłby tylko jeden (prawdopodobnie obejmujący drivers/hid/usbhid/usbkbd.c). Zgaduję, że sterownik klawiatury służy do tworzenia skancodu, który można przekazać do vt / keyboard.c (patrz getkeycode () u góry tego). Documentation/input/input.txtma pewne (cudownie starożytne, lol) wskazówki.
goldilocks

PS. Wielu deweloperów jądra znajduje się na otwartej publicznie liście mailingowej jądra Linuksa (LKML), a jeśli masz na myśli swoje pytania i odpowiedzi itp. ( Tux.org/lkml ), warto o to zapytać ... po prostu upewnij się, że od razu skonfiguruj folder, w grę wchodzi DUŻO poczty.
goldilocks

Po dokładniejszym zbadaniu kodu w keyboard.c są tylko trzy nieaktualne funkcje, które wywołują set_console: fn_lastcons (), fn_dec_console () i fn_inc_console (). Jeden do przejścia do ostatniej konsoli i jeden do przejścia w prawo lub w lewo. Więc nadal nie rozumiem, jak wywoływana jest funkcja set_console (), gdy naciskamy Ctrl + Alt + F <num>. Zakładam, że musimy przekazać gdzieś parametr <num> jako parametr do set_console (). Widzę, że set_console () pojawia się również w vt_ioctl.c, ale czy nie jest to tylko dla ioctl z przestrzeni użytkownika, np. Z chvt? W moim rozumieniu wciąż są pewne dziury.
user31765,

1
W sterownikach / ukrytych jest więcej potencjalnie powiązanych rzeczy. Zwróć także uwagę na „console_callback ()” w vt.c, które może dokonać przełączenia i jest zarejestrowane na górze poprzez DECLARE_WORK. Odnosi się to do harmonogramu: lxr.free-electrons.com/ident?i=DECLARE_WORK (to narzędzie do odsyłaczy można zasilać z makelinux.net/kernel_map, co może być dla ciebie interesujące); Zakładam, że dzięki temu ta funkcja jest swego rodzaju „główną pętlą” dla vt. Oczywiście brakujący link tutaj jest dokładnie tym, w jaki sposób przekazywane są zdarzenia na klawiaturze.
złotowłosa
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.