리눅스에서 인터럽트는 어떻게 처리됩니까?


35

난 그냥 아는 InterruptA는 hardware signal assertion프로세서 핀에서 발생. 그러나 Linux OS가 어떻게 처리하는지 알고 싶습니다.
인터럽트가 발생할 때 어떤 일이 발생합니까?


tldp.org/LDP/tlk/dd/interrupts.html 당신 이 요청한 질문에 대한 모든 것을 설명합니다
John

답변:


40

다음은 저수준 처리에 대한 높은 수준의 견해입니다. 간단한 전형적인 아키텍처를 설명하고 있습니다. 실제 아키텍처는이 수준에서 중요하지 않은 방식으로 더 복잡하거나 다를 수 있습니다.

인터럽트가 발생하는 인터럽트를 마스크하는 경우, 프로세서 보인다. 이러한 경우 마스크를 해제 할 때까지 아무 일도 일어나지 않습니다. 인터럽트가 마스크 해제 될 때 보류중인 인터럽트가 있으면 프로세서가 하나를 선택합니다.

그런 다음 프로세서는 메모리의 특정 주소로 분기하여 인터럽트를 실행합니다. 해당 주소의 코드를 인터럽트 핸들러 라고 합니다 . 프로세서가 거기서 분기하면 인터럽트를 마스킹 (인터럽트 핸들러는 독점 제어 할 수 있음)하고 일부 레지스터의 내용을 특정 위치 (일반적으로 다른 레지스터)에 저장합니다.

인터럽트 핸들러는 일반적으로 데이터를 보내거나 받기 위해 인터럽트를 트리거 한 주변 장치와 통신하여 수행해야하는 작업을 수행합니다. 타이머에 의해 인터럽트가 발생한 경우 핸들러는 OS 스케줄러를 트리거하여 다른 스레드로 전환 할 수 있습니다. 핸들러가 실행을 마치면 저장된 레지스터를 복원하고 인터럽트를 마스크 해제하는 특수한 인터럽트에서 리턴 명령을 실행합니다.

인터럽트 처리기는 다른 인터럽트가 실행되지 않도록하기 때문에 빠르게 실행해야합니다. Linux 커널에서 인터럽트 처리는 두 부분으로 나뉩니다.

  • "상반부"는 인터럽트 핸들러입니다. 필요한 최소한의 작업을 수행하며 일반적으로 하드웨어와 통신하고 커널 메모리의 어딘가에 플래그를 설정합니다.
  • "하단"은 데이터를 프로세스 메모리에 복사, 커널 데이터 구조 업데이트 등과 같은 다른 필요한 처리를 수행합니다. 인터럽트가 활성화 된 상태에서 실행되기 때문에 시스템의 다른 부분을 기다리는 데 시간이 걸리고 심지어는 차단할 수도 있습니다.

이 주제에서 평소와 같이 자세한 정보는 Linux 장치 드라이버를 읽으십시오 . 10 장은 인터럽트에 관한 것입니다.


22

Gilles는 이미 인터럽트의 일반적인 경우에 대해 설명 했으며, 다음은 Intel 아키텍처의 Linux 2.6에만 적용됩니다 (이 부분은 Intel 사양을 기반으로 함).

인터럽트는 프로세서가 실행하는 명령 순서를 변경하는 이벤트입니다.
인터럽트에는 두 가지 종류가 있습니다 :

  • 명령어를 처리하는 동안 CPU에서 생성 된 동기 인터럽트 (예외)
  • 다른 하드웨어 장치에서 발행 한 비동기 인터럽트 (인터럽트)

커널에서 처리해야하는 프로그래밍 오류 (fe Divide error , Page Fault , Overflow ) 로 인해 예외가 발생 합니다. 그는 프로그램에 신호를 보내고 오류를 복구하려고 시도합니다.

다음 두 가지 예외가 분류됩니다.

  • 비정상 조건을 감지하는 동안 CPU에서 생성 된 프로세서 감지 예외 . 세 그룹으로 나누어 : 오류는 일반적으로 수정 될 수있다, 트랩 , 실행보고 가 취소가 심각한 오류입니다.
  • 프로그래머가 요청한 프로그래밍 된 예외 는 트랩처럼 처리됩니다.

