2.1 OS의 목적
- 운영체제는 사용자와 컴퓨터 사이의 가교역할 -> 사용자가 컴퓨터를 보다 편리하게 사용 가능
- 컴퓨터 시스템의 자원들을 효율적으로 사용될 수 있게 함. -> 사용자의 편리성과 효율적 사용
- (사용자) 사용하기 쉽고 편리, 배우기 쉽고 신뢰할 수 있으며 빨라야 함
- (개발자) 설계, 유지, 복수가 쉽고 적응성이 좋으며 오류 없이 효율적이어야 함
2.2 몇 가지 상식
2.2.1 부팅
: 커널의 일부가 메모리에 올라와 실행되어 장치들을 준비시키고 각종 레지스터 값을 초기화하고 나서 사용자의 입력을 받을 준비를 마치는 것
부트 프로그램과 부츠트랩 로더 : 커널이 어디에 있고, 어떻게 메모리에 올라와야 할 지 알려주는 프로그램. ROM에 저장되어 있음.
부트 프로그램 : 전원이 켜지면 무조건 제일 먼저 실행되도록 함 -> 커널을 찾아 메모리에 올린 후 실행시켜줌
부츠트랩 로더 : 먼저 부트 프로그램을 메모리에 올려 실행시키면 부트 프로그램이 커널을 올려 실행
2.2.2 레지스터 (Register)
: 메모리보다 빠른 기억장치
데이터 레지스터 : 연산을 위해 사용
주소 레지스터 : 데이터나 명령어의 메모리 주소를 저장하거나 계산하는데 사용
프로그램 상태 워드 (PSW) : 여러 가지 조건 코드와 함께 인터럽트 가능 여부를 표시하는 비트, 현재 실행 모드를 나타내는 비트 등을 포함
2.2.3 명령어 처리
반입 (Fetch) : (메모리에 있는) 명령어 읽어 (처리기에 있는) 레지스터로 가져옴
인터럽트와 명령어 실행 주기
시작 -> 명령어 반입 -> 실행 -> 인터럽트 확인 및 처리
2.3 인터럽트 (Interrupt)
컴퓨터 시스템에 존재하는 각 자원들의 현 상황을 파악할 수 있는 방법 : 폴링 (Polling), 인터럽트 (Interrupt)
1) 폴링 (Polling)
: CPU가 일정한 시간 간격을 두고 각 자원들의 상태를 주기적으로 확인하는 방식
- 폴링의 간격을 적절히 정해야 함
- 직전 폴링 이후 변화된 자신의 상태를 다음 번 폴링 때까지는 알릴 수 없음
- 아무 일이 없었는데도 CPU는 폴링에 일정량의 시간을 들여야 하는 부담
2) 인터럽트 (Interrupt)
: 각 자원들이 능동적으로 자신의 상태 변화를 CPU에게 알리는 방식
- CPU는 따로 시간을 들이지 않아도 됨
- 자원들은 상황이 발생하면 즉시 알려 처리받을 수 있음
2-1) 하드웨어 인터럽트
: 주변 장치 (= 자원)들로부터의 인터럽트
2-2) 소프트웨어 인터럽트
: CPU 스스로 자신에게 인터럽트 해야하는 경우 (=트랩) 가 있는데, 이것은 실행 중인 명령어 때문에 생기는 일.
2.3.1 인터럽트는 언제 처리될까?
: 현재 진행 중인 명령어 실행을 마친 후 처리됨
트랩 : 처리 중인 명령어에 의해 발생되므로 오류의 경우는 바로 프로그램의 종료를 가져옴
시스템 콜 : 입출력이 완료되어야 실행 중인 명령어가 완료되고 이어서 다음 실행문으로 진행될 것
2.3.2 인터럽트는 어떻게 처리될까?
1) 장치가 인터럽트 신호를 CPU에게 전송
1-1) CPU가 명령어를 실행 중이었다면 이 명령어의 실행을 완료시키고 인터럽트 신호 확인
2) 현 상태의 정보를 시스템 스택에 저장 (현재 실행 중인 프로그램이 인터럽트 처리 후 다시 실행되어야 하기 때문)
(현 상태의 정보 = PSW, PC 레지스터의 값 등)
(PC 레지스터 : 수행할 코드 주소를 기억하는 레지스터)
3) 인터럽트 처리 루틴의 시작 주소를 PC에 넣어 실행시킴
4) 인터럽트 처리 루틴 : CPU에 있는 레지스터들의 값을 저장 (값들이 훼손될 가능성이 있어서) -> 필요한 인터럽트 처리 시작
5) 처리가 끝나면 이전에 저장했던 레지스터 값들을 다시 저장 + PSW와 PC 값들을 원래 자리에 넣어주고 실행
+) 문맥 교환 (Context Switching)
: 현재 하던 일에서 잠시 다른 일을 해야 할 때, 현재까지의 내용을 가까운 어딘가에 보관했다가 나중에 다시 이어감.
(작업대 = CPU, 하고 있던 일의 상태 = 문맥) -> 상태 정보를 포함한 처리기 레지스터들의 값
2.3.3 중첩된 인터럽트의 처리는?
1) 순차적 처리
: 인터럽트를 처리하는 동안에 발생하는 인터럽트는 현재 처리가 끝난 뒤 바로 처리. 차례대로 하나씩
: 두 인터럽트의 우선순위가 같을 때
2) 중첩 처리
: 현재 처리 중인 인터럽트를 잠시 접어두고 또 다른 인터럽트로 실행을 옮길 수 있도록 하는 방식.
: 두 인터럽트의 우선 순위가 존재할 때
2.4 기억 장치의 계층적 구초 (Storage Hierarchy)
레지스터, 캐시, 주기억 장치 -> 전원이 나가면 저장된 정보가 휘발 (실행 목적)
-> 용량이 작고 속도와 가격이 좋음. (비트당 단가가 비쌈)
전자디스크, 자기디스크, 광디스크, 자기테이프 -> 휘발되지 않음 (저장 목적)
-> 용량이 큼
+) 계층적 구조의 설계
- 계층 간 데이터가 이동되는 데 드는 부담을 동반
- 상위계층의 접근을 통해 얻게 되는 처리 시간의 절약
2.5 I/O 방식
각각의 입출력 장치에는 컨트롤러가 있고, 여기에는 CPU와 입출력할 데이터를 저장하는 버퍼가 있다.
CPU의 개입 정도에 따른 입출력 방식의 분류
- 프로그램에 의한 입출력 (Programmed I/O)
: CPU가 입력을 지시한 후 한 워드가 컨트롤러의 버퍼에 입력됐는지를 계속 확인하는 방식
입력 확인 : 시스템 소프트웨어에 의한 것 (= 프로그램에 의한 입출력)
입력 완료 : 인터럽트 필요 X -> CPU가 지속적으로 완료 여부 확인. ( => CPU가 다른 작업에 동원되지 못하여 낭비됨)
- 인터럽트에 의한 입출력 (Interrupt-driven I/O)
: 한 워드의 입력이 이루어지는 사이에 CPU는 다른 작업에 활용. 낭비를 없앨 수 있다
입력 완료 시 인터럽트를 통해 CPU에 알려짐
: 버퍼의 크기에 비해 입출력할 데이터가 클수록 잦은 인터럽트 처리가 요구됨
- 메모리에 직접 접근하는 입출력 (Direct Memory Access, DMA)
: 인터럽트에 의한 입출력의 단점을 개선하기 위한 방식
: 입출력 작업을 CPU 대신 해줄 수 있는 채널이라는 위성 프로세서 필요.
CPU는 입출력할 데이터의 시작 주소와 크기를 채널에게 알려주고 다른 작업에 동원 -> 이때부터 입출력은 채널 관할
( 블록 : 한 번의 입출력 단위)
한 블록 단위로 CPU에게 인터럽트를 보내 알리게 됨. -> 인터럽트의 횟수가 훨씬 줄어들 수 있다
+) CPU와 채널의 관계에 대해
- 공유 버스로 시스템 구성 : 한 번에 하나의 장치만 버스를 사용. 채널이 버스를 사용해 블록 전송하는 동안 CPU는 대기. 전송이 끝나는 잠시 동안 실행 지연 but 전체적으로 볼 때 입출력에 걸리는 시간은 훨씬 앞당겨질 수 있음
- CPU와 채널이 동시에 메모리 접근 요구를 할 때? : 채널에게 기회를 주어 원활한 입출력이 이루어질 수 있도록 함. (=Cycle Stealing)
입출력을 위한 하드웨어의 구성
- 독립적인 입출력 (Isolated I/O)
: 입출력 장치 <-> 입출력 버스를 통해 CPU와 연결
메모리 <-> 메모리 버스를 통해 연결
단점 : 입출력 명령어가 명령어 집합에 추가되므로 제어 로직이 복잡, 입출력 버스를 장착하는데 추가 비용이 있다는 것.
장점 : 속도가 빨라짐
- 메모리 주소지정 입출력 (Memory-mapped I/O)
: 입출력 장치들이 메모리와 함께 메모리 버스에 연결.
입출력을 위한 명령어를 따로 두어 사용하지 않고 MOVE, LOAD 등을 사용해 실제 입출력을 함.
주소 공간만큼의 메모리를 활용할 수 없음.
'5학기 > 운영체제' 카테고리의 다른 글
Ch 05. 병행 프로세스와 동기화 (0) | 2023.04.20 |
---|---|
Ch 04. CPU 스케줄링 (0) | 2023.04.20 |
Ch 03. 프로세스와 스레드 (0) | 2023.04.20 |
Ch01. OS? Oh Yes! (0) | 2023.03.10 |