core.ewha.ac.kr/publicview/C0101020140314151238067290?vmode=f

 

반효경 [운영체제] 4. System Structure & Program Execution 2

설명이 없습니다.

core.ewha.ac.kr

 

 

io 작업, exception 이 났을때 process는 trap(interrupt)을 걸어 os 에게 cpu 를 넘긴다.

 

 

 

synchronous IO :

 사용자 process 에서 io 가 발생하면 cpu 가 os 에게 넘어감

 os 는 io 명령을 수행하고 io 응답이 올 때 까지 기다림(cpu 는 아직도 os 에게 있음)

 io 응답이 오면 그제서야 사용자 process memory 에 결과를 넣고

 사용자 process 에게 cpu 를 돌려줌.

 ....cpu 낭비가 어마무시하군. 또한 매시점 하나의 io 만 일어나기 때문에 다른 io 디바이스들도 노는 꼴이 됨.

 

 그래서 io 명령을 수행한 후 응답을 기다리지 않고, 다른 process 에게 cpu 를 넘겨준다고 함.

 cpu (와 io 디바이스들)가 놀지 않게 하기 위해.

 io 응답이 오면 사용자 process memory 에 결과를 넣고

 (다른, 혹은 io를 발생시킨) process 에게 cpu 를 돌려줌.

 

asynchronous IO :

 A라는 사용자 process 에서 io 가 발생하면 cpu 가 os 에게 넘어감

 os 는 io 명령을 수행하고, io 응답이 오는 걸 기다리지 않고 바로 A process 에게 다시 cpu 를 넘김

 io 응답이 오면 interrupt 가 걸리고, os 는 해당 처리를 한 다음 다시 A process 에게 cpu 를 넘김.

 

JAVA 프로그램을 예로 들어 쉽게 설명하자면,

동기식 입출력은 io 를 요청한 후 process가 멈춤. io 응답이 오면 그제서야 process가 계속됨.

여기서 process 가 계속 멈춰있으면 cpu 가 놀게 되니까, 그 때 다른 process 에게 cpu 를 줄 수 있음.

비동기식 입출력은 io 를 요청한 후 응답이 오든 말든 process 는 다음 명령을 계속 수행함.

io 응답이 오면 응답 결과를 가지고 다시 일처리를 하겠지.

 

 

 

 

컴퓨터에 DMA(Direct Memory Access) 라는 장치가 있음.

io 디바이스들이 하도 cpu 에 interrupt 를 여러번 거니까 cpu 효율이 나빠짐.

DMA 는 cpu 가 받는 io interrupt 들을 자신이 받아 미리 처리하고(memory 에 io 응답값을 넣는 등)

cpu 에게는 "일을 내가 거의 끝내놨다. 너는 마무리 작업을 해라" 라고 말하며

cpu 에게 한 번만 interrupt 를 걸어줌.

이렇게 cpu 의 부담을 줄여주는 것이 DMA.

 

예를 들어 키보드의 키 하나를 누르면 1byte 정보가 키보드 버퍼에 쌓이고

키보드의 device controller 가 cpu 에 interrupt 를 걸어

메모리 내로 방금 생성한 1byte 정보를 복사하라고 요청

이런 방식으로 키보드를 사용하면 수많은 interrupt 들이 생성될텐데,

이 interrupt 들이 계속 cpu 를 방해하면 성능이 떨어짐.

DMA 는 이런 상황에서 필요함.

DMA 는 키보드에서 생성한 1byte 에 대한 interrupt 를 자신이 받아서

메모리에 직접 정보를 넣음.

메모리에 넣은 정보가 특정 단위(페이지 혹은 블럭)를 넘어서면 그제서야 DMA 가

cpu 에게 "네가 할 일 내가 미리 끝내놓음. 나머지 작업 네가 처리하셈" 라고 말하며

cpu 에게 한 번 interrupt 를 걸어줌.

DMA 덕분에 cpu 가 interrupt 당하는 빈도가 줄어 성능이 향상됨.

 

DMA 는 메모리에 직접 접근이 가능함(그래서 io 응답 처리가 가능함)

 

 

 

 

아래는 프로그램이 어떻게 실행되는지 그 절차를 설명함.

 

 

- 프로그램은 실행파일 형태(binary)로 disk 에 저장되어 있음.

- 프로그램이 실행되면 프로그램의 binary 가 memory 에 올라가게 됨.

- memory 에 올라갈 때, 각 프로그램들은 memory에 각자의 memory 공간을 할당받게 됨.

  (프로그램이 memory 에 올라가 있어야 cpu 가 실행할 수 있으니까)

- memory 공간은 주소를 갖고 있음

- 각 프로그램들이 할당받은 공간의 주소는10, 예를들어

  프로그램A는 2553~6754 이고 프로그램 B는 88552~91502, 12204~53582

  이렇게 예쁘지 않은 주소 공간임. 게다가 나란히 존재하지 않고 쪼개져 있을 가능성이 농후함