I / O 장치 (키보드, 네트워크 어댑터, ..), 인터벌 타이머 및 (다중 프로세서 시스템의) 다른 CPU에 의해 인터럽트가 발생할 수 있습니다. 인터럽트가 발생하면 CPU는 현재 명령을 중지하고 새로 도착한 인터럽트를 실행해야합니다. 그는 인터럽트가 처리 된 후 이전 프로세스 상태를 저장하여 (아마도) 재개해야합니다.

인터럽트 처리는 중요한 작업입니다.

  • 인터럽트는 언제든지 발생할 수 있으며 커널은 가능한 빨리 중단을 시도합니다.
  • 다른 인터럽트로 인터럽트를 인터럽트 할 수 있습니다
  • 커널에 전혀 중단되어서는 안되는 영역이 있습니다

두 가지 다른 인터럽트 레벨이 정의됩니다.

  • I / O 장치에서 발생한 마스킹 가능한 인터럽트 마스크 또는 마스크 해제 상태의 두 가지 상태 일 수 있습니다. 마스크되지 않은 인터럽트 만 처리됩니다.
  • 마스크 불가능 인터럽트 ; 중대한 오작동 (하드웨어 고장); 항상 CPU에 의해 처리됩니다.

모든 하드웨어 장치에는 자체 IRQ (Interrupt Request) 라인이 있습니다. IRQ는 0부터 시작하여 번호가 매겨집니다. 모든 IRQ 라인은 PIC (Programmable Interrupt Controller)에 연결됩니다. PIC는 IRQ를 수신하여 CPU에 할당합니다. 특정 IRQ 회선을 비활성화 할 수도 있습니다.
최신 멀티 프로세싱 Linux 시스템에는 일반적으로 CPU간에 IRQ 요청을 균등하게 분배하는 최신 API (API)가 포함되어 있습니다.

인터럽트 또는 예외와 처리 사이의 중간 단계는 IDT (Interrupt Descriptor Table)입니다. 이 테이블은 각 인터럽트 또는 예외 벡터 (숫자)를 지정된 핸들러와 연관시킵니다 (fe 나누기 오류 가 함수에 의해 처리됨 divide_error()).

커널은 IDT를 통해 발생한 인터럽트 또는 예외를 처리하는 방법을 정확하게 알고 있습니다.


그렇다면 인터럽트가 발생할 때 커널은 무엇을 하는가?

  • CPU는 (A) PIC에서 IRQ가 있는지 각 명령 후에 확인합니다.
  • 그렇다면 IDT를 참조하여 수신 된 벡터를 함수에 매핑하십시오.
  • 승인 된 소스에서 인터럽트를 발행했는지 확인
  • 중단 된 프로세스의 레지스터를 저장합니다
  • 인터럽트를 처리하기 위해 해당 함수를 호출
  • 중단 된 프로세스의 최근에 저장된 레지스터를로드하고 다시 시작하십시오.

당신은 명확 수 "는 (A) PIC에서 IRQ가 있다면 각 명령 후 CPU 검사" . 정확히 어떻게 발생합니까? VIP플래그 레지스터의 -flag 와 관련이 있습니까? 미리 감사드립니다
red0ct

7

인터럽트 처리에 관련된 모든 참가자는 우선 주변 하드웨어 장치, 인터럽트 컨트롤러, CPU, 운영 체제 커널 및 드라이버입니다. 주변 하드웨어 장치는 인터럽트 생성을 담당합니다. 그들은 운영 체제 커널의 관심을 끌 때 인터럽트 요청 라인을 주장합니다. 이 신호는 인터럽트 컨트롤러에 의해 다중화되어 인터럽트 신호 수집을 담당합니다. 또한 인터럽트 신호가 CPU로 전달되는 순서를 결정합니다. 인터럽트 컨트롤러는 특정 인터럽트 요청 라인 (IRQL)을 일시적으로 비활성화하고 다시 활성화 할 수 있습니다 (IRQL 마스킹). 인터럽트 컨트롤러는 수집 된 인터럽트 요청을 CPU에 순차적으로 전달합니다. 각 명령어 실행이 완료된 후 CPU CPU는 인터럽트 컨트롤러로부터 대기중인 인터럽트 요청이 있는지 확인합니다. CPU가 대기 요청이 있고 내부 CPU 제어 레지스터에 인터럽트 활성화 플래그가 설정되어 있으면 CPU가 인터럽트 처리를 시작합니다. 보다시피, 리눅스 커널은 CPU의 인터럽트 플래그를 조작하고 인터럽트 컨트롤러와 통신함으로써 인터럽트 수용을 제어 할 수 있습니다. 예를 들어, Linux는 특정 장치의 인터럽트 수락을 비활성화하거나 인터럽트 수락을 비활성화 할 수 있습니다. 리눅스 커널은 인터럽트 수용을 제어 할 수 있습니다. 예를 들어, Linux는 특정 장치의 인터럽트 수락을 비활성화하거나 인터럽트 수락을 비활성화 할 수 있습니다. 리눅스 커널은 인터럽트 수용을 제어 할 수 있습니다. 예를 들어, Linux는 특정 장치의 인터럽트 수락을 비활성화하거나 인터럽트 수락을 비활성화 할 수 있습니다.

