컴퓨터 시스템 구조
CPU와 Memory : Computer
Disk와 키보드, 프린터, 모니터 : I/O device
CPU
메모리보다 더 빠르면서 정보를 저장할 수 있는 register를 가진다
지금 CPU에서 실행되는 것이 운영체제인지 사용자 프로그램인지를 구분해주는 mode bit을 가진다
CPU가 메모리 접근을 하다가 I/O가 발생하면 이를 I/O device의 device controller에 요청하고 자신은 다음 Instruction을 실행한다.
사용자 프로그램은 직접 I/O 접근을 못하므로 자신의 CPU 제어권을 OS에 넘기면서 이를 요청하는 것이며, OS는 device controller에 의해 I/O가 진행되는 동안 CPU의 제어권을 다른 프로그램으로 넘겨준다
I/O 요청을 받은 해당 device는 local buffer에 정보를 담아두고, 작업이 완료되면 device controller는 interrupt를 발생시킨다.
interrupt가 발생하면 기본적으로 CPU의 제어권이 OS로 넘어가므로, CPU는 하던 일을 멈추고 인터럽트의 발생 원인을 확인한다.
local buffer에 저장되어 있던 값을 I/O 요청을 했던 프로그램의 메모리 공간에 copy 해두고 인터럽트가 발생하기 이전의 프로그램으로 다시 돌아가 남은 한정된 시간동안 실행된다
사용자 프로그램에서 무한 반복 등의 문제로 CPU를 독점하는 상황에 대비하여 timer를 가진다
CPU는 하나의 instruction이 실행된 후, interrupt line을 확인하고 난 뒤에 다음 instruction을 실행한다.
timer가 interrupt를 발생시키면 CPU는 하던 일을 멈추고, CPU의 제어권이 사용자 프로그램으로부터 운영체제로 넘어간다.
timer에 기준 시간을 설정하면 OS는 다음 사용자 프로그램에 CPU의 제어권을 넘겨준다
그런데 CPU가 인터럽트에 의해 너무 많이 방해받는다. 따라서 DMA controller를 가진다
DMA controller는 직접 메모리에 접근 가능한 controller이며, CPU와 DMA controller가 동시에 특정 메모리 영역에 접근하는 것을 방지하기 위해 memory controller를 가진다.
DMA controller가 I/O 작업 이후 메모리에 데이터를 옮긴 후, CPU에는 interrupt를 1번 발생시킴으로써 오버헤드를 크게 줄일 수 있다.
사용자 프로그램은 I/O device에 접근 가능한 특권 명령을 내릴 수 있는 권한이 없다.
따라서 CPU가 실행하고 있는 메모리 주소를 OS로 넘겨줘야 하는데, 사용자 프로그램은 운영체제의 메모리 주소를 참조할 수 있는 능력도 없다.
따라서 timer나 device controller와 같이 사용자 프로그램도 interrupt를 발생시켜 CPU가 다음 명령어를 실행하기 전에 인터럽트를 확인하고, mode bit를 0으로 변경하며, OS가 제어권을 가지도록 하여 I/O 요청을 할 수 있게 된다.
위의 인터럽트 방식을 Trap (소프트웨어 인터럽트) 라고 부른다
결국 I/O를 하기 위해서는 2번의 인터럽트가 발생한다
소프트웨어 인터럽트로 요청이 되고, I/O 작업이 끝난 후에는 하드웨어 인터럽트로 받아온다
인터럽트의 종류는 다양하고 각 요청에 따라 CPU가 해야하는 작업이 다르다.
각각 무슨 일을 해야 하는지는 운영체제에 정의되어 있다 (인터럽트 처리 루틴)
각각의 인터럽트 처리 루틴을 불러오기 위해서 주소를 가진 인터럽트 벡터를 사용한다
Memory
- CPU의 작업공간
- CPU는 매 클럭마다 Instruction (기계어)를 하나씩 읽어서 실행한다
I/O device
- 디스크는 보조기억장치로 보통 말하긴 하지만 I/O device라고 할 수도 있다
- device를 전담하는 작은 CPU인 device controller를 가지고 있다
- 시간 차이가 수십만배 ~ 수백만배 차이나기 때문에
- 디스크에서 헤드를 어떻게 움직이고 어떤 데이터를 읽을지 등의 디스크의 내부 동작을 control 하는 것은 CPU가 아닌 디스크에 붙어있는 device controller가 담당한다
- CPU의 Memory처럼 device controller의 작업공간인 local buffer를 가진다
Mode bit
사용자 프로그램의 잘못된 수행으로 다른 프로그램 및 운영체제에 피해가 가지 않도록 하기 위한 보호 장치가 필요하다
Mode bit을 통해 하드웨어적으로 두 가지 모드의 operation을 지원한다
1 사용자 모드 : 사용자 프로그램 수행
0 모니터 모드 : OS 코드 수행
모니터 모드 = 커널모드 = 시스템 모드
- 보안을 해칠 수 있는 중요한 명령어는 모니터 모드에서만 수행 가능한 ‘특권 명령’으로 규정
- Interrupt나 Exception 발생 시 하드웨어가 mode bit을 0으로 바꿈
- 사용자 프로그램에게 CPU를 넘기기 전에 mode bit을 1로 세팅
Timer
정해진 시간이 흐른 뒤 운영체제에게 제어권이 넘어가도록 인터럽트를 발생시킴
타이머는 매 클럭 틱 때마다 1씩 감소
타이머 값이 0이 되면 타이머 인터럽트 발생
CPU를 특정 프로그램이 독점하는 것으로부터 보호
- 타이머는 time sharing을 구현하기 위해 널리 이용됨
- 타이머는 현재 시간을 계산하기 위해서도 사용
Device Controller
해당 I/O 장치 유형을 관리하는 일종의 작은 CPU
제어 정보를 위해 control register, status register를 가짐
local buffer를 가짐 (일종의 data register)
입출력하라는 명령어는 control register에 담고, 실제 입출력할 정보는 local buffer에 저장
- I/O는 실제 device와 local buffer 사이에서 일어남
- Device Controller는 I/O가 끝났을 경우 interrupt로 CPU에 그 사실을 알림
device driver (장치구동기)
: OS 코드 중 각 장치별 처리루틴 ⇒ software
device controller (장치제어기)
: 각 장치를 통제하는 일종의 작은 CPU ⇒ hardware
입출력(I/O)의 수행
모든 입출력 명령은 특권 명령
사용자 프로그램은 어떻게 I/O를 하는가?
- 시스템 콜(system call)
- 사용자 프로그램은 운영체제에게 I/O 요청
- trap을 사용하여 인터럽트 벡터의 특정 위치로 이동
- 제어권이 인터럽트 벡터가 가리키는 인터럽트 서비스 루틴으로 이동
- 올바른 I/O 요청인지 확인 후 I/O 수행
- I/O 완료 시 제어권을 시스템 콜 다음 명령으로 옮김
인터럽트 (Interrupt)
인터럽트 당한 시점의 레지스터와 program counter를 save 한 후 CPU의 제어를 인터럽트 처리 루틴에 넘긴다
넓은 의미의 Interrupt
- Interrupt (하드웨어 인터럽트) : 하드웨어가 발생시킨 인터럽트
- Timer 또는 Controller에 의한 인터럽트
- Trap (소프트웨어 인터럽트)
- Exception : 프로그램이 오류를 범한 경우
- System call : 프로그램이 커널 함수를 호출하는 경우
관련 용어
- 인터럽트 벡터
- 해당 인터럽트의 처리 루틴 주소를 가지고 있음
- 인터럽트 처리 루틴 (Interrupt Service Routine, 인터럽트 핸들러)
- 해당 인터럽트를 처리하는 커널 함수
시스템 콜(System Call)
사용자 프로그램이 운영체제의 서비스를 받기 위해 커널 함수를 호출하는 것
동기식 입출력과 비동기식 입출력
두 경우 모두 I/O의 완료는 인터럽트로 알려줌
동기식 입출력 (synchronous I/O)
I/O 요청 후 입출력 작업이 완료된 후에야 제어가 사용자 프로그램에 넘어감
구현 방법 1
- I/O가 끝날 때까지 CPU를 낭비시킴
- 매시점 하나의 I/O만 일어날 수 있음
구현 방법 2
- I/O가 완료될 때까지 해당 프로그램에게서 CPU를 빼앗음
- I/O 처리를 기다리는 줄에 그 프로그램을 줄 세움
- 다른 프로그램에게 CPU를 줌
비동기식 입출력 (asynchronous I/O)
I/O가 시작된 후 입출력 작업이 끝나기를 기다리지 않고 제어가 사용자 프로그램에 즉시 넘어감
DMA (Direct Memory Access)
빠른 입출력 장치를 메모리에 가까운 속도로 처리하기 위해 사용
CPU의 중재 없이 device controller가 device의 buffer storage의 내용을 메모리에 block 단위로 직접 전송
바이트 단위가 아니라 block 단위로 인터럽트를 발생시킴
서로 다른 입출력 명령어
- I/O를 수행하는 special instruction에 의해 (좌측)
- 일반적인 I/O 방식
- 메모리를 접근하는 instruction과 각 I/O device에 접근하는 instruction이 구분되어 있음
- instruction과 같이 Address도 구분되어 있음
- Memory Mapped I/O에 의해 (우측)
- I/O 장치 또한 메모리 주소에 연장 주소를 붙여 접근
저장장치 계층 구조
Primary (Executable)
- CPU가 직접 접근 가능
- 바이트 단위로 접근 가능한 매체이므로 CPU가 접근 가능하다
Secondary
- CPU가 직접 접근 불가능
- 섹터 단위로 접근 가능하므로 CPU가 접근 불가능하다
- Speed : 위로 갈수록 빠르다
- Cost : 위로 갈수록 비싸다
- Volability : Primary는 휘발성, Secondary는 비휘발성
Caching : copying information into faster storage system
(캐싱은 재사용을 목적으로 한다)
프로그램의 실행 (메모리 load)
어떤 프로그램을 실행시키면 Virtual Memory에 그 프로그램의 주소 공간이 생성된다
- 0번지 부터 시작
- code, data, stack 영역으로 이루어져 있다
Kernel Address space는 컴퓨터 부팅 시에 생성된다
프로세스들의 주소 공간은 프로세스가 실행되었을 때 생성되었다가 완료되면 사라진다.
다만 위의 주소공간을 Physical Memory에 모두 올리지 않는다
당장 필요한 부분만 올려 메모리 낭비를 막는다
필요하지 않은 부분은 디스크 공간의 Swap area에 내려둔다
모든 가상 메모리 상의 주소 공간은 0번지부터 시작하므로 실제 물리 메모리 상의 주소 값과는 차이가 있다
→ Address translation (주소 변환 계층에 의해)
커널 주소 공간의 내용
Code 영역
커널 코드가 들어있다
- 시스템 콜, 인터럽트 처리 코드
- 자원 관리를 위한 코드
- 편리한 서비스 제공을 위한 코드
Data 영역
운영체제는 CPU, Memory, Disk 등의 하드웨어를 관리한다
- 하드웨어를 다루기 위한 자료구조를 내부적으로 가지고 있을 것이다
운영체제는 Process 들을 관리한다
- 각 프로그램들의 독자적인 주소 공간을 관리하기 위해 자료구조인 PCB를 가지고 있다
Stack 영역
운영체제의 코드는 여러 사용자 프로그램들의 요청에 의해 호출된다
따라서 사용자 프로그램마다 커널 스택을 따로 둔다
사용자 프로그램이 사용하는 함수
사용자 정의 함수
- 자신의 프로그램에서 정의한 함수
- 프로세스 A의 주소 공간 내의 code 영역에 존재한다
라이브러리 함수
- 자신의 프로그램에서 정의하지 않고 갖다 쓴 함수
- 자신의 프로그램의 실행 파일에 포함되어 있다
- 프로세스 A의 주소 공간 내의 code 영역에 존재한다
커널 함수
- 운영체제 프로그램의 함수
- 커널 함수의 호출 = 시스템 콜
- 커널 주소 공간 내의 code 영역에 존재한다
프로그램의 실행
사용자 정의 함수나 라이브러리 함수를 호출하면 자신의 주소 공간의 code 영역 내에서 함수를 호출하므로 모드 전환이 없다
시스템 콜을 하게되면 사용자 모드에서 커널 모드로의 전환이 발생한다
PS
이 포스팅은 KOCW 반효경 교수님의 운영체제 강의를 기반으로 작성했습니다.
'Computer Science Lectures > 운영체제 - KOCW' 카테고리의 다른 글
1강. Introduction to Operating Systems (0) | 2022.02.10 |
---|---|
OS를 다시 공부하며.. (0) | 2022.02.09 |