- 하지만 각 프로그램 입장에서는 아주 예쁘게 0부터 1024 처럼 정렬된 공간처럼 보임.

  이것이 virtual memory 

- 프로그램은 자신을 실행시키기 위해 할당받은 메모리 공간에 code, data, stack 영역으로 나눈 후

  각 영역의 역할에 맞게 사용.

- code : cpu 에서 실행할 기계어 코드를 넣음.

- data : code 에서 실행할 전역변수 등을 넣는 영역으로 사용.

- stack : code 가 동작할 때 사용하는 stack 영역(함수를 실행하는 데 사용하는 stack 영역) 으로 사용.

- 흔히 쓰이는 JAVA 프로그램의 경우 할당받은 메모리 공간을 메소드, 스택, 힙 영역으로 나눠서 사용.

  [여기] 링크에서 구체적으로 확인 가능.

- 각 프로그램이 할당받은 메모리 공간이 모두 memory 를 차지하고 있지 않음(모두 메모리에 올라가 있지 않음)

- 각 프로그램에서 실제 사용해야 하는 부분만 메모리에 올림.

  다 올리면 프로그램에서 안 사용하는 부분까지 올라가게 되어 메모리가 낭비되니까. 

- 그럼 메모리 공간에 올라가지 않은 나머지 프로그램부분은 어디에 있을까? 아직 disk 에 있다.

- 즉, disk 에서 프로그램이 실행을 위해 필요한 부분만 읽어 메모리에 넣은 다음 cpu 를 통해 실행시키는 것.

- 다르게 말하면, 메모리에 올라가 있는 프로그램 부분 중에 안 사용하는 부분은 메모리에서 내려와서

  다시 disk 로 돌아감

- 커널 역시 프로그램(상시 돌아가는 process)이기 때문에 자신의 메모리 주소 공간을 갖고 있음

  위 이미지에서 흰 색 박스 부분.

 

 

 

 

커널은 os 라서 중요하니까

커널의 주소 공간 내용을 구체적으로 살펴보자.

 

 

커널의 코드 부분에는 다음과 같은 코드들이 들어있음.

- 각 interrupt 를 처리하기 위한 코드(interrutpt 처리 루틴

- 자원 관리를 위한 코드

- 사용자에게 제공하는 인터페이스 코드

 

data 부분에는 cpu, memory 등 자원 관리하기 위한 자료구조 들이 들어있음.

또한 동작하는 process 들을 관리하기 위한 자료구조(PCB) 들이 들어있음.

예를 들어 process A 가 cpu 를 얼마나 썼는지, 다음 process 에게 메모리는 얼마나 줘야 하는지 등

이걸 보고 PCB(Process Control Block) 이라고 함.

프로그램마다 PCB 가 하나씩 만들어져서 os 가 관리함.

그리고 그것이 (위 그림처럼) data 영역에 들어있음.

 

os(kernel) 역시 함수 구조로 짜여있기 때문에 함수나 return 등의 구조를 사용하기 위한 stack 영역을 사용.

사용자 process 들이 os 에 system call 을 하면 그것을 각 process 당 커널 스택으로 정리함.

예를 들어 process A 가 system call 을 하고 process B 역시 system call 을 하면

그것들을 각 process 에 맞게 process A 의 커널스택, process B 의 커널스택으로 관리한다고 함.

... 솔직히 이해는 안 가는데 자세한 내용을 뒤에서 한다고 함.

 

 

 

 

프로그램은 함수로 이루어짐.

C로 짜든 JAVA 로 짜든 프로그램은 함수로 구성됨.

프로그램을 구성하는 함수는 총 세 가지 종류가 있음.

 

- 사용자 정의 함수 : 코드 내에 사용자가 직접 만든 함수. myfunc 같은 ㅋㅋ

- 라이브러리 함수 : 라이브러리를 통해 불러온(import) 함수 혹은 내장 함수.

- 커널 함수 : os 가 정의함, os 프로그램의 함수. 즉 system call.

  예를 들어 read("/home/eyeballs/README.md") 라는 함수를 실행하면

  해당 path 의 file 을 읽어달라는 명령이 실행되는데

  이 때 system call 이 불림. 이 system call 에 의해 실행되는 (실질적으로 device 에 가서 읽는) 함수는

  os 에서 제공해주는 함수임.

 

사용자 정의 함수, 라이브러리 함수는 process 가 할당받은 메모리 공간의 code 영역에 들어감.

커널 함수는 os 이 갖고 있는 kernal 메모리 공간의 code 영역에 들어감.

 

따라서 사용자 정의 함수, 라이브러리 함수를 실행할 때는

cpu interrupt 가 걸리지 않고 자기 메모리 공간 내에서 계속 실행이 가능

커널 함수(system call)를 실행할 때는 interrupt 가 걸림.

 

아래 이미지는 프로그램을 실행시키는 절차를 보여준다.

 

 

빨간색 선은 프로그램이 cpu 를 잡고 있을 때

파란색 선은 os(커널)가 cpu 를 잡고 있을 때

 

 

 

+ Recent posts