Ctrl + Alt + F <Num>을 누르면 어떻게됩니까?


38

이 키 조합을 눌러 현재 터미널을 변경하면 Linux에서 발생하는 일에 대한 설명을 찾고 있습니다. 특히 어떤 소프트웨어 구성 요소가이 키 조합을 가로 채 터미널을 변경합니까? 커널입니까? 커널 인 경우이를 처리하는 소스 파일의 위치를 ​​제공 할 수 있습니까?

편집 : 그래픽 (X11) 및 텍스트 기반 환경에서 이것이 어떻게 작동하는지 이해하고 싶습니다.


1
명확히하기 위해 X11 (그래픽 세션) 또는 텍스트 콘솔 에서이 키를 누르고 있습니까? 답은 다릅니다.
derobert

답변:


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.c호출하는 (모든 파일이 같은 디렉토리에있는) set_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);

해당 목록에서 일부 조회수를 수정했습니다. 마지막 두 번째 줄에서 함수 서명을 볼 수 있습니다.

이것이 스위칭과 관련된 것입니다. 당신이 전화의 순서를 보면, 결국은 다시 오지 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 Kernel Mailing List (LKML)의 기록 보관소는 1995 년 이상으로 거슬러 올라갑니다. 그들 중 일부는 유지되지 않고 검색 기능이 손상되었지만 gmane 하나 는 매우 잘 작동하는 것 같습니다. 사람들은 메일 목록에 대해 많은 질문을했으며 개발자들 사이의 주요 커뮤니케이션 수단이기도합니다.
  • printk간단한 추적 수단으로 자체 라인을 소스에 삽입 할 수 있습니다 (stdio의 printf를 포함하여 모든 표준 C lib를 커널 코드에서 사용할 수있는 것은 아닙니다). printk 항목은 syslog로 끝납니다.

Wolfgang Mauerer는 2.6 커널 인 Professional Linux Kernel Architecture 에 대한 큰 책을 썼습니다 . 지난 10 년간의 주요 개발자 중 한 명인 Greg Kroah-Hartman 도 많은 일을하고 있습니다.


1
고마워, 이것은 내가 찾던 것입니다. 체인의 초기에 어떤 일이 발생하는지 자세히 설명해 주시겠습니까? Ctrl + Alt + F1을 누르면 keyboard.c의 코드가 어떻게 호출됩니까? keyboard.c는 실제 "키보드 드라이버"가 아닙니까?
user31765

1
아니요, 그렇게 생각하지 않습니다. 그것은 모두 tty 드라이버의 일부이며, keyboard.c이벤트 핸들러가 될 것입니다. "키보드 드라이버"자체는 더 낮은 수준 drivers/input/keyboard/일 것입니다. USB 물건은 표준화되어 있으므로 하나만 (아마도 관련이 있음 drivers/hid/usbhid/usbkbd.c) 있습니다. 키보드 드라이버는 vt / keyboard.c에 전달할 수 있는 스캔 코드 를 생성하기위한 것 같습니다 (맨 위의 getkeycode () 참조). Documentation/input/input.txt(놀랍게도 고대의 lol) 힌트가 있습니다.
goldilocks

추신. 많은 커널 개발자들이 공개 된 리눅스 커널 메일리스트 (LKML)에 있으며, P & Q 등 ( tux.org/lkml ) 을 염두에두고 있다면 여기에 문의 해보 십시오. 폴더를 바로 설정하면 많은 메일이 관련됩니다.
goldilocks

코드를 좀 더 자세히 살펴보면, keyboard.c에는 fn_lastcons (), fn_dec_console () 및 fn_inc_console ()과 같이 set_console을 호출하는 3 개의 사용되지 않는 함수 만 있습니다. 하나는 마지막 콘솔로 가고 다른 하나는 오른쪽이나 왼쪽으로갑니다. 따라서 Ctrl + Alt + F <num>을 누를 때 set_console ()이 어떻게 호출되는지 이해하지 못합니다. <num>을 매개 변수로 set_console ()에 전달해야한다고 가정합니다. set_console ()도 vt_ioctl.c에서 자르는 것을 보았습니다. 그러나 ivttl은 사용자 공간에서, 예를 들어 chvt에서 아닙니다. 내 이해에는 여전히 몇 가지 구멍이 있습니다.
user31765

1
드라이버 / 숨김에 더 관련성이있는 것들이 있습니다. 또한 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.