키보드를 누르면 어떤 일이 발생할까?
에 대한 답변으로 OS 인터럽트에 대해 얘기할 수 있다. 하나씩 차근 차근 살펴보자
A 키를 눌렀다고 생각해보자. 우선 키보드의 키 밑에는 작은 고무가있다. 이 고무를 누르게 되면 키보드 아래의 회로에 전자가 흐르게 되어, 키보드 내의 마이크로 컨트롤러가 신호를 인식하게 된다.
이때 컨트롤러는 어느 키가 눌러졌는지(key down), 키가 올라갔는지(key up)를 판별하기 위한 정보인 Scan Code와 자신의 IO 번호(키보드는 1번이다)를 OS에게 전달하게 된다.
Scan Code는 우리가 흔히 아는 ASCII Code와 다르다. ASCII Code로의 변환은 키보드 인터럽트 핸들러에서 진행된다.
여담으로 key up 시그널은 key down 시그널의 + 128 값으로 발생한다. 따라서 키가 계속 눌러진 상태인지는 +128의 시그널 발생 여부로 판단 할 수 있다. 이는 어플리케이션의 구현방법마다 다르다. 게임에서 방향키를 계속 누르고 있으면 끊김 없이 이동하는 반면 워드나 메모장에서 키를 누르고 있으면 잠시 끊겼다가 입력되는게 그 예이다.
키보드는 I/O장치로 시스템 버스를 통해 시그널이 전달된다. 시스템 버스로 전달된다. 이 부분은 소프트웨어 폴링, 하드웨어 폴링 등 구현 방법에 따라 다른데, 일반적으로 TEST I/O(IRA) 선을 통해 전달된다.
CPU는 Execute 명령이 끝날 때마다, 인터럽트 신호를 확인함으로 이 때 키보드에서 발생된 시그널을 확인하게 된다. 이 시그널에는 Keyboard I/O 번호(1번)와 Scan Code가 담겨 있다.
인터럽트 신호를 확인한 CPU는 현재 정보들을 Stack에 저장한다. 이를 Context Switching 이라 한다. 이 후 Interrupt Service Routine(ISR)에게 제어권을 넘겨준다.
ISR에서는 Interrupt Vector를 확인하는데, 여기에는 인터럽트 번호와 해당 인터럽트를 처리할 핸들러의 주소가 Key-Value 형태로 저장되어 있다. 여기에 저장된 핸들러 주소로 점프해서 키보드 인터럽트가 수행된다.
인터럽트를 수행 중에 다른 인터럽트가 발생 했을 때의 처리는 인터럽트마다 다르다. 다른 인터럽트 발생을 막을러면 인터럽트 시작시에 다른 인터럽트가 끼어들지 못하게 인터럽트 금지 비트를 셋한다.
키보드 인터럽트에서는 ScanCode를 ASCII Code로 변환해서 버퍼에 저장한다.
Caps Lock이나 Shift 같은 특수키는 버퍼에 저장하지 않고 상태 비트를 바꾸는 역할만 한다. 즉 모든 키들이 버퍼에 저장되는 것은 아니다.
이후 원래의 프로세스로 복귀한다. 키보드 시그널이 필요한 프로세스는 Queue에 저장된 ASCII Code를 가져와 로직을 수행한다.