Linux 커널은 키보드 누르기를 어떻게 처리합니까?

Linux 커널은 키보드 누르기를 어떻게 처리합니까?

저는 현재 Linux 커널과 운영 체제 전반에 대해 배우고 있으며 IRQ, 드라이버, 스케줄링 및 기타 중요한 운영 체제 개념과 키보드 관련 리소스에 대한 훌륭한 리소스를 많이 찾았습니다. Linux 커널이 키보드의 버튼 누름을 처리하는 방법에 대한 개요입니다. 이 단계에서는 모든 세부 사항을 이해하려고 노력하는 것이 아니라 개념을 어느 정도 포괄적으로 연결하려고 노력하고 있습니다.

다음 시나리오가 떠오릅니다.

  1. 저는 단일 프로세서가 있는 x64 시스템을 사용하고 있습니다.
  2. VIM여러 프로세스, 특히 편집기 ( Process #1) 및 say LibreOffice( ) 가 실행 중입니다 Process #2.
  3. 나는 안에 있고 - 키를 VIM누릅니다 . a그러나 현재 실행중인 프로세스 Process #2( VIM다음에 예약됩니다).

이제 상황이 이렇게 될 것이라고 상상합니다.

  1. 키보드는 일련의 단계를 거쳐 전기 신호(USB 프로토콜 인코딩)를 생성하고 이를 USB 케이블을 통해 보냅니다.
  2. 신호는 USB 컨트롤러에 의해 처리되고 APICPCI-e(및 다른 컨트롤러/버스?)를 통해 인터럽트 컨트롤러( )로 전송됩니다. 트리거 프로세서 APIC.INT Pin
  3. 프로세서는 요청을 Kernel Mode전환 하고 이를 오프셋 ( )으로 사용합니다. 설명자를 얻고 해당 설명자를 사용하여 인터럽트 처리기 루틴의 주소를 얻습니다. 내가 이해한 바에 따르면, 이 인터럽트 핸들러는 처음에 키보드 드라이버에 의해 등록됩니다.IRQ-NumberAPICInterrupt Descriptor Table RegisterIDTR
  4. 인터럽트 처리기를 호출합니다(이 경우 키보드 처리기).

이는 나의 주요 질문으로 이어집니다. 인터럽트 핸들러 루틴은 어떤 메커니즘을 통해 누른 키를 올바른 프로세스( Process #1)에 전달합니까? 실제로 그렇게 합니까, 아니면 char-device한 번에 하나의 프로세스에서만 읽을 수 있는 버퍼(통과 가능?)에 누른 키를 기록합니까(현재는)"포함"도착하다 Process #1)? 언제인지 이해가 안 돼요Process #1 받다열쇠. 인터럽트 핸들러로서 데이터를 즉시 처리하는지 여부일정즉시 처리하시겠습니까, 아니면 다음에 스케줄러가 예약할 때 중요한 데이터를 처리하시겠습니까?

  1. 이 핸들러가 ( IRET)를 반환하면 컨텍스트는 이전에 실행 중인 프로세스( Process #2)로 다시 전환됩니다.

답변1

지금까지 귀하의 이해는 정확했지만 이를 기반으로 구축하는 복잡성의 대부분을 놓치고 있습니다. 커널에서의 처리는 여러 계층에서 발생하며 키 입력은 이러한 계층을 통해 "버블링"됩니다.

USB 통신 프로토콜 자체는 훨씬 더 복잡합니다. USB의 인터럽트 핸들러 루틴은 이를 처리하고 필요에 따라 여러 조각에서 완전한 USB 패킷을 조립합니다.

소위 말하는 키를 사용하는 키고압 가스 방전관("Human Interface Device") 프로토콜은 USB 위에 구축됩니다. 따라서 하위 USB 커널 계층은 전체 메시지가 USB HID 이벤트임을 감지하고 이를 커널의 HID 계층으로 전달합니다.

HID 계층은 초기화 중에 장치에 필요한 HID 설명자를 기반으로 이 이벤트를 해석합니다. 그런 다음 이벤트를 입력 레이어에 전달합니다. 단일 HID 이벤트는 여러 주요 이벤트를 생성할 수 있습니다.

입력 레이어는 커널 키보드 레이아웃 테이블을 사용하여 스캔 코드(키보드의 키 위치)를 키 코드(예: A)에 매핑하고 이를 해석 합니다 Shift. Alt이 해석의 결과는 /dev/input/event*사용자 공간 프로세스를 통해 사용할 수 있습니다. evtest이러한 이벤트를 실시간으로 시청 하는 데 사용할 수 있습니다 .

그러나 처리는 여기서 끝나지 않습니다. X 서버(그래픽 담당)에는 evdev장치에서 이벤트를 읽고 /dev/input/event*이를 매핑 하는 일반 드라이버가 있습니다.다시xmodmap두 번째 키보드 레이아웃 표 세트를 기반으로 합니다(이 키보드 레이아웃 표는 XKBD 확장을 부분적으로 사용 하고 XKBD 확장을 완전히 사용하여 볼 수 있음 ). 이는 X 서버가 커널 입력 계층보다 이전 버전이고 초기에는 마우스와 PS/2 키를 직접 처리하는 드라이버가 있었기 때문입니다.

그런 다음 X 서버는 키보드 이벤트가 포함된 메시지를 X 클라이언트(응용 프로그램)로 보냅니다. 앱을 사용하여 이러한 메시지를 볼 수 있습니다 xev. LibreOffice이 이벤트는 직접 처리되고, VIM이벤트를 처리할 an 에서 실행되며 xterm, ( 짐작하셨겠지만) 다시 처리를 추가하고 마지막으로 VIMvia 에 전달합니다 stdin.

충분히 복잡합니까?

답변2

누른 키를 버퍼에 기록합니다(문자 장치를 통해 사용 가능합니까?).

예, 그렇게 말해야 합니다.

그런 다음 (낮은 수준) 콘솔에서 tty(가상), 의사 tty까지 계단식으로 연결됩니다. 키 입력은 활성화된 "콘솔"에 따라 /dev/tty1 또는 /dev/tty5에 기록됩니다.

xterm에서(ps axf 출력):

  467 tty1     Ss     0:38  \_ -bash
 5820 tty1     S+     0:00      \_ xinit fvwm -- vt9
 5821 tty9     S<sl+  54:15          \_ /usr/lib/Xorg :0 vt9
 5831 tty1     S      0:00          \_ xterm -geometry +1+1 -n login fvwm
 5833 pts/0    Ss+    0:38              \_ fvwm
 ...
 ...
  773 pts/0    S      0:07                  \_ xterm
  775 pts/2    Ss+    0:00                  |   \_ bash
14452 pts/0    S      0:04                  \_ xterm
14454 pts/1    Ss     0:00                  |   \_ bash
14507 pts/1    S      0:00                  |       \_ xfontsel
31044 pts/1    R+     0:00                  |       \_ ps ax f
19549 pts/0    S      0:00                  \_ xterm
19551 pts/3    Ss+    0:00                      \_ bash

이것은 Xorg가 tty1에서 tty9로 시작하는 방법과 fvwm(창 관리자) 및 xterm(터미널 에뮬레이터)이 /dev/pts/0을 "가져오는" 방법과 새 쉘이 /dev/pts/1, pts/2를 얻는 방법을 보여줍니다. pts/3 등

이제 pid 19551 pts/3 bash 프로세스를 활성화했는지 여부에 관계없이조언을 제공xterm 창에서 키를 누르거나 echo hello >/dev/pts/3/dev/tty5와 같은 콘솔 vt에서 이 작업을 수행하면 문자가 올바른 프로세스로 이동합니다.

man ps"프로세스 상태 코드" 아래에 설명되어 있습니다(글쎄, 나열되어 있습니다):

S    interruptible sleep (waiting for an event to complete)
s    is a session leader    
+    is in the foreground process group

이런 키워드를 남겨드립니다...

관련 정보