강의 목표
- 컴퓨터 시스템에서 하드웨어가 어떻게 동작하는지 이해
- 프로그램들이 하드웨어 위에서 어떻게 돌아가는지 이해
컴퓨터 시스템의 하드웨어 구조
-
Computer : CPU + Memory
-
I/O device
- Input : I/O device의 데이터가 Computer 안으로 들어가는 것
- Output : Computer에서 처리한 결과를 I/O device로 내보내는 것
Memory
- CPU의 작업 공간
- CPU는 매 clock cycle마다 Memory에서 instruction을 하나씩 읽어서 실행
Disk
- 보조기억장치로 이야기하나, I/O device로 보기도 함
- 하드디스크 내의 데이터를 메모리로 읽어들이기도 함(Input device의 역할)
- 처리 결과를 Disk의 file system에 저장하기도 함 (Output device의 역할)
device controller
- 각각의 I/O device에 있는, 그 device를 전담하는 일종의 작은 CPU
- CPU와 I/O device들의 처리 속도 차이 매우 큼 (CPU와 Disk의 처리 속도는 100만배 차이)
- 따라서 Disk 내에서의 처리는 CPU에서 담당하지 않고, device controller가 수행
- ex) disk의 헤더를 어떻게 움직이고, 어떤 데이터를 읽을지 등 disk의 내부를 통제하는 역할
local buffer
- device controller들의 작업 공간
register
- CPU 내에 있는 정보를 저장할 수 있는 작은 공간
- Memory보다 더 빠름
memory controller
- Memory도 하나의 device이기 때문에, 이를 전담하는 controller가 존재
mode bit
- 현재 CPU에서 실행되는 것이 운영체제인지 사용자 프로그램인지 구분해주는 것 (= CPU를 OS가 가지고 있느냐, 사용자 프로그램이 가지고 있느냐를 나타내는 것)
- 사용자 프로그램의 잘못된 수행으로 다른 프로그램 및 운영체제에 피해가 가지 않도록 하기 위한 보호장치
0 : 모니터모드 (=커널 모드, 시스템 모드)
→ OS 코드 수행
1 : 사용자 모드
→ 사용자 프로그램 수행
interrupt line
- CPU가 I/O device에 요청한 일이 끝나면, I/O device는 interrupt를 통해 CPU에게 이 사실을 알림
- CPU는 매 instruction이 끝날 때마다 interrupt line을 확인, 들어온 interrupt가 있다면 이를 우선적으로 처리
timer
- 특정 프로그램에 CPU를 1회 할당하는 시간을 체크하는 역할
- 할당된 시간이 지나면 interrupt를 통해 CPU에게 이 사실을 알림
- 특정 프로그램이 CPU를 독점하는 것을 막는 역할
동작 과정
CPU는 오로지 Memory에 올라온 instruction을 실행하는 역할만을 수행한다.
- 컴퓨터를 처음 켜면, 최초에 OS가 CPU를 가지고 있다가, 여러 프로그램이 실행되면 프로그램에게 CPU를 넘겨줌
1-1. 이 때, timer에 일정 값을 세팅한 상태로 프로그램에게 CPU를 넘겨줌
1-2. Mode bit도 0 -> 1로 변경
- timer에 설정한 시간이 지나면, timer가 CPU에 interrupt를 걸음
- CPU는 하나의 instruction이 끝날 때마다 interrupt line을 체크함
- interrupt가 있다면, CPU가 하던 일을 잠시 멈추고 CPU 제어권이 프로그램에서 OS로 넘어옴.
4-1. Mode bit도 1->0 으로 변경
- OS는 아까까지 실행된 프로그램 이외의 다음 프로그램에 CPU를 넘겨줌
5-1. 마찬가지로 timer에 일정 값을 세팅
5-2. Mode bit도 0->1 로 변경
- 프로그램이 종료되면 자동으로 CPU를 반납하게 됨
timer 설정의 이유
- 사용자 프로그램이 독점적으로 CPU를 계속 쓸 수 있는 것이 아니라, 할당된 시간까지만 사용가능하도록 함
- 한 프로그램이 CPU만 쓰는 무한루프만 돌 경우, CPU가 다른 프로그램으로 넘어가지 못해서 time sharing이 불가능한 문제를 막기 위함
- 타이머는 매 클럭 틱마다 1씩 감소하며, 0이 되면 timer interrupt 발생
- time sharing 구현을 위해 널리 이용됨
- 현재 시간을 계산하기 위해서도 사용
I/O 과정
보안 상의 문제로 사용자 프로그램은 자신이 직접 I/O device, 다른 프로그램이나 OS의 Memory 공간에 접근하는 것이 불가능하다.
즉, I/O device에 접근하는 모든 instruction은 OS를 통해서만 가능하다.
그렇다면 사용자 프로그램에서 I/O가 필요할 때에는 어떤 과정을 거쳐야 하는가?
- 사용자 프로그램이 CPU 제어권을 가지고 실행되는 중
1-1. Mode bit 1인 상태
- 사용자 프로그램에서 I/O가 필요한 instruction의 실행 순서가 됨
- 프로그램이 system call을 통해 OS에게 I/O 요청을 전달
3-1. 프로그램이 직접 interrupt line을 세팅하는 instruction을 세팅
- CPU는 다음 instruction을 실행하기 이전에 interrupt를 발견
4-1. Mode bit가 1 -> 0 으로 변경
4-2. CPU 제어권이 OS로 넘어감
- OS는 올바른 I/O 요청인지를 확인 후 I/O 수행
5-1. 해당하는 device controller에 요청 전달
5-2. I/O device는 요청에 따라 데이터를 찾음
5-3. CPU는 다른 instruction을 실행하거나, I/O 작업결과 없이 instruction을 실행할 수 없는 상황이라면 다음 프로그램으로 CPU 제어권 이동시키며 작업 재개
- I/O 작업 완료 시 찾은 데이터를 I/O device의 local buffer에 저장
- I/O device에서 hardware interrupt를 걸음
7-1. local buffer에 저장된 data를, 해당 I/O 요청을 한 프로그램의 memory 공간에 저장 (누가? DMA Controller가!)
- CPU 제어권을 system call 다음 명령으로 옮김
=> 정상 실행
System Call 후의 CPU의 상황
- OS는 system call에 따라 I/O 요청을 전달하고 난 후, 이를 요청한 프로그램이 아닌 다른 프로그램에 CPU를 넘김
- I/O는 시간이 오래 소요되므로
- 그렇다면 해당 프로그램은 언제 다시 CPU를 얻게 되는가?
Mode bit에 따른 접근 제한
- 커널모드(Mode bit==0)일 때는 제한 없음
- Memory 접근 가능
- I/O device에 접근하는 instruction 가능
- 사용자 모드(Mode bit==1)일 때는 제한된 instruction만 CPU에서 실행 가능
- 보안 상의 목적
- OS가 사용자 프로그램에게 CPU를 넘겨줄 때 mode bit을 1로 바꾸어서 넘겨줌
- instruction을 실행하다가 I/O 장치로 접근하거나, 다른 프로그램/OS의 메모리 공간에 접근하는 등의 시도를 하면, mode bit이 1인 것을 확인하고 instruction 실행을 막도록 하드웨어적 구현을 해둠
- interrupt가 들어오면 CPU 제어권이 운영체제로 넘어가면서 mode bit이 0으로 바뀜
세부 개념
Device Controller의 구성
- 제어 정보를 위해 control register, status register를 가짐
- 제어 정보를 위한 register : CPU가 device에 일을 시킬 때 “그 register를 통해서 무슨 일을 하라”고 지시하기 위한 것
- data를 저장하는 local buffer를 가짐 (일종의 data register)
- input data를 담고 있다가 memory에 옮기기 위함이거나, 화면에 출력할 data를 담고 있기 위함 등
- I/O는 실제 device와 local buffer 사이에서 일어남
- 용어 정리
- device driver (장치 구동기)
- OS 코드 중 각 장치별 처리 루틴 → software
- 운영체제의 코드 중에서 각 device로 접근/처리하기 위해서 그 device의 인터페이스가 있음. 그것에 맞게 접근할 수 있게 해주는 소프트웨어 구조
- device cotroller (장치 제어기)
- 각 장치를 통제하는 일종의 작은 CPU → hardware
DMA Controller
: Direct Memory Access controller (직접 메모리를 접근할 수 있는 컨트롤러)
- memory는 원칙적으로는 CPU만 접근할 수 있음
- CPU는 memory 접근 가능, local buffer 접근 가능
- device controller는 자기 자신의 local buffer만 접근 가능
- 따라서 기본적으로는, I/O가 끝나서 hardware interrupt가 발생하면, CPU가 I/O device의 local buffer에 접근해서 해당 데이터를 memory 공간에 복사해와야 함
- memory에 접근할 수 있는 장치를 하나 더 생성 : DMA controller
- CPU는 계속 자신의 일을 하고 있도록 함
- local buffer에 들어온 내용이 작업이 끝났으면 DMA가 직접 해당 data를 메모리에 복사하는 일까지 담당
- memory에 접근하는 것이 2개가 되었으므로, 관리 필요
- 둘이서 특정 메모리 영역을 동시에 접근하면 문제가 생길 수 있으므로, memory controller가 이를 중재
- 이 일이 끝났으면 CPU에 interrupt를 한번만 걸어서, 해당 작업이 완료되었음을 보고
CPU와 Disk의 실행 코드
- Program Counter(PC) register가 CPU가 실행해야 하는 instruction의 메모리 주소를 가지고 있음. 그것을 실행하는 것이 CPU의 숙명
- 그 instruction 중, I/O device에 접근해야 하는 경우가 생기면 device driver를 통해서 device에 읽거나 쓰기 명령을 하게 됨
- device driver는 실제로 disk에서 head를 움직여서 읽고 쓰게 하는 코드는 아님
- 그 코드는 disk controller가 해당 코드의 지시를 받아서 일을 하게 됨
- CPU는 본인이 직접 일을 하는 것은 아니고, memory에 있는 instruction의 지시를 받아서 매번 일을 하게 됨
- device driver도 본인이 일을 하기 위해서는 매뉴얼이 있음(disk 내의 펌웨어 : device를 동작하기 위해서는 어떤 일을 해야하는지에 대한 실행하는 instruction code)
- device driver는 CPU가 실행하는 코드 (장치를 실행하기 위해서 필요한 코드)를 담고 있음
- CPU는 직접 일을 할 수 없고 매뉴얼대로 일을 함
- 매뉴얼에는 메모리 몇번지에 있는 일을 하라고 적혀있음
- 이에 대한 전체적인 통제는 OS가 함
입출력(I/O)의 수행
- 모든 입출력 명령은 특권 명령
- 특권명령 : OS만 할 수 있는(Mode bit 0일때만 할 수 있는) instruction
- 즉, 사용자 프로그램이 직접 I/O를 하지 못하고, OS를 통해서만 I/O 장치에 접근할 수 있음.
- 사용자 프로그램이 disk에서 어떤 파일을 읽어와야 하는 경우 어떻게 하는가?
- 시스템콜(system call) : 운영체제에게 요청
- 사용자 프로그램을 실행하다보면 함수 호출을 하는 경우가 있다.
- 프로그램 안에서 함수 호출을 하는 것은 프로그램 내에서 메모리 주소를 바꾸면 됨
- 그런데 내 프로그램의 함수를 실행하다가 I/O 요청을 하기 위해 OS의 함수를 호출(system call)하는 것은 그냥 메모리 주소를 바꾸어서 되는 일은 아니고, 조금 더 복잡함
- I/O를 해야할 때는 직접 OS로 주소 점프를 할 수 없음
- 왜냐하면 나는 지금 사용자 프로그램이기 때문(mode bit이 1임)
- 자신의 프로그램 메모리 주소 안에서만 점프가 가능하고, 함수 호출이 가능함
- I/O를 하기 위해 운영체제에 해당하는 주소로 넘어가야 함
- but mode bit이 1일때는 접근이 허용이 안됨
- device controller들이 CPU에 interrupt를 거는 방식으로 system call을 함
- 프로그램이 직접 interrupt line을 세팅하는 instruction을 세팅함
- CPU는 다음 instruction을 실행하기 이전에 interrupt가 들어왔으므로 mode bit이 0으로 바뀌고 CPU 제어권이 OS로 넘어감
- OS는 올바른 I/O 요청인지 확인 후 I/O 수행
- I/O 완료 시 하드웨어 인터럽트가 걸림 → 제어권을 시스템 콜 다음 명령으로 옮김
- 즉, I/O를 하기 위해서 필요한 인터럽트는 2개임 (소프트웨어 인터럽트 / 하드웨어 인터럽트)
Interrupt
- interrupt는 하드웨어 일꾼들이 CPU에게 정보 교신을 위해 걸수도 있고, 사용자 프로그램이 OS에 요청해야 하는 일을 할 때도 interrupt line을 세팅할 수도 있음
- Interrupt (하드웨어 인터럽트) : 하드웨어가 발생시킨 인터럽트 / 좁은 의미의 interrupt
- Trap (소프트웨어 인터럽트)
- Exception : 프로그램이 오류를 범한 경우
- System call : 프로그램이 커널 함수를 호출하는 경우
현대의 운영체제는 인터럽트에 의해서 구동된다.
- OS는 CPU를 잡을 일이 없다.
- interrupt가 들어올 때만 CPU가 OS로 넘어간다.
- 그렇지 않으면 CPU는 항상 사용자프로그램이 쓴다.
- 인터럽트의 종류가 굉장히 많음.
- 각각의 인터럽트 종류마다 OS가 해야할 일이 다름.
- 각 인터럽트의 종류마다 무슨 일을 해야 하는지가 OS code에 정의되어 있음
- 각 인터럽트마다 실제로 처리해야 하는 코드 : 인터럽트 처리 루틴(Interrupt Service Routine, 인터럽트 핸들러)
- 어떤 인터럽트가 들어왔을 때 어떤 함수로 가야하는지 표시 : 인터럽트 벡터
- 인터럽트 종류마다 그 인터럽트가 생겼을 때 어떤 함수를 실행해야 하는지, 함수의 주소들을 정의해둔 일종의 table
System call
: 사용자 프로그램이 I/O 등 (OS에게 뭔가를 부탁할 때) OS의 서비스를 받기 위해 커널 함수를 호출하는 것
질문
-
DMA를 사용하면 CPU가 interrupt 당하는 빈도가 줄어드는 이유? local buffer -> memory로 복사하는 instruction을 실행하지 않아도 되는 것이지, 빈도는 그대로이지 않나?
- 4강 참조
- I/O 작업 하나하나마다 interrupt를 거는 방식이 아니라, block 단위로 data를 쌓고, 이것을 DMA가 Memory로 카피하는 방식으로 진행됨. 따라서 기존의 byte 단위로 interrupt를 거는 방식보다 interrupt 빈도가 줄어들게 됨
-
위 작업(복사)를 CPU가 하지 않는다면, 결국 OS가 하는 일은 무엇인가
- 5강 참조
- I/O 작업이 끝나고나면 해당 프로세스의 상태를 blocked -> ready로 변경하는 등의 작업을 수행함
-
펌웨어의 개념
참고 링크
KOCW 운영체제 - 이화여대 반효경 교수 (2014-1) 3강