floatFirstTOC: right
🖥️ 시작하며🔍 전형적인 PC Bus 구조🔍 커널의 I/O 구조🔍 I/O 디바이스📌 Block Device vs Character Device📌 Device controller (or host adapter)📌 I/O Hardware💡 헷갈릴 수 있는 부분 정리1️⃣ Direct I/O2️⃣ Memory-mapped I/O🔍 CPU가 I/O 요청 처리 여부를 아는 법📌 Polled I/O📌 Interrupt-driven I/O💡 부팅 과정에서 각 디바이스에 인터럽트 요청 번호(IRQ)가 할당됨🔍 I/O와 Main Memory 사이에서 데이터 이동📌 Programmed I/O (PIO)📌 Direct Memory Access (DMA)💡 DMA Transfer Six step💡 Blocking I/O vs Non-blocking I/O🔍 커널에서 I/O 소프트웨어의 목표🔍 디바이스 드라이버📌 디바이스 드라이버의 문제점1️⃣ 신뢰성 문제2️⃣ 디바이스 드라이버 확장의 증가3️⃣ OS 오류의 주요 원인📌 Device-Independent I/O SW1️⃣ Error Reporting2️⃣ Error Handling Strategies📌 User-Space I/O Software
🖥️ 시작하며
운영체제에서 디바이스의 특성, I/O가 어떻게 작동하는지에 대해 알아보려고 합니다.
🔍 전형적인 PC Bus 구조
🔍 커널의 I/O 구조
장치 컨트롤러는 입출력장치를 연결하기 위한 하드웨어적인 통로 장치 드라이버는 입출력장치를 연결하기 위한 소프트웨어적인 통로
🔍 I/O 디바이스
📌 Block Device vs Character Device
특성 | 블록 장치 (Block Device) | 문자 장치 (Character Device) |
정보 저장 방식 | 고정 크기 블록에 정보를 저장 | 문자 스트림을 전달하거나 수신 |
주소 지정 | 각 블록은 고유 주소를 가짐 | 주소 지정 불가 및 탐색(Seek) 연산 없음 |
블록 크기 | 블록당 512B - 32KB | 해당 없음 |
독립적인 블록 읽기/쓰기 | 각 블록을 다른 블록과 독립적으로 읽거나 쓸 수 있음
→ random한 seek가 가능 | 해당 없음 |
예시 장치 | 디스크(HDD, SSD), 테이프 등 | 프린터, 모뎀, 마우스, 키보드 등 |
- 요즘 Character Device도 USB로 연결하므로 보통은 block device이다.
📌 Device controller (or host adapter)
여러 장치를 처리할 수 있는 기능
- I/O 장치의 구성 요소에는 기계적 부분, 전자적 부분이 존재
- Electronic 부분에는 디바이스 컨트롤러가 포함됨
- 컨트롤러의 작업:
bit
데이터를bytes
로 변환- 메인 메모리에 사용 가능하게 함
- 필요에 따라 오류 수정 수행
📌 I/O Hardware
디바이스 컨트롤러는 레지스터나 버퍼를 가지고 있음
- 디바이스 드라이버:
- 명령 실행 후 레지스터에 커맨드, 주소 및 데이터를 쓰거나 읽을 수 있도록 배치
- 운영체제 커널 공간에 설치됨
- 주요 레지스터:
- 데이터 입력 레지스터 (Data-in register)
- 데이터 출력 레지스터 (Data-out register)
- 상태 레지스터 (Status register)
- 제어 레지스터 (Control register)
- 디바이스의 주소 지정 방법에는 두 가지가 존재: (명령과 데이터를 전송하는 방법)
- Direct I/O instructions (직접 I/O 명령어)
- Memory-mapped I/O (메모리 맵 I/O)
💡 헷갈릴 수 있는 부분 정리
항목 | 디바이스 (Device) | 디바이스 컨트롤러 (Device Controller) |
역할 | 실제 작업을 수행하는 물리적 장치 | 디바이스와 시스템 간의 인터페이스 역할을 수행 |
구성 요소 | 기계적 구성 요소, 전자적 구성 요소 | 전자적 구성 요소, 레지스터, 버퍼 등 |
주요 기능 | 데이터 입력/출력, 물리적 작업 수행 | 데이터를 처리하고 시스템 메모리와 디바이스 간의 데이터 전송 및 제어 명령 수행 |
레지스터 | 일부 디바이스는 자체적으로 레지스터를 가질 수 있음 | 디바이스와의 상호 작용을 위해 다양한 레지스터를 포함 |
데이터 처리 | 실제 데이터를 생성하거나 사용하는 작업 수행 | 데이터를 직렬 비트 스트림에서 바이트 블록으로 변환하고 오류 수정을 수행 |
통신 방식 | 디바이스 컨트롤러와 통신하여 명령을 받고 데이터를 전송 | 시스템과 디바이스 간의 통신을 관리 |
예시 | 디스크 드라이브, 프린터, 마우스 등 | 디스크 컨트롤러, 프린터 컨트롤러 등 |
1️⃣ Direct I/O
CPU를 만들 때부터 특정 I/O 포트 주소에 특별한 I/O 명령을 사용하는 방법
- 예시: (intel의 명령어)
명령어 | 설명 |
in | 포트에서 읽음 |
ins | 포트에서 문자열 입력 |
insb | 포트에서 바이트 문자열 입력 |
insl | 포트에서 더블워드 문자열 입력 |
insw | 포트에서 워드 문자열 입력 |
out | 포트에 씀 |
⚠️ 다른 디바이스에서 사용하려면 전부 바꿔야 한다는 단점이 존재
2️⃣ Memory-mapped I/O
디바이스 컨트롤러의 제어 레지스터를 프로세서의 주소 공간에 매핑
- CPU가 표준 데이터 전송 명령어를 사용해 I/O 요청을 실행할 수 있도록 함
- I/O 디바이스 드라이버를 C언어로 완전하게 작성 가능함
- 특별한 보호 메커니즘이 불필요
- 메모리에 매핑하므로 PTE를 통해서 이미 Protection bit가 존재함
- 필요한 페이지를 Page Table에 포함시킬 수 있음
- 특정 디바이스에 대한 제어를 사용자에게 제공 가능함
- 디바이스 레지스터를 읽고 그 값을 테스트하는 것을 단일 명령어로 가능
🔍 CPU가 I/O 요청 처리 여부를 아는 법
📌 Polled I/O
레지스터 bit를 CPU가 계속 체크해 디바이스 상태 확인
- 이점
- 구현 및 이해가 쉬움
- 소프트웨어가 언제든지 디바이스 상태를 확인하고 제어 가능
- 결과가 빨리 나오는 작업에는 효율적
- 단점
- CPU가 유휴 상태의 디바이스를 계속 Polling해야 하므로 비효율적
- 낮은 우선순위의 디바이스는 서비스되지 않을 수 있음 (Polling 빈도가 낮아져서)
📌 Interrupt-driven I/O
I/O 장치가 필요할 때 CPU에게 인터럽트를 요청
- 각 장치에 특화된 Interrupt service routines이 호출됨
- 여러 장치가 인터럽트를 공유할 수 있음
- 이점
- CPU가 필요한 경우에만 장치를 처리해 효율적
- 일반적으로는 Polling보다 더 효율적
- 단점
- 과도한 인터럽트는 프로그램 실행을 느리게 함
- 오버헤드 발생 (작은 일에 대해서 계속 인터럽트 시, 바이트마다 등등)
💡 부팅 과정에서 각 디바이스에 인터럽트 요청 번호(IRQ)가 할당됨
🔍 I/O와 Main Memory 사이에서 데이터 이동
📌 Programmed I/O (PIO)
CPU가 I/O 장치와 메모리 간의 데이터 전송에 직접 관여
- 특징:
- 특별한 I/O 명령 이나 메모리 맵드 I/O를 사용
- 장단점:
- 장점: 구현이 간단하고 제어가 쉬움
- 단점: CPU가 직접 데이터를 전송하기 때문에 효율이 낮고, CPU 시간이 많이 소모됨
항목 | 특별한 I/O 명령어 (Special I/O Instructions) | 메모리 맵드 I/O (Memory-mapped I/O) |
데이터 전송 방식 | CPU가 특별한 I/O 명령어( in , out )를 사용하여 데이터 전송 | CPU가 메모리 접근 명령어( mov , ld , st 등)를 사용하여 데이터 전송 |
I/O 포트 접근 | I/O 포트 주소를 통해 접근 | 메모리 주소 공간의 일부로 매핑된 I/O 레지스터에 접근 |
명령어 예시 | in , out | mov , ld , st |
사용 예시 | 특정 I/O 포트에 대한 직접 접근 | 메모리 주소를 통해 I/O 레지스터에 접근 |
📌 Direct Memory Access (DMA)
고속 I/O장치를 위해 CPU의 개입 없이 디바이스 컨트롤러가 데이터를 직접 메모리에 전송
- 특징:
- 고속 데이터 전송: 메모리 속도에 가까운 속도로 데이터 전송 가능
- 블록 전송: 장치 컨트롤러가 버퍼 저장소에서 주 메모리로 데이터를 블록 단위로 전송
- CPU 개입 없음: CPU의 개입 없이 데이터 전송, 블록 전송 후 인터럽트만 발생
- 장단점:
- 장점: CPU가 데이터 전송에 관여하지 않아 효율이 높고, CPU가 다른 작업을 수행할 수 있음
- 단점: 구현이 복잡하며, 하드웨어 지원이 필요함
💡 DMA Transfer Six step
💡 Blocking I/O vs Non-blocking I/O
항목 | Blocking I/O (일반적) | Non-blocking I/O (네트워크 등) |
특징 | 프로세스가 I/O 완료까지 대기 | I/O 호출이 즉시 반환되며, 전송된 바이트 수 반환 |
주요 함수 | read() , write() | select() |
장점 | 사용 및 구현이 쉽고 직관적 | CPU 자원을 효율적으로 사용 가능, 여러 I/O 작업 동시 처리 가능 |
단점 | CPU 자원 비효율적 사용 가능성, 동시 처리 어려움 | 구현이 복잡하고, 완료 상태를 지속적으로 확인해야 함 |
🔍 커널에서 I/O 소프트웨어의 목표
- Device Independence (디바이스 독립성)
프로그램이 특정 디바이스에 종속되지 않도록 함. (open, read 시 알아서 다 동작하도록)
- Uniform Naming (일관된 이름 지정)
- Error Handling (오류 처리)
- Synchronous vs Asynchronous (동기 vs 비동기)
- Buffering (버퍼링)
- Sharable vs Dedicated Devices (공유 가능한 디바이스 vs 전용 디바이스)
🔍 디바이스 드라이버
각 I/O 디바이스를 제어하기 위한 디바이스에 특화된 코드, 디바이스 제조사에서 제작
- Device-independent I/O(디바이스에 독립적인 I/O 소프트웨어)와 인터럽트 핸들러와 상호작용
- 운영체제의 나머지 부분과 상호작용하는 방법을 정의하는 명확한 모델과 표준 인터페이스 필요
- 디바이스 드라이버 구현 방법:
- 커널에 정적으로 링크됨: 커널에 직접 통합되어 운영체제의 일부분으로 동작
- 부팅 시 선택적으로 로드됨: 시스템 부팅 시 필요에 따라 선택적으로 로드
- 실행 중 동적으로 로드됨: 특히 핫 플러그 가능 디바이스의 경우, 시스템 실행 중에 동적으로 로드
📌 디바이스 드라이버의 문제점
커널과 같이 동작하므로 문제가 생길 수 있음
1️⃣ 신뢰성 문제
- 중요성: 신뢰성은 여전히 중요한 문제로 남아 있으며, 해결되지 않은 상태
- 사례:
- 매일 5%의 Windows 시스템이 충돌
- 주식 거래소, 전자 상거래 등에서 실패의 비용이 큼
- 디지털 가전 제품, 소비자 전자 기기 등 "관리되지 않는 시스템"의 증가
2️⃣ 디바이스 드라이버 확장의 증가
- 리눅스 커널 코드의 70%: 디바이스 드라이버가 차지
- Windows XP: 35,000개 이상의 드라이버와 120,000개 이상의 버전
- 작성자: 상대적으로 경험이 적은 프로그래머가 작성
3️⃣ OS 오류의 주요 원인
- Windows XP: 드라이버가 85%의 충돌 원인
- 리눅스: 커널보다 드라이버가 7배 더 버그가 많음
📌 Device-Independent I/O SW
통합 인터페이스를 위한 디바이스 드라이버
- 유닉스에서, 디바이스를 특수 파일로 모델링 (I/O 장치를 파일로 취급)
- 이러한 특수 파일을 시스템 호출로 접근
- 각 디바이스는 파일 이름과 연결됨
- Major device number(주요 장치 번호)로 적절한 드라이버를 찾음
→ 주 장치 번호가 8이면 SCSI 디스크 드라이버를 나타냄
- i-node에 저장되는 Minor device number는 특정 유닛을 지정하기 위해 드라이버에 매개변수로 전달
→ 부 장치 번호가 0이면 첫 번째 SCSI 디스크를, 1이면 두 번째 SCSI 디스크를 나타냄
⚙️ SCSI (Small Computer System Interface) → 여러 장치를 컴퓨터에 연결하는 표준 인터페이스
- 디바이스 파일은 일반 파일과 동일한 보호 규칙을 가짐
/dev
디렉토리:- 모든 다바이스 파일은
/dev
디렉토리에 존재
1️⃣ Error Reporting
- 필요성: 에러는 사용자에게 보고되어야 함
- 특성: 많은 에러가 디바이스에 특화되어 있음
- 처리 방법: 적절한 드라이버가 에러를 처리해야 함
- 유형: 프로그래밍 오류와 실제 I/O 오류로 구분
2️⃣ Error Handling Strategies
- 에러 코드 반환: 시스템 호출을 에러 코드와 함께 반환
- 재시도: 일정 횟수만큼 재시도
- 에러 무시: 에러를 무시하고 계속 진행
- 프로세스 종료
- 시스템 종료
📌 User-Space I/O Software
사용자 공간에서 실행되는 I/O 작업을 위한 라이브러리로 제공됨
항목 | 설명 |
표준 I/O 라이브러리 | C 표준 라이브러리는 파일을 열고 읽고 쓰기 위한 다양한 함수들을 제공 |
예시 함수 | fopen() , fgets() , fscanf() , fwrite() , fclose() |
fopen() vs. open() | fopen() : 고수준 파일 입출력 함수, open() : 저수준 시스템 호출 |
사용자 선택 | 사용자는 필요에 따라 표준 I/O 라이브러리 함수나 시스템 호출을 선택 가능 |
자체 I/O 라이브러리 작성 | 사용자는 필요에 따라 자신의 I/O 라이브러리를 작성 가능, 예: myopen() , myfgets() |
댓글