키보드 입력 및 텍스트 출력은 어떻게 작동합니까?


85

A텍스트 편집기에서 키를 누르면 a문서에 문자 가 삽입 되어 화면에 표시됩니다. 편집기 응용 프로그램이 하드웨어와 직접 통신하지 않는다는 것을 알고 있습니다 (커널과 그 사이에 물건이 있음). 내 컴퓨터 내부에서 어떤 일이 일어나고 있습니까?

답변:


100

몇 가지 다른 시나리오가 있습니다. 가장 일반적인 것을 설명하겠습니다. 연속적인 거시적 사건은 다음과 같습니다.

  1. 입력 : 키 누름 이벤트가 키보드 하드웨어에서 응용 프로그램으로 전송됩니다.
  2. 처리 : 응용 프로그램은 키 A를 눌렀 기 때문에 문자를 표시해야 한다고 결정합니다 a.
  3. 출력 : 응용 프로그램 a이 화면 에 표시 할 순서를 제공합니다 .

GUI 어플리케이션

유닉스 시스템의 사실상의 표준 그래픽 사용자 인터페이스는 X 윈도우 시스템으로 , X11은 종종 응용 프로그램과 디스플레이 서버 간의 핵심 프로토콜의 11 번째 버전에서 안정화 되었기 때문에 X11이라고합니다. X 서버라는 프로그램은 운영 체제 커널과 응용 프로그램 사이에 있습니다. 화면에 창을 표시하고 포커스가있는 창으로 키 누름을 전송하는 등의 서비스를 제공합니다.

입력

+----------+              +-------------+         +-----+
| keyboard |------------->| motherboard |-------->| CPU |
+----------+              +-------------+         +-----+
             USB, PS/2, …                 PCI, …
             key down/up

먼저, 키 누름 및 키 해제에 대한 정보가 키보드에서 컴퓨터 및 컴퓨터 내부로 전송됩니다. 세부 사항은 하드웨어 유형에 따라 다릅니다. 체인의이 부분에서 정보가 동일하게 유지되기 때문에이 부분에 대해서는 더 이상 언급하지 않겠습니다. 특정 키를 누르거나 놓았습니다.

         +--------+        +----------+          +-------------+
-------->| kernel |------->| X server |--------->| application |
         +--------+        +----------+          +-------------+
interrupt          scancode             keysym
                   =keycode            +modifiers

하드웨어 이벤트가 발생하면 CPU가 인터럽트를 트리거 하여 커널의 일부 코드 가 실행되도록합니다. 이 코드는 하드웨어 이벤트가 키보드에서 나오는 키 누르기 또는 키 릴리스임을 감지하고 키 를 식별하는 스캔 코드 를 기록합니다 .

