HW, SW 인터럽트에 대해 설명해 주세요.
인터럽트는 발생 원인에 따라 CPU 외부 장치가 발생시키는 하드웨어 인터럽트와 프로그램 내부에서 발생하는 소프트웨어 인터럽트로 나뉩니다.
한눈에 비교
| 항목 | 하드웨어 인터럽트 | 소프트웨어 인터럽트 |
| 발생 주체 | CPU 외부 하드웨어 장치 | 프로그램 내부 명령어 |
| 동기/비동기 | 비동기적 (언제든 발생) | 동기적 (명령어 실행 시점) |
| 의도성 | 비의도적 (외부 이벤트) | 의도적(트랩) 또는 비의도적(예외) |
| 전달 경로 | 장치 → PIC/APIC → CPU INTR 핀 | 명령어 → CPU 직접 처리 |
| 예시 | 키보드 입력, 타이머, 디스크 완료 | 시스템 콜, 0으로 나누기, 페이지 폴트 |
| IF 플래그 영향 | 마스커블은 IF=0이면 무시됨 | IF와 무관하게 처리 |
전체 분류 체계
인터럽트
│
├── 하드웨어 인터럽트 (외부, 비동기)
│ │
│ ├── 마스커블 (Maskable)
│ │ - CLI 명령으로 비활성화 가능
│ │ - 키보드, 마우스, 디스크, NIC, 타이머
│ │
│ └── 논마스커블 (NMI)
│ - 비활성화 불가능
│ - 전원 이상, 메모리 패리티 오류, 하드웨어 고장
│
└── 소프트웨어 인터럽트 (내부, 동기)
│
├── 트랩 (Trap) — 의도적
│ - 시스템 콜 (int 0x80, syscall)
│ - 디버그 브레이크포인트 (int 3)
│
└── 예외 (Exception) — 비의도적
├── Fault — 복구 후 같은 명령어 재실행 (페이지 폴트)
├── Trap — 다음 명령어로 진행 (오버플로우)
└── Abort — 복구 불가 (Double Fault)
하드웨어 인터럽트 (HW Interrupt)
특징
| 항목 | 내용 |
| 발생 원인 | 외부 장치에서 이벤트 발생 |
| 전달 경로 | 장치 → IRQ → 인터럽트 컨트롤러(PIC/APIC) → CPU |
| 비동기적 | 현재 실행 중인 프로그램과 무관하게 언제든 발생 |
| 처리 구조 | Top Half (긴급) + Bottom Half (지연) |
처리 흐름
장치 이벤트 발생 (예: 키보드 'A' 입력)
│
▼
키보드 컨트롤러 → IRQ1 → 인터럽트 컨트롤러(APIC)
│
▼
APIC: 우선순위 판단 → CPU INTR 핀에 신호 + 벡터 번호(33) 전달
│
▼
CPU: 현재 명령어 완료 → IF 확인 → 상태 저장
│
▼
IDT[33] → 키보드 ISR 주소 조회
│
▼
커널 모드 전환 → ISR 실행
│
├── [Top Half] 스캔 코드 읽기, 버퍼 저장
└── [Bottom Half] 문자 변환, 프로세스 깨우기
│
▼
EOI 전송 → 상태 복원 → iret → 사용자 모드 복귀
마스커블 vs 논마스커블
| 항목 | 마스커블 (Maskable) | 논마스커블 (NMI) |
| 비활성화 | 가능 (cli 명령) | 불가능 |
| CPU 핀 | INTR | NMI |
| 용도 | 일반 I/O 장치 | 치명적 오류 |
| 예시 | 키보드, 디스크, NIC, 타이머 | 전원 이상, 메모리 패리티 오류 |
| IF 플래그 | IF=0이면 무시됨 | IF와 무관하게 항상 처리 |
[마스커블]
cli 실행 (IF=0)
→ 키보드 인터럽트 발생 → 보류 (IF=0이므로)
sti 실행 (IF=1)
→ 보류된 인터럽트 처리
[논마스커블]
cli 실행 (IF=0)
→ 전원 이상 NMI 발생 → 즉시 처리 (IF 무관)
대표적인 하드웨어 인터럽트
| IRQ | 장치 | 벡터 | 용도 |
| 0 | 타이머 | 32 | 프로세스 스케줄링, 시간 관리 |
| 1 | 키보드 | 33 | 키 입력 감지 |
| 8 | RTC | 40 | 실시간 시계 |
| 11 | NIC | 43 | 네트워크 패킷 수신 |
| 12 | PS/2 마우스 | 44 | 마우스 입력 |
| 14 | Primary IDE | 46 | 디스크 I/O 완료 |
소프트웨어 인터럽트 (SW Interrupt)
특징
| 항목 | 내용 |
| 발생 원인 | 프로그램 내부 명령어 실행 또는 CPU가 오류 감지 |
| 전달 경로 | CPU가 직접 감지, 인터럽트 컨트롤러 불필요 |
| 동기적 | 특정 명령어 실행 시점에 정확히 발생 |
| IF 무관 | IF 플래그와 무관하게 항상 처리 |
트랩 (Trap) — 의도적
프로그래머가 명시적으로 커널 기능을 요청할 때 발생합니다.
사용자 프로그램: read(fd, buf, size) 호출
│
▼
glibc: RAX = 0 (시스템 콜 번호) 세팅
│
▼
syscall 명령어 실행 → 트랩 발생
│
▼
CPU: 상태 저장 → 커널 모드 전환
│
▼
시스템 콜 디스패처: sys_call_table[0] → sys_read() 실행
│
▼
완료 → RAX에 결과 → sysret → 사용자 모드 복귀
| 트랩 명령어 | 용도 |
int 0x80 | Linux 시스템 콜 (32비트, 레거시) |
syscall | Linux 시스템 콜 (64비트, 현대) |
sysenter | Windows/Intel 시스템 콜 |
int 3 | 디버그 브레이크포인트 |
예외 (Exception) — 비의도적
프로그램 실행 중 CPU가 비정상 상황을 감지할 때 발생합니다.
프로그램: int result = 10 / 0;
│
▼
CPU: 나누기 명령 실행 → 제수가 0 감지
│
▼
Divide Error 예외 발생 (벡터 0)
│
▼
IDT[0] → Divide Error 핸들러 실행
│
▼
커널: 프로세스에 SIGFPE 시그널 전송 → 프로세스 종료 또는 처리
| 분류 | 설명 | 복귀 지점 | 예시 |
| Fault | 복구 가능, 원인 해결 후 재실행 | 같은 명령어 | 페이지 폴트 |
| Trap | 정상 처리 후 다음으로 진행 | 다음 명령어 | 오버플로우, 브레이크포인트 |
| Abort | 복구 불가능한 심각한 오류 | 복귀 불가 | Double Fault |
처리 과정 비교
[하드웨어 인터럽트]
장치 → IRQ → APIC → CPU INTR 핀
→ 상태 저장 → IDT 조회 → ISR 실행
→ EOI 전송 → 상태 복원 → iret
[소프트웨어 인터럽트 — 트랩]
프로그램 → syscall 명령어 → CPU 직접 처리
→ 상태 저장 (RCX, R11) → 커널 진입
→ sys_call_table 조회 → 커널 함수 실행
→ sysret → 복귀
[소프트웨어 인터럽트 — 예외]
명령어 실행 중 오류 → CPU가 감지
→ 상태 저장 + Error Code → IDT 조회
→ 예외 핸들러 실행
→ Fault: 같은 명령어 재실행 / Abort: 프로세스 종료
| 처리 단계 | HW 인터럽트 | SW 인터럽트 (트랩) | SW 인터럽트 (예외) |
| 발생 | 장치 → APIC → CPU | syscall 명령어 | CPU가 오류 감지 |
| 인터럽트 컨트롤러 | 필요 (APIC) | 불필요 | 불필요 |
| 상태 저장 | 커널 스택에 자동 | RCX, R11에 저장 | 커널 스택 + Error Code |
| 핸들러 조회 | IDT[벡터] | MSR 기반 진입점 | IDT[벡터] |
| EOI | 필요 | 불필요 | 불필요 |
| 복귀 명령 | iret | sysret | iret |
Java에서 HW / SW 인터럽트 발생 상황
// ═══ 소프트웨어 인터럽트 (트랩 — 시스템 콜) ═══
System.out.println("hello"); // write() 시스템 콜
new FileInputStream("data.txt"); // open() 시스템 콜
new Socket("example.com", 80); // socket() + connect()
new Thread(() -> {}).start(); // clone() 시스템 콜
Thread.sleep(1000); // nanosleep() 시스템 콜
// ═══ 소프트웨어 인터럽트 (예외) ═══
int result = 10 / 0; // Divide Error (벡터 0)
// → ArithmeticException
Object obj = null;
obj.toString(); // GPF/SIGSEGV (벡터 13/14)
// → NullPointerException
byte[] huge = new byte[100_000_000];
huge[0] = 1; // Page Fault (벡터 14)
// → 커널이 물리 페이지 할당
// ═══ 하드웨어 인터럽트 ═══
Scanner sc = new Scanner(System.in);
sc.nextLine(); // 키 입력마다 IRQ1 (키보드)
Files.readAllBytes(Path.of("big.dat")); // 디스크 I/O 완료 시 IRQ14
// DMA 전송 완료 인터럽트
socket.getInputStream().read(); // 패킷 도착 시 IRQ11 (NIC)
Thread.sleep(1000); // 1초 후 타이머 인터럽트 (IRQ0)
// → 프로세스 깨움
Java 프로그램 실행 타임라인:
사용자 모드 ●━━━●━━━━━●━━━━●━━━━━━━━━━●━━━━━●
│ │ │ │ │
트랩 HW인터럽트 예외 HW인터럽트 트랩
(write) (키보드) (÷0) (디스크) (sleep)
│ │ │ │ │
커널 모드 ●━● ●━● ●━● ●━● ●━●
SW 인터럽트: 프로그램 흐름 안에서 동기적으로 발생
HW 인터럽트: 프로그램 흐름과 무관하게 비동기적으로 발생