프로세서가 인터럽트 요청을 받으면 어떻게됩니까? 첫째, CPU는 인터럽트 플래그를 재설정하여 인터럽트를 자동으로 비활성화합니다. 인터럽트 처리가 완료되면 다시 활성화됩니다. 동시에 CPU는 인터럽트 된 코드의 실행을 재개 할 수있는 방식으로 CPU를 사용자 모드에서 커널 모드로 전환하는 데 필요한 최소한의 작업을 수행합니다. CPU는 Linux 커널로 채워진 특수 CPU 제어 구조를 참조하여 제어가 전달 될 코드 주소를 찾습니다. 이 주소는 Linux 커널의 일부인 인터럽트 핸들러의 첫 번째 명령어 주소입니다.

인터럽트 처리의 첫 단계로 커널은 어떤 종류의 이벤트가 시스템에서 발생했는지 식별하기 위해 수신 된 인터럽트 벡터를 식별합니다. 인터럽트 벡터는 리눅스가 처리하는 작업을 정의합니다. 두 번째 단계로 Linux는 CPU에 의해 자동으로 저장되지 않은 나머지 CPU 레지스터를 저장하고 잠재적으로 중단 된 프로그램에 의해 사용될 수 있습니다. 이것은 Linux가 인터럽트 된 프로그램과 투명하게 관련하여 인터럽트를 처리 할 수있게 해주기 때문에 매우 중요한 조치입니다. 세 번째 단계로 Linux는 커널 환경을 설정하고 필요한 CPU 상태를 설정하여 커널 모드로 전환합니다. 마지막으로 벡터 종속 인터럽트 핸들러가 호출됩니다. arch \ x86 \ kernel \ entry_32에서 BUILD_INTERRUPT3 매크로를 볼 수 있습니다. S는 x86 아키텍처 관련 예제에 대한 추가 정보를 얻습니다.) 주변 장치의 경우 do_IRQ () 루틴입니다. (아치 \ x86 \ kernel \ irq.c를 살펴보십시오)

벡터 종속 인터럽트 핸들러는 일반적으로 irq_enter () 및 irq_exit () 호출에 의해 랩핑됩니다. 이러한 기능의 쌍으로 둘러싸인 코드 영역은 다른 영역과 관련하여 원 자성이며 ​​cli / sti 쌍에 대해서는 원 자성입니다. Irq_enter () 및 irq_exit ()는 인터럽트 처리와 관련된 일부 통계도 캡처합니다. 마지막으로, 커널은 vector_irq 테이블을보고 수신 된 인터럽트의 벡터에 할당 된 irq 번호를 찾고 handle_irq ()를 호출합니다 (arch \ x86 \ kernel \ irq_32.c에서).

이 시점에서 커널은 irq 디스크립터의 일부로 장치 드라이버에 의해 설치된 장치 종속 인터럽트 핸들러 루틴을보고 호출하기 때문에 Linux에서 인터럽트 처리의 공통 부분이 종료됩니다. 이러한 핸들러가 드라이버에 의해 설치되지 않은 경우 커널은 인터럽트 컨트롤러의 인터럽트를 승인하고 일반 인터럽트 핸들러를 종료합니다.

인터럽트 처리 종료 후 커널은 이전에 중단 된 프로그램의 상태를 복원하고이 프로그램 실행을 재개합니다.


CPU consults with special CPU control structures filled by Linux kernel to find an address of code to which control will be passed.예! 나는 그 특별한 제어 구조가 무엇인지 궁금합니다 ...
automaton

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