운영체제는 App의 요청을 네트워크 회선이나, 특정 디스크 섹터에 어떻게 연계시키는가?
즉 입출력 요구를 어떻게 하드웨어 연산으로 변환시키는지 알아보자.
MS-DOS와 FAT
- 파일명으로 데이터를 참조함.
- 이름 ⇒ 파일 액세스 테이블의 항목을 나타낸 숫자
파일 이름과 디스크 컨트롤러 연결하기
- 파일명의 첫 부분 : 특정 하드웨어 장치를 알려줌.
- 콜론을 통해 장치 이름과 파일 이름을 쉽게 구분
- 운영체제가 각 장치에 추가적인 기능을 쉽게 연결시킬 수 있음.
UNIX라면?
- 파일명으로 데이터를 참조함.
- 이름 ⇒ inode 번호로 매핑되고, inode는 공간할당 정보를 포함.
파일 이름과 디스크 컨트롤러 연결하기
- 장치 이름과 파일 시스템 이름이 같은 공간 안에 결합됨.
- 통상의 파일 시스템 이름 서비스가 자동으로 제공
- 파일 이름에 대한 소유와 접근 제어를 제공 시, 장치도 이를 가짐.
- 따라서 이러한 인터페이스는 입출력 시스템에 대한 접근을 두 수준에서 제공
- 이름이 장치에 접근하기 위해 사용됨.
- 이름이 장치 속 파일에 접근하기 위해 사용됨.
경로명과 장치
- 장치 이름도 보통 파일처럼 표기
- 경로상으로만 보면 장치 이름이 표면적으로 구분되지 않음
- 대신 경로 이름의 접두어를 특정 장치 이름과 연관 짓는 마운트 테이블이 있음.
- 마운트 테이블을 찾아 inode 대신 <major, minor> 장치 번호를 획득
- major : 장치 드라이버를 나타냄
- minor : 장치 드라이버에게 전달되고, 통상 장치 테이블에 대한 인덱스로 나타냄
최신 OS의 경우
입출력 요청과 장치 컨트롤러 사이에 여러가지 룩업 테이블을 갖춰 놓고 유연성을 제공.
- 커널을 다시 컴파일하지 않고도 새 장치와 드라이버를 컴퓨터에 추가 가능
몇몇 운영체제는 언제든지 새 장치 드라이버를 적재할 수 있는 능력을 가지고 있음.
- 부트 시 필요한 하드웨어의 종류를 판단하고 필요한 드라이버를 적재.
- 부팅 후 추가된 장치는 발생하는 오류에 의해 감지될 수 있음.
예시 : 봉쇄형 읽기 처리
-
한 프로세스가 read()를 요청
-
커널 안에 있는 시스템 콜 코드는 그 인자를 검사
read()의 경우 자료가 이미 버퍼 캐시에 있으면 자료를 반환 후 끝
-
만약 자료가 버퍼 캐시에 없으면 실제의 read()가 필요.
프로세스를 실행 큐에서 대기 큐로 옮김.
입력 작업이 장치 드라이버로 보내짐.
요구가 서브루틴 호출이나 커널 내부이 메시지를 통해 전달.
-
장치 드라이버는 입력될 자료를 위해 커널 버퍼를 확보하고, 입출력을 스케줄
-
장치 컨트롤러가 장치를 작동 = 데이터 입력
-
장치 드라이버는 상태를 알아보거나 데이터를 얻기 위해 폴링할 수도 있고, DMA 방식으로 작업 처리를 했을 수도 있음.
DMA 방식이라고 쳤을 때, DMA가 전송이 완료되면 인터럽트를 보냄.
-
인터럽트 벡터 테이블을 통해 해당 인터럽트 핸들러가 인터럽트를 받고, 장치 드라이버에 신호를 보내며, 인터럽트로부터 되돌아 옴.
-
신호를 받은 장치 드라이버는 어떠한 입출력이 완성되었는지 확인
커널 입출력 서브시스템에게 그 요구가 완료되었음을 알려준다.
-
커널은 자신의 버퍼로부터 요구된 프로세스의 버퍼로 데이터를 옮기고, 그 프로세스를 블록 큐에서 준비 완료 큐로 옮김
-
준비 완료 큐로 보내진 작업은 블록 상태를 벗어나서 준비 완료 상태가 됨.
스케쥴러가 이 작업에 CPU를 할당. 프로세스는 시스템 콜에서 복귀한 것.