2026. 3. 26. 11:13ㆍ운영체제(OS)
입출력 프로그래밍 — I/O가 CPU를 기다리지 않는 이유
CPU와 입출력 장치 사이의 속도 차이를 극복하기 위해 OS가 어떤 방식으로 I/O를 처리하는지, 폴링부터 DMA·채널·스풀링까지의 구조를 정리한다.
1. BIOS — 컴퓨터가 켜질 때 가장 먼저 실행되는 것
BIOS1는 컴퓨터 전원을 켜면 운영체제보다 먼저 실행되는 프로그램이다. ROM에 저장되어 있고, 다른 말로 펌웨어2라고도 부른다. 모든 소프트웨어는 BIOS를 기반으로 실행되기 때문에, 시스템 전체의 첫 번째 관문이라고 볼 수 있다.
BIOS는 세 가지 루틴으로 구성된다. 첫 번째 스타트업 루틴은 전원이 켜지면 자동으로 실행되며, POST3를 수행하고 주변 장치 연결을 확인한다. 두 번째 서비스 처리 루틴은 화면 출력·디스크 읽기 같은 OS나 사용자 요청을 처리한다. 세 번째 하드웨어 인터럽트 처리 루틴은 특정 사건 발생 시 현재 프로그램을 중단하고 대응한 뒤 다시 복귀시키는 역할을 한다.
부팅 순서 (Windows 기준)
전원이 공급되면 ROM에서 BIOS가 기동하고, 이후 아래 순서로 진행된다.
Loader 검사
부팅이 완료되면 운영체제가 컴퓨터 시스템의 전체적인 운영권을 갖는다. Bootstrap Loader는 ROM에 저장된 BIOS가 커널을 RAM으로 올리기 위한 중간 역할을 담당한다.
2. 입출력 방식 — 직접제어 vs 간접제어
I/O 방식은 크게 CPU가 직접 개입하느냐 아니냐로 나뉜다. 직접제어방식은 이동되는 모든 데이터가 반드시 CPU를 거치며, 간접제어방식은 전용 장치가 CPU 대신 I/O를 처리한다.
직접제어 — 폴링(Polling)과 인터럽트
가장 단순한 방식은 폴링(Polling)이다. CPU가 I/O 장치의 상태를 직접 계속 확인하는 방식으로, CPU 시간이 낭비되고 I/O 동안 다른 작업을 전혀 할 수 없다. 반면 인터럽트 방식은 I/O가 완료됐을 때 장치가 CPU에 신호를 보내므로, 그 동안 CPU는 다른 작업을 수행할 수 있다.
→ I/O 동안 CPU 점유
→ 다른 작업 불가
→ CPU 시간 낭비
→ CPU는 다른 작업 수행
→ 완료 알림 수신 후 처리
→ 효율적
간접제어 — DMA와 채널
DMA5(Direct Memory Access)는 CPU를 거치지 않고 메모리와 주변장치가 직접 데이터를 주고받는 방식이다. CPU는 DMA에게 주소, 전송 방향, 전송량만 알려주면 되고, 나머지는 DMA 컨트롤러가 처리한다. 전송이 완료되면 DMA가 CPU에 인터럽트를 발생시켜 완료를 알린다.
DMA가 버스를 사용하는 동안 CPU가 버스에 접근해야 할 경우, 사이클 스틸링6(Cycle Stealing)이 발생한다. DMA가 CPU의 버스 사용권을 잠깐 빌려 1바이트씩 전송하고 반납하는 방식이다. 인터럽트와 달리 CPU 상태 보존이 필요하지 않다는 점이 특징이다.
0x1000, 방향 READ, 크기 4KB — 처리해줘"채널(Channel)7은 DMA보다 더 발전된 형태로, 독자적인 채널 프로그램을 실행할 수 있는 전용 입출력 처리 장치다. 주기억장치와 입출력장치 사이에 위치하며, CPU의 개입 없이 여러 블록을 한 번에 처리할 수 있다. 선택 채널(한 번에 하나의 I/O 장치)과 다중화 채널(여러 장치 동시 제어)로 나뉜다. DMA는 주로 PC에서, 채널 방식은 대형 서버에서 사용된다.
| 방식 | CPU 개입 | 처리 단위 | 주 사용처 |
|---|---|---|---|
| 폴링 | 전체 감시 | 바이트 | 단순 임베디드 |
| 인터럽트 | 완료 시만 | 바이트 | 일반 I/O |
| DMA | 시작/끝만 | 블록 | PC |
| 채널 | 거의 없음 | 여러 블록 | 대형 서버 |
3. 버퍼링과 스풀링 — 속도 차이를 극복하는 두 가지 방법
CPU는 I/O 장치보다 압도적으로 빠르다. 이 속도 차이를 보완하는 기법이 버퍼링8(Buffering)과 스풀링9(SPOOLing)이다.
버퍼링은 CPU에서 처리된 데이터를 주기억장치의 임시 공간(버퍼)에 저장해 두고, 채널이 이를 읽어 I/O 장치로 전송하는 방식이다. CPU와 입출력을 동시에 수행하기 위한 기법이며, 하드웨어적으로 구현된다. 대표적인 예가 프린터의 경우로, 프린터 자체 RAM에 데이터를 버퍼링한 뒤 자신의 속도에 맞춰 출력한다.
스풀링은 더 나아가 하드디스크를 거대한 버퍼처럼 사용하는 방식이다. 프린터로 출력할 데이터를 디스크의 스풀 공간에 임시 저장하고, CPU는 바로 다음 작업으로 넘어간다. 소프트웨어적으로 구현되며, 여러 사용자가 동시에 프린터 요청을 보낼 수 있는 다중 사용자 환경에 적합하다.
| 항목 | 버퍼링 | 스풀링 |
|---|---|---|
| 구현 방식 | 하드웨어 | 소프트웨어 |
| 중복 범위 | 한 작업의 입출력+연산 | 여러 작업의 입출력+연산 |
| 입력 방식 | 스택/큐 | 큐 |
| 사용자 | 단일 | 다중 |
| 저장 위치 | 주기억장치 | 하드디스크 |
4. 인터럽트 방식 — 예외 처리의 기반 메커니즘
인터럽트는 예기치 않은 사건이 발생했을 때 CPU에게 알려 제어 흐름을 변경하는 메커니즘이다. 실행 중인 프로그램이 아닌 외부 요인에 의해 제어 흐름이 바뀐다는 점이 핵심이다. 인터럽트 처리가 끝나면 원래 프로그램으로 복귀한다.
인터럽트의 종류는 재시작, 기계착오, 외부(신호), 입출력, 프로그램 검사, 슈퍼바이저 콜(SVC) 여섯 가지다. SVC는 사용자 프로그램이 OS의 기능을 요청할 때 사용되는 소프트웨어 인터럽트로, 시스템 콜의 하드웨어 구현이라고 볼 수 있다.
인터럽트 우선순위 결정 방식
여러 인터럽트가 동시에 발생하면 우선순위를 결정해야 한다. 소프트웨어 방식인 폴링은 우선순위가 높은 순서대로 플래그를 검사하는 방식이라 유연하지만 반응이 느리다. 하드웨어 방식은 빠르지만 추가 회로가 필요하다.
| 방식 | 응답 속도 | 우선순위 변경 | 비용 |
|---|---|---|---|
| 폴링 (SW) | 느림 | 쉬움 | 경제적 |
| 데이지 체인 (HW) | 빠름 | 어려움 | 비경제적 |
| 병렬 방식 (HW) | 가장 빠름 | 마스크 레지스터로 제어 | 가장 비쌈 |
데이지 체인은 장치들을 CPU에서 직렬로 연결하며, CPU와 가까울수록 우선순위가 높다. 병렬 방식은 각 장치가 CPU에 개별 회선으로 연결되고, 마스크 레지스터의 비트 위치로 우선순위를 제어한다.
5. 현대 I/O의 변화
교재에서 다루는 I/O 구조는 HDD 중심의 SATA 시대를 배경으로 한다. 현재는 저장장치 패러다임이 NVMe SSD(M.2 PCIe)로 전환됐다. NVMe는 PCIe 버스를 직접 사용하기 때문에 DMA 전송 효율이 압도적으로 높고, 기존 SATA 대비 I/O 지연이 수십 배 단축된다.
// Polling 방식
while (!device.isReady()) { } // CPU 점유
device.read(buffer);
// io_uring — 제출 큐에 요청 등록
io_uring_sqe_set_data(sqe, &request);
io_uring_submit(&ring);
// CPU는 다른 작업 수행
// 완료 큐에서 결과 수집
io_uring_wait_cqe(&ring, &cqe);
또한 DMA 보안 측면도 중요해졌다. DMA는 CPU를 거치지 않기 때문에 요청의 유효성을 검증할 수단이 없어 보안 위협에 노출될 수 있다. 이를 막기 위해 현대 시스템에서는 IOMMU를 통해 DMA가 접근 가능한 메모리 영역을 제한한다.
📎 용어 설명
- BIOS (Basic Input Output System) — 컴퓨터 전원 시 가장 먼저 실행되는 펌웨어. ROM에 저장되어 하드웨어 초기화와 OS 부팅을 담당한다.
- 펌웨어 (Firmware) — 하드웨어에 내장된 소프트웨어. ROM과 같은 비휘발성 메모리에 저장되어 하드웨어를 제어하는 저수준 프로그램.
- POST (Power-On Self-Test) — 컴퓨터 전원 시 BIOS가 수행하는 자가 진단 프로그램. CPU, 메모리, 그래픽 카드 등 주변 장치 이상을 점검한다.
- UEFI (Unified Extensible Firmware Interface) — 레거시 BIOS를 대체하는 현대 펌웨어 인터페이스. GPT 파티션 방식과 Secure Boot를 지원한다.
- DMA (Direct Memory Access) — CPU를 거치지 않고 I/O 장치와 주기억장치가 직접 데이터를 전송하는 방식. DMA 컨트롤러가 전송을 관리한다.
- 사이클 스틸링 (Cycle Stealing) — DMA가 CPU의 버스 사용 사이클을 일시적으로 빌려 데이터를 전송하는 기법. CPU 상태 보존이 필요 없다.
- 채널 (Channel) — DMA를 확장한 전용 입출력 처리 장치. 독자적인 채널 프로그램을 실행하며 CPU 개입 없이 여러 블록의 I/O를 처리한다.
- 버퍼링 (Buffering) — CPU와 I/O 장치의 속도 차이를 보완하기 위해 임시 기억공간(버퍼)에 데이터를 저장해 처리하는 기법. 하드웨어적으로 구현.
- 스풀링 (SPOOLing, Simultaneous Peripheral Operation On-Line) — 디스크를 스풀 공간으로 사용해 여러 작업의 I/O와 연산을 동시에 처리하는 소프트웨어 기법.
'운영체제(OS)' 카테고리의 다른 글
| [OS] 메모리 단편화(Fragmentation)와 배치 전략 - 12 (0) | 2026.04.03 |
|---|---|
| [OS] 기억장치 개요와 주기억장치 할당 기법 - 11 (0) | 2026.03.27 |
| [OS] 동기화 기법과 교착 상태 - 9 (0) | 2026.03.17 |
| [OS] 병행 프로세스, 임계구역, 상호배제 - 8 (0) | 2026.03.17 |
| [OS] CPU 스케줄링 - 7 (0) | 2026.03.12 |