일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 삼성기출
- 완전탐색
- exec
- fork
- Deadlock
- higunnew
- 알고리즘
- 구현
- 프로세스
- 시뮬레이션
- BOJ
- samsung research
- 가상메모리
- 삼성리서치
- 백트래킹
- ascii_easy
- 동기화문제
- 스케줄링
- segmentation
- pwnable.kr
- dfs
- 김건우
- 컴공복전
- 운영체제
- Brute Force
- Memory Management
- paging
- 데드락
- BFS
- 백준
- Today
- Total
gunnew의 잡설
1강. 시스템 구조 본문
컴퓨터의 구조는 다음 그림과 같이 간단하게 나타낼 수 있다.
먼저 CPU는 메모리 하고만 일할 수 있다. 그러니까 오른쪽에 있는 I/O device와는 일할 수 없다. CPU는 정말 정말 빠른 속도로 일하는데 반해 I/O device와 같은 친구들은 너무나 느리기 때문에 같이 일을 하지 않는다고 생각하면 편하다. 그렇다고 해서 CPU가 정말 똑똑한 아이냐? 그렇게 말할 수는 없다. 단지 CPU는 매 클럭마다 메모리(Memory)에서 다음 instruction만 읽어 들여 그 일을 정말 빠르게 수행할 뿐이다. 이러한 이유로 사용자가 하드 디스크로부터의 파일 입출력이나 표준 입출력(키보드, 모니터를 이용한 입출력)과 같은 일들은 CPU가 담당하지 않고 device controller라는 각 device에 붙어있는 컨트롤러에게 그 일을 전담하게 한다. I/O device에게 입출력을 하라는 명령이 들어오면 진행하며 나타나는 데이터들을 자신의 local buffer에다가 저장을 시킨다. 물론 그 와중에 CPU는 계속해서 다른 일을 하게 되는 것이다.
왜 CPU가 직접 처리를 하지 않고 계속해서 다른 일을 하게 할까? 그것은 가장 성능이 좋은 하드웨어(CPU)의 효율성의 문제와 연결되어 있다. CPU의 속도는 흔히 1.6 GHz ~ 3.0 GHz의 속도를 가지고 있는데 이는 1초에 16억~30억 회의 연산이 실행될 수 있음을 의미한다. 그런데 우리가 타자를 치는 속도를 생각해보자. 기껏해야 1초에 2-3자 정도일 것이다. 그래서 CPU는 입출력과 같이 느린 일들을 직접 처리하지 않는다.
그렇다면 I/O의 느린 속도와 같은 문제만 해결한다면 CPU를 효율적으로 가동하게 할 수 있을까? 당연히 아닐 것이다. 예를 들어 우리가 무한 루프를 돌며 연산하는 프로그램을 작성했다고 가정하자. 만약 CPU가 한 프로그램을 실행하는데 중간에 어떤 방해 없이 온전히 그 프로그램만 다루어야 한다면, CPU입장에서는 한 평생을 그 프로그램에 전념하고도 끝낼 수 없는 림보 상태에 빠지게 될 것이다. 이를 해결하기 위해 등장한 것이 timer와 interrupt이다.
timer는 특정 임계치 값을 세팅하고 OS가 해당 프로그램에게 CPU를 넘겨주게 된다.(이 개념은 다음 강부터 자세히 설명될 예정) 세팅된 시간이 되면 timer가 interrupt를 걸고 cpu에게 알려주게 된다. interrupt는 단어 그대로 방해를 하는 것이다. 그러니까 한 프로그램이 CPU를 하루종일 붙잡게 되는 것을 방지하게 되는 것이다. CPU가 interrupt를 체크하는 과정은 다음과 같다. CPU의 instruction이 끝나고 나면 interrupt line 체크하는 데 이 때 interrupt가 있으면 cpu 제어권이 사용자 프로그램으로부터 자동으로 OS로 넘어가게 된다. 만약 timer에 세팅된 시간이 다 끝나게 되어 interrupt가 걸렸다면 이도 마찬가지로 CPU가 OS로 그 소유권이 넘어간다.(CPU 소유권에 대한 것은 추후에 설명) OS가 CPU를 사용자 프로그램에게 줄 땐 자유롭게 주지만 한 번 넘어가면 뺏을 수 없다.
다시 I/O와 관련한 이야기를 해보자. 결론부터 말하면 사용자 프로그램은 보안상의 이유로 자신이 할당받지 않은 공간에 접근하는 것이 금지된다. 나쁜 짓을 할 수도 있기 때문이다. 그래서 사용자 프로그램에서 I/O와 관련된 코드에 도달하면 자진해서 프로그램이 운영체제한테 CPU를 I/O 해달라고 넘겨준다. 그러니까 사용자 프로그램은 본인이 I/O device에 접근할 수 없다는 것이다.
이 때, IO가 오래 걸리니까 요청한 사용자 프로그램이 아니라 다른 프로그램한테 CPU 넘겨주게 된다. 그러면 그 넘겨준 사용자 프로그램은 언제까지 기다리느냐? 요청한 작업이 끝나서 local buffer에 들어오면, device controller가 CPU한테 interrupt를 걸고 OS가 CPU한테 넘어가는데 이때 어떤 것 때문에 interrupt가 일어났는지를 판별하게 된다. 만약 I/O 때문이었다면 입력된 값을 요청한 프로그램 메모리 공간에 카피를 해주고, 방금 전에 interrupt 당한 프로그램한테 timer가 남아있다면 다시 넘겨준다. 그러고 나서 해당 timer가 끝나면 I/O를 요청했던 프로그램에게 CPU를 넘겨준다.
Mode bit |
추가로 설명해야 할 개념은 mode bit이다. 크게 어렵지 않으므로 간단하게 설명하자면 다음과 같다.
0 : 모니터모드(kernel mode, system mode) OS 코드를 수행함. 0일 때는 모든 작업을 수행할 수 있게 함. 메모리 접근, IO 장치 접근 등
1 : 사용자모드(사용자 프로그램 수행)
제한된 instruction만 할 수 있게 함.(IO 접근 불가, 다른 프로그램 메모리 공간, OS 메모리 공간 침범 등등 불가)
Timer |
Timer에 대해서는 I/O를 어떻게 처리하는지에 대해 설명하며 이미 언급하였기 때문에 간단히 설명하고 넘어가겠다. 정해진 시간이 흐른 뒤 운영체제에게 제어권이 넘어가도록 interrupt 발생시킨다. 타이머는 매 클럭 틱마다 1씩 감소하는데 타이머 값이 0이 되면 타이머 interrupt를 발생시켜 CPU를 특정 프로그램이 독점하는 것으로부터 보호한다. Timer 는 time sharing을 구현하기 위해 이용된다.
Device Controller |
I/O device controller 해당 I/O 장치를 관리하는 일종의 작은 CPU라고 생각하면 된다. 제어 정보를 위해 control register, status register를 가지며, 데이터를 저장하기 위해 local buffer를 가진다.(일종의 data register) 이렇게 보면 CPU의 구조와 크게 다르지 않다는 것을 확인할 수 있다. 위에서도 설명했듯 I/O는 실제 device와 local buffer 사이에서 일어나고 device controller는 I/O가 끝났을 경우 interrupt로 CPU에 그 사실을 알리게 된다.
Device driver(장치구동기) |
Device driver는 Device controller와는 다르다. controller는 하드웨어이며 driver는 소프트웨어이다. 우리는 흔히 프린트 드라이버, 핸드폰 드라이버 등 많은 드라이버를 인터넷에서 다운로드하여 썼던 경험이 있을 것이다. Device와 컴퓨터를 연결하기 위해 만들어진 소프트웨어이며 OS코드 중 각 장치별로 처리하기 위한 인터페이스가 있는데 그것에 맞게 처리 루틴이 되어 있어 이 드라이버가 있어야만 해당 장치를 이용하여 프로그램 진행을 할 수 있게 된다.
DMA Controller (Direct Memory Access) |
원래는 메모리에 접근할 수 있는 장치는 CPU 뿐이었는데DMA를 두면 DMA도 메모리에 접근 가능하게 된다. 이 개념은 다음 장에서 조금 더 자세하게 설명할 예정이다. 간단히 설명하자면, I/O 장치들이 매번 interrupt를 걸면 overhead가 발생하니까 CPU가 비효율적이 되기 때문에 CPU는 계속 자기 일을 하고 있고, DMA가 적절히 조율해서 CPU한테 한 번만 interrupt를 걸게 하는 일을 담당한다.
입출력 (I/O) 수행 |
모든 입출력 명령은 특권 명령이다. (사용자 프로그램이 하지 못함) 한참 동안 설명했지만 I/O를 하는 과정은 다음과 같다.
- 시스템 콜(system call) : 운영체제 커널을 호출한다. 즉, OS한테 부탁하는 것인데 일반 함수 호출과는 다름. 그냥 메모리 주소만 바꿔서 점프하는 게 아니다. (이것은 당장 이해하기 어렵기 때문에 나중에 설명하겠다.) device controller들이 CPU한테 interrupt를 하는 것처럼 직접 OS로 점프 불가능하다. (사용자 프로그램 내부에서만 점프 가능하기 때문에, 즉, mode bit이 1) 따라서 프로그램이 직접 interrupt line을 세팅하는 instruction을 실행함. 이것을 Trap이라고 하며 Software Interrupt라고도 부른다. Trap을 사용하여 인터럽트 벡터의 특정 위치로 이동하며 CPU 제어권이 인터럽트 벡터가 가리키는 인터럽트 서비스 루틴으로 이동한다. 이후에 올바른 I/O 요청인지 확인 후 I/O를 수행하게 되고, I/O 완료 시 제어권을 시스템 콜 다음 명령으로 옮기게 되는데, 이때 하드웨어 인터럽트가 걸려야 한다. 즉, device controller가 인터럽트를 걸게 되는 것이다.
요컨대 CPU는 Program Counter라는 cpu register에 다음번에 어디에 있는 instruction을 실행해야 하는지 정보를 가지고 있다. 그 instruction 중에서 I/O장치를 접근해야 하는 상황이 되면 device drive를 통해서 device controller를 동작시킨다. Device driver도 본인이 일을 하기 위해서는 driver가 아니라 Disk안에 Firmware를 작동시켜 device controller를 동작시킨다.
CPU는 스스로 뭔가 일을 하는 게 아니라 manual대로 일을 하는 기계이다. 그 manual에는 memory 몇 번지에 있는 일을 하라는 게 적혀있을 뿐이다. 그 통제의 모든 것은 운영체제 OS가 하는 것이다.
인터럽트(Interrupt) |
이미 인터럽트에 관한 논의는 위에서 모두 끝냈다. 설명은 다음 캡처로 대체한다. 하나하나 따라왔다면 충분히 이해할 수 있을 것이다.
본 포스트는 반효경 교수님의 운영체제 오픈 강의를 기반으로 작성됩니다.
링크 : http://www.kocw.net/home/search/kemView.do?kemId=1046323
'Operating System' 카테고리의 다른 글
5-1강. 프로세스 관리(Process Management) (0) | 2020.01.23 |
---|---|
4강. 스레드(Thread) (0) | 2020.01.22 |
3-2강. 프로세스(Cont'd) (0) | 2020.01.21 |
3-1강. 프로세스 (0) | 2020.01.21 |
2강. 프로그램의 실행 (0) | 2020.01.21 |