X 서버는 디바이스 파일을 통해 입력 이벤트를 읽습니다 /dev/input/eventNNN( 예 : Linux의 경우 NNN은 숫자 임). 이벤트가있을 때마다 커널은 해당 장치에서 읽을 데이터가 있다는 신호를 보냅니다. 장치 파일은 스캔 코드와 함께 키 업 / 다운 이벤트를 전송합니다. 스캔 코드는 하드웨어에 의해 전송 된 값과 같거나 같지 않을 수 있습니다 (커널은 스캔 코드를 키보드 종속 값에서 공통 값으로 변환 할 수 있으며 Linux 는 모르는 스캔 코드를 다시 전송하지 마십시오 .

X는 코드를 읽는 스캔 코드를 호출합니다 . X 서버는 키 코드를 키심 으로 변환하는 테이블을 유지 관리합니다 ( "키 심볼"의 약어). keysyms 같은 이름 반면 키 코드는 숫자되어 A, aacute, F1, KP_Add, Control_L, ... keysym 데는 (보조 키를 누르면에 따라 다를 수있다 Shift, Ctrl...).

키 코드에서 키심으로의 맵핑을 구성하는 두 가지 메커니즘이 있습니다.

  • xmodmap 은 전통적인 메커니즘입니다. 키 코드를 키심 목록 (수정되지 않은, 이동 된…)에 맵핑하는 간단한 테이블입니다.
  • XKB 는보다 강력하지만 복잡한 메커니즘으로, 특히 이중 언어 구성을 위해 더 많은 수정자를 더 잘 지원합니다.

응용 프로그램이 X 서버에 연결되고 해당 응용 프로그램의 창에 포커스가있는 동안 키를 누르면 알림이 수신됩니다. 이 알림은 특정 키 심을 눌렀거나 놓았으며 현재 어떤 수정자를 눌렀는지 나타냅니다. xev터미널 에서 프로그램 을 실행하여 키 심을 볼 수 있습니다 . 응용 프로그램이 정보를 사용하여 수행하는 작업은 정보에 달려 있습니다. 일부 응용 프로그램에는 구성 가능한 키 바인딩이 있습니다.

일반적인 구성에서 A수정 자없이 레이블이 지정된 키를 누르면 키 심이 a응용 프로그램으로 전송 됩니다. 응용 프로그램이 텍스트를 입력하는 모드 인 경우 문자가 삽입됩니다 a.

키보드 레이아웃과 xmodmap의 관계는 키보드 입력에 대해 자세히 설명합니다. 리눅스에서 마우스 이벤트는 어떻게 작동합니까? 낮은 수준에서 마우스 입력에 대한 개요를 제공합니다.

산출

+-------------+        +----------+          +-----+         +---------+
| application |------->| X server |---····-->| GPU |-------->| monitor |
+-------------+        +----------+          +-----+         +---------+
               text or              varies          VGA, DVI,
               image                                HDMI, …

문자를 표시하는 방법에는 두 가지가 있습니다.

다른 유형의 XWindows 글꼴의 목적은 무엇입니까?를 참조하십시오 . X11에서 클라이언트 측 및 서버 측 텍스트 렌더링에 대해 설명합니다.

X 서버와 그래픽 처리 장치 (비디오 카드의 프로세서) 사이에서 일어나는 일은 하드웨어에 따라 다릅니다. 간단한 시스템은 X 서버가 프레임 버퍼 (framebuffer ) 라고하는 메모리 영역을 가져와 GPU가 표시하도록 선택합니다. 21 세기 PC 또는 스마트 폰에서 볼 수있는 고급 시스템을 통해 GPU는 일부 작업을 직접 수행하여 성능을 향상시킬 수 있습니다. 궁극적으로 GPU는 1 초마다 픽셀 단위로 화면 내용을 모니터에 전송합니다.

터미널에서 실행되는 텍스트 모드 응용 프로그램

텍스트 편집기가 터미널에서 실행되는 텍스트 모드 응용 프로그램 인 경우 위 섹션의 목적을위한 응용 프로그램 인 터미널입니다. 이 섹션에서는 텍스트 모드 응용 프로그램과 터미널 간의 인터페이스에 대해 설명합니다. 먼저 X11에서 실행 되는 터미널 에뮬레이터 의 경우를 설명합니다 . '터미널', '쉘', 'tty'및 '콘솔'의 정확한 차이점은 무엇입니까? 여기에 유용한 배경이 될 수 있습니다. 이 내용을 읽은 후 훨씬 더 자세한 내용을 읽을 수 있습니다. 각 PTY (Pseudo-Terminal) 구성 요소 (소프트웨어, 마스터 측, 슬레이브 측)의 책임은 무엇입니까?

입력

      +-------------------+               +-------------+
----->| terminal emulator |-------------->| application |
      +-------------------+               +-------------+
keysym                     character or
                           escape sequence

터미널 에뮬레이터는 "같은 이벤트를 수신 Left누른 동안이 Shift다운 된". 터미널 에뮬레이터와 텍스트 모드 응용 프로그램 간의 인터페이스는 바이트를 전송 하는 문자 장치의사 터미널 (pty) 입니다. 터미널 에뮬레이터가 키 누르기 이벤트를 수신하면이를 하나 이상의 바이트로 변환하여 응용 프로그램이 pty 장치에서 읽습니다.

ASCII 범위를 벗어난 인쇄 가능한 문자는 문자 및 인코딩 에 따라 하나 이상의 바이트로 전송됩니다 . 예를 들어 유니 코드 문자 집합 의 UTF-8 인코딩 에서 ASCII 범위의 문자 는 단일 바이트로 인코딩되고 해당 범위 밖의 문자는 여러 바이트로 인코딩됩니다.

기능 키 또는 같은 개질제와 인쇄 문자에 해당하는 키 누름 Ctrl또는이 Alt로 전송되는 제어 시퀀스 . 이스케이프 시퀀스는 일반적으로 문자 이스케이프 (바이트 값 27 = 0x1B = \033, 때로는 ^[또는로 \e표시됨)와 하나 이상의 인쇄 가능한 문자로 구성됩니다. 일부 키 또는 키 조합에는 ASCII 기반 인코딩 (유니 코드를 포함하여 오늘날 사용되는 거의 모든 문자)에 해당 하는 제어 문자 가 있습니다. Ctrl+ letter1-26 범위의 문자 값을 생성 Esc하고 이스케이프 문자입니다. 위에서 본도 동일하다 Ctrl+ [, Tab동일하다 Ctrl+ I,ReturnCtrl+ 와 동일합니다 M.

다른 터미널은 주어진 키 또는 키 조합에 대해 다른 이스케이프 시퀀스를 보냅니다. 다행히도 그 반대는 사실이 아닙니다. 시퀀스가 ​​주어지면 실제로는 인코딩하는 키 조합이 최대 하나뿐입니다. 한 가지 예외는 문자 127 = 0x7f = \0177인데 종종 Backspace있지만 때로는 그렇습니다 Delete.

터미널에서 Ctrl+ V와 키 조합을 차례로 입력 하면 이스케이프 시퀀스의 첫 번째 바이트가 키 조합에서 문자 그대로 삽입됩니다. 이스케이프 시퀀스는 일반적으로 첫 번째 문자 다음에 인쇄 가능한 문자로만 구성되므로 전체 이스케이프 시퀀스를 문자 그대로 삽입합니다. 키 바인딩 테이블을 참조하십시오 ? 이 맥락에서 zsh에 대한 토론.

단말기는 (예를 들어 많은 단말이 모두 공백 문자를 전송하는 일부 수정 조합 동일 제어 시퀀스를 전송할 수있다 SpaceShift+ Space; xterm 등은 개질제의 조합을 구별 할 수있는 모드를 갖고 있지만, 인기 VTE 라이브러리를 기반으로 단말기 않는 생략 ). 터미널 에뮬레이터의 바인딩 (예 : 복사 또는 붙여 넣기 명령)을 트리거하는 수정 자 키 또는 키와 같은 일부 키는 전혀 전송되지 않습니다.

원하는 경우 이스케이프 시퀀스를 기호 키 이름으로 변환하는 것은 애플리케이션에 달려 있습니다.

산출

+-------------+               +-------------------+
| application |-------------->| terminal emulator |--->
+-------------+               +-------------------+
               character or
               escape sequence

출력은 입력보다 다소 간단합니다. 응용 프로그램이 pty 장치 파일에 문자를 출력하면, 터미널 에뮬레이터는 해당 문자를 현재 커서 위치에 표시합니다. (터미널 에뮬레이터는 커서 위치를 유지하고 커서가 화면 맨 아래에 놓이면 스크롤됩니다.) 응용 프로그램은 이스케이프 시퀀스 (주로 ^[또는로 시작 ^])를 출력 하여 커서 이동과 같은 작업을 수행하도록 터미널에 지시 할 수 있습니다. 텍스트 속성 (컬러, 굵은 체,…) 변경 또는 화면 지우기 부분.

터미널 에뮬레이터가 지원하는 이스케이프 시퀀스는 termcap 또는 terminfo 데이터베이스에 설명되어 있습니다. 오늘날 대부분의 터미널 에뮬레이터는 xterm 과 상당히 밀접하게 정렬되어 있습니다. LESS_TERMCAP_ * 변수에 대한 설명서를 참조하십시오 ? 터미널 기능 정보 데이터베이스에 대한 자세한 설명과 커서 깜박임을 중지하는 방법로컬 시스템의 터미널 색상을 설정하여 ssh로 전환 한 시스템의 색상을 사용할 수 있습니까? 일부 사용 예의 경우.

텍스트 콘솔에서 실행되는 응용 프로그램

애플리케이션이 텍스트 콘솔, 즉 터미널 에뮬레이터 애플리케이션이 아닌 커널이 제공하는 터미널에서 직접 실행중인 경우 동일한 원칙이 적용됩니다. 터미널과 애플리케이션 사이의 인터페이스는 여전히 문자를 전송하는 바이트 스트림이며 특수 키와 명령은 이스케이프 시퀀스로 인코딩됩니다.

네트워크를 통해 액세스되는 원격 애플리케이션

원격 텍스트 애플리케이션

SSH를 통해 원격 시스템에서 프로그램을 실행 하면 네트워크 통신 프로토콜이 pty 레벨에서 데이터를 릴레이합니다.

+-------------+           +------+           +-----+           +----------+
| application |<--------->| sshd |<--------->| ssh |<--------->| terminal |
+-------------+           +------+           +-----+           +----------+
               byte stream        byte stream       byte stream
               (char/seq)         over TCP/…        (char/seq)

원격 터미널 데이터베이스가 로컬 터미널의 모든 기능을 알지 못하는 경우를 제외하고는 대부분 투명합니다.

원격 X11 애플리케이션

응용 프로그램과 서버 간의 통신 프로토콜 자체는 SSH와 같은 네트워크 프로토콜을 통해 전송 될 수있는 바이트 스트림입니다.

+-------------+            +------+        +-----+            +----------+
| application |<---------->| sshd |<------>| ssh |<---------->| X server |
+-------------+            +------+        +-----+            +----------+
               X11 protocol        X11 over       X11 protocol
                                   TCP/…

응용 프로그램과 디스플레이간에 직접 통신이 필요한 영화 디코딩 및 3D 렌더링과 같은 일부 가속 기능을 사용할 수 있다는 점을 제외하고는 대부분 투명합니다.


완전히 확실하지는 않지만 대답은 일반적으로 다소 상세하기 때문에 "텍스트 콘솔에서 실행중인 응용 프로그램"이라는 부분이 to man 5 keymaps를 번역하는 데 사용되는 것과 같은 기능이 없는지 궁금합니다 . 언급 된 바와 같이 그것은 완전히 다른 도구 / 프로그램 세트이며 이것은 아마도 더 많은 통찰력을 가질 것입니다. 그 옆에 포함 된 관련 질문으로 인해 대답은 +1이며 훌륭합니다. keycodesscancodes
humanandANDpeace

tty1 (TERM = linux)에서 발견 PgUp하고 Ctrl+PgUp구분할 수 없습니다. keysym-> 제어 순서 맵핑을 구성 할 수 있습니까?
stewbasic

@stewbasic 그렇습니다 loadkeys. 키맵이로드되어 있습니다. linux console keyboard-layout 태그가 지정된 질문을 검색하십시오 .
Gilles

@ 길스 감사합니다! loadkeys는 키 코드-> keysym 및 keysym-> 이스케이프 시퀀스를 모두 변경한다는 점에 주목할 가치가 있습니다 (이것은 처음에는 나에게 분명하지 않았습니다).
stewbasic

1
와우, 이것은 내가 Stackexchange에서 본 최고의 답변 중 하나 여야합니다-잘 조직되고, 질문에 대답하고, 관련 컨텍스트를 제공하며, 다른 유용한 답변을 상호 참조하고, 심지어 멋진 ASCII 예술을 가지고 있습니다!
Johntron

4

이해할 수있을 정도로 작은 유닉스 시스템에서 이것을보고 싶다면 Xv6을 파헤 치십시오 . 존 라이온의 유명한 논평 의 기초가 된 신화적인 Unix 6th Edition은 얼마 안되어 samizdat로 널리 보급되었습니다. 이 코드는 ANSI C에서 컴파일되고 멀티 프로세서와 같은 최신 개발을 고려하여 재 작업되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.