컴퓨터 시스템의 구조
- 입력 (input) : 컴퓨터 내부로 데이터가 들어오는 것
- 출력 (output) : 컴퓨터 외부장치로 데이터가 나가는 것
- 메모리와 입출력 장치 등의 각 하드웨어 장치에는 컨트롤러 (일종의 작은 CPU) 라는 것이 붙어있음
- 운영체제는 컴퓨터가 부팅될 때부터 항상 메모리에 올라가 있음 : 커널(항상 메모리에 올라가 있는 부분)
CPU연산과 I/O 연산
- CPU연산과 I/O 연산은 동시 수행이 가능
- 로컬버퍼 : 장치로부터 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리
- 키보드 등에서 데이터를 읽어오는 경우, 로컬버퍼에 임시로 저장된 후 메모리에 전달됨
- 장치에서 로컬버퍼로 읽어오는 일은 컨트롤러가 담당
- 과정 (디스크에서 데이터를 읽어오는 예시)
- 디스크 컨트롤러가 물리적인 디스크에서 내용을 읽어 로컬버퍼에 저장
- 다 저장하고 나서 컨트롤러가 인터럽트를 발생시켜 CPU에 보고
- 메인 CPU에서 다음 일을 수행
인터럽트의 일반적 기능
- 하드웨어 인터럽트 : 컨트롤러 등 하드웨어 장치가 CPU의 인터럽트 라인을 세팅
- 소프트웨어 인터럽트 : 소프트웨어가 위의 일을 수행
트랩 trap
- 예외상황 (exception) : 비정상적인 작업의 시도, 권한없는 작업 시도
- 시스템 콜 (system call) : 사용자 프로그램이 os 내부에 정의된 코드를 실행하고 싶을 때 운영체제에 서비스를 요청하는 방법
⇒ 둘 다 인터럽트가 발생하면 CPU는 하던 일을 멈추고 운영체제 커널 내에서 해당 인터럽트의 처리를 위해 정의된 코드를 찾음
- 인터럽트 벡터 (interrupt vector) : 인터럽트 종류마다 번호를 정해서 번호에 따라 처리해야 할 코드가 위치한 부분을 가리키고 있는 자료구조
할 일을 쉽게 찾아가기 위해 존재 - 인터럽트 처리루틴 or 인터럽트 핸들러 : 실제 처리해야 할 코드
⇒ 인터럽트 처리 후 원래 수행하던 작업으로 돌아가 계속 수행함
⇒ 돌아갈 위치를 알아야 하므로 수행중이던 작업 반드시 저장해두어야 함
인터럽트 핸들링
- 인터럽트가 발생한 경우 처리해야 할 일의 절차
- 프로그램 A가 실행 중에 인터럽트가 발생
- A의 현재 상태(현재 CPU에서 실행 중인 명령의 메모리 주소를 포함한 몇 가지 부가적인 정보) 먼저 저장
- PCB (프로세스 제어블록) : 현재 시스템 내에서 실행되는 프로그램들을 관리하기 위한 자료구조
- 각각의 프로그램마다 하나씩 존재
- 해당 프로그램의 어느 부분이 실행 중이었는지 저장 : 프로그램이 실행 중이던 코드의 메모리 주소와 레지스터값, 하드웨어 상태 등
⇒ 요즘은 인터럽트가 발생할 때에만 OS가 실행됨, 이외에는 사용자가 CPU를 계속 점유
입출력 구조
- 동기식 입출력 (Synchronous I/O)
- 어떤 프로그램이 입출력 요청을 했을 때 입출력 작업이 완료된 후에야 그 프로그램이 후속 작업을 수행할 수 있는 방식
- 입출력이 진행되는 동안 다음 명령을 수행하지 않고 기다림 ⇒ 입출력이 완료되어 인터럽트를 통해 그 사실이 전달된 후에야 CPU의 제어권이 그 프로그램에게 넘어감
- ❌ CPU는 입출력 연산이 끝날 때까지 인터럽트를 기다리며 자원 낭비
⇒ 입출력을 수행 중인 경우 CPU를 다른 프로그램에게 이양해 CPU가 쉬지 않고 일하도록 함
⇒ 이를 관리하기 위해 운영체제는 프로그램을 몇 가지 상태로 나누고 입출력중인 상태를 봉쇄 상태(blocked state)로 전환시킴 - 봉쇄상태 : CPU를 할당하지 않고, CPU 할당 시 곧바로 명령을 수행할 수 있는 상태
- ✅ 동기화가 자동으로 이루어짐 (요청 큐 순서대로 처리함)
- 비동기식 입출력
- 연산이 끝나기를 기다리는 것이 아니라 CPU의 제어권을 입출력 연산을 호출한 그 프로그램에게 곧바로 다시 부여하는 방식
DMA (Direct Memory Access)
- CPU 이외에 메모리 접근이 가능한 장치, 일종의 컨트롤러
- 모든 메모리 접근 연산이 CPU에 의해서만 이루어질 경우 입출력 장치가 메모리 접근을 원할 때마다 인터럽트에 의해 CPU업무가 방해를 받게 되어 CPU 효율성이 떨어지는 문제를 방지하기 위해
- CPU가 입출력 장치들의 메모리 접근 요청에 의해 자주 인터럽트 당하는 것을 막아주는 역할
- 로컬버퍼에서 메모리로 읽어오는 작업을 대행함으로써 CPU가 원래 하던 작업을 멈추고 인터럽트를 처리할 필요가 없어짐
- 바이트 단위가 아니라 블록이라는 큰 단위로 정보를 메모리로 읽어온 후 CPU에게 인터럽트를 발생시켜 해당 작업의 완료를 알려줌
⇒ CPU에 발생하는 인터럽트의 빈도를 줄여 더 효율적이고 빠른 연산 수행 도와줌
저장장치의 구조
- 주기억장치 : 메모리, 전원이 나가면 저장되어있던 내용이 모두 날아가는 휘발성
- 보조기억장치 : 전원이 나가도 저장된 내용을 기억할 수 있는 비휘발성
- 파일 시스템용 : 전원이 나가도 유지해야할 정보가 있으면 파일 형태로 보조기억장치에 저장
- 스왑 영역용 : 크기가 한정되고, 가격이 비싼 메모리의 한계를 극복하기 위해 당장 필요한 부분만 메모리에 올려놓고 그러지 않은 부분은 디스크의 스왑 영역에 저장
프로그램이 실행될 때 내용을 저장했다가 프로그램이 종료될 때 삭제하는 메모리의 연장 공간 (휘발성)
저장장치의 계층 구조
- 빠른 저장장치 : 비쌈, 적은 용량
- 느린 저장장치 : 저렴, 대용량, 접근 속도가 느림
⇒ 당장 필요한 정보는 빠른 저장장치에, 그렇지 않은 정보는 느린 저장장치에 보관
- 레지스터 > 캐시 메모리 > 메인 메모리 > 마그네틱 디스크 > 광디스크 > 마그네틱 테이프
- 위로 갈수록 접근 속도 ↑, 용량 ↓, 가격 ↑
- 캐싱 기법 : 상대적으로 용량이 적은 빠른 저장장치를 이용해 느린 저장장치의 성능을 향상시키는 총체적 기법, 두 저장장치 사이의 속도를 완충
하드웨어의 보안
- 다중 프로그래밍(multi-programming) 환경에서는 각 프로그램이 다른 프로그램의 실행을 방해하거나 프로그램 간 충돌을 일으키는 문제를 막기 위해 각종 보안 기법이 필요함
- 어떤 프로그램이 이상한 명령을 수행시켜 다른 프로그램의 메모리 영역이나 파일 영역을 침범하는 경우가 발생할 수 있음
- 커널 모드 (kernel mode, system mode)
- 중요한 정보에 접근해 위험한 상황을 초래할 수 있는 연산
- 운영체제가 CPU의 제어권을 가지고 운영체제 코드를 실행하는 모드, 모든 종류의 명령 실행가능
- 사용자 모드 (user mode)
- 일반적인 연산
- 일반 사용자 프로그램 실행, 제한적인 명령만 수행 가능
⇒ 그러나 사용자 프로그램이 프로그램 내에서 그런 종류의 연산을 수행해버리면 제어가 소용없음
- 모드 비트 (mode bit) - 0 : 커널모드로서 모든 명령 수행 가능
- 1 : 사용자모드로서 제한된 명령만 수행 가능
⇒ 보안과 관련된 명령을 수행하기 전에 항상 모드비트를 조사해 0인 경우만 명령(특권명령) 수행, 사용자 프로그램에게 CPU 제어권을 넘길 때 다시 1로 세팅해서 넘김
- 각종 하드웨어 장치에서는 모든 입출력 명령을 특권명령으로 규정해서 사용자 프로그램이 직접 입출력 하는 것을 차단
- 입출력이 필요할 때에는 운영체제에 요청하여 운영체제가 입출력 명령 대신 수행
- 이 때, 운영체제는 입출력 요청이 올바른 요청인지 확인 후 실행하기 때문에 파일에 대한 보안 유지 가능
메모리 보안
- 여러 프로그램이 메모리에 동시에 올라가므로 하나의 사용자 프로그램이 다른 사용자 프로그램이나 운영체제가 위치한 메모리 영역을 침범하는 것을 방지
- 2개의 레지스터를 사용해서 프로그램이 접근하려는 메모리 부분이 합법적인지 체크
- 기준 레지스터 (base register)
- 어떤 프로그램이 수행되는 동안 그 프로그램이 합법적으로 접근할 수 있는 메모리상의 가장 작은 주소 보관
- 한계 레지스터 (limit register)
- 그 프로그램이 기준 레지스터값부터 접근할 수 있는 메모리의 범위를 보관
⇒ 즉, 시작주소와 길이를 각각 보관해서 메모리 접근 연산이 있을 때마다 하드웨어적으로 현재 접근하려는 위치가 합법적인 범위에 있는지 체크 ⇒ 범위 안에 없으면 예외상황이라는 일종의 소프트웨어 인터럽트 발생
- 이렇게 레지스터 2개를 이용한 메모리 보호 기법은 하나의 프로그램이 메모리의 한 영역에 연속적으로 위치하는 단순화된 메모리 관리 기법을 사용하는 경우만 해당됨
- 사용자모드에서 이렇게 메모리를 보호하고, 커널모드에서는 메모리에 무제한 접근가능
- 메모리 접근 명령 자체는 특권 명령이 아니지만, 기준 레지스터와 한계 레지스터 값을 세팅하는 연산은 특권명령임
CPU 보호
- CPU가 하나의 프로그램에 의해 독점되는 것을 방지
- 타이머 (Timer) : 정해진 시간이 지나면 인터럽트를 발생시켜 운영체제가 CPU의 제어권을 획득할 수 있도록 함
- 일정한 시간 단위로 세팅될 수 있으며 매 클럭 틱 때마다 1씩 감소
- 타이머가 0이 되는 순간 인터럽트 발생
- 로드타이머 (load timer) : 타이머의 값을 세팅하는 명령, 특권명령
시스템 콜을 이용한 입출력 수행
- 입출력 명령은 운영체제 코드에 구현되어 있음
- 사용자 프로그램은 직접 입출력을 수행하는 대신 운영체제에게 시스템 콜이라는 서비스 대행 요청을 하여 입출력 수행
- 시스템 콜(소프트웨어 인터럽트) : 트랩이 발생해 CPU의 제어권이 운영체제로 넘어가게 됨
- 시스템 콜이 발생하면 운영체제는 해당 시스템 콜을 처리하기 위한 루틴으로 가서 정의된 명령 수행
- EX. 디스크 입출력 요청 : 디스크 컨트롤러에게 입출력 요청 수행하도록 명령 > 수행 마치면 CPU에게 인터럽트를 발생시켜 완료되었음을 알려줘서 해당 프로그램이 다시 CPU를 할당받을 수 있도록 함