본문 바로가기
Computer Science/OS

[OS] 프로그램의 구조와 실행

by soobaaaam 2021. 11. 18.
728x90

<동기식 입출력과 비동기식 입출력>

 

출처 : 이화여자대학교 반효경 교수님 '운영체제' 강의

 

 1. 동기식 입출력 (Synchronous)

 

 동기식 입출력에서는 I/O를 요청 후 입출력 작업이 완료된 후에야 제어가 사용자 프로그램에게 넘어간다.

 

 I/O는 커널을 통해서만 할 수 있다. 사용자 프로그램이 I/O 요청을 커널에게 하면, 그 I/O 장치에 맞는 디바이스 드라이버를 거치고 실제 하드웨어를 통해서 I/O를 한다.

 I/O는 시간이 걸리는 작업이기에 어느 정도 시간이 흐른 뒤에야 I/O가 끝난 것이 도착하고, 이를 보고 사용자가 다음 작업을 한다.

 동기식 입출력에서는 I/O 작업이 끝날 때까지 아무 일도 안 하고 기다려야 하므로 CPU가 낭비된다. 매 시점 하나의 I/O만 일어나기 때문에 I/O 장치도 낭비된다.

 

2. 비동기식 입출력 (Asynchronous)

 

 사용자 프로그램이 I/O 요청을 커널에게 하고, I/O 작업이 진행되면 이를 기다리지 않고 CPU를 얻어서 다른 작업을 한다.

 마찬가지로 I/O가 끝나면 이를 알린다.

 

 

 * 동기식 입출력, 비동기식 입출력 모두에서 I/O가 끝났음을 인터럽트를 통해 알려준다.

 

 

<DMA (Direct Memory Access) >

 

 DMA는 메모리에 접근할 수 있는 장치이다.

 원래 메모리에 접근 가능한 장치는 CPU 밖에 없기 때문에 I/O 장치들이 CPU와 교신해야 할 때는 인터럽트를 걸어준다.

 그러나 매번 I/O 마다 인터럽트가 걸리면 CPU가 인터럽트를 너무 많이 당하게 된다. 인터럽트를 당하면 사용자 프로그램이 실행되는 도중에 하던 일을 멈추기 때문에 상당한 오버헤드가 뒤따른다. 즉, CPU가 효율적으로 동작할 수 없다.

 그래서 DMA를 통해 작은 일들은 한데 모아 한번에 CPU에게 인터럽트를 걸어준다. CPU의 인터럽트가 당하는 빈도가 적어지므로 보다 효율적으로 동작할 수 있다.

 

 

<서로 다른 입출력 명령어>

 

 CPU에서 실행할 수 있는 instruction에는 메모리만 접근하는 instruction과 I/O 장치에 접근해야 하는 instruction이 있다.

 

 일반적으로 두 개의 instruction은 별개로 정의되어 있다. I/O 디바이스에도 주소가 있어서 특정 주소에 대해서 I/O 장치에 접근하는 instruction을 실행하면 해당 디바이스에 접근할 수 있다.

 하지만 Memory Mapped I/O 라는 것에서는 I/O 디바이스들에게 메모리 주소를 줘서, 메모리에 접근하는 instruction을 통해서 I/O를 할 수 있게 된다.

 

 

<저장 장치 계층 구조>

 

 

출처 : 이화여자대학교 반효경 교수님 '운영체제' 강의

 

- Primary : CPU에 직접 접근할 수 있는 메모리 Storage 매체 (바이트 단위 접근이 가능하다).

- Secondary : CPU에서 직접 접근해서 처리하지 못하는 것들

 

 저장 장치의 계층 구조에는 세 가지 특징이 있다.

 

1. Speed

 계층의 위로 갈수록 속도가 빠른 매체를 사용한다.

2. Cost

 계층의 위로 갈수록 단위 공간 당 가격이 비싸기 때문에 용량이 적어진다.

3. Volatility

 위쪽의 Registers, Cache Memory, Main Memory는 휘발성이며, 아래쪽의 Magnetic Disk, Optical Disk, Magnetic Tape은 비휘발성이다.

 

 

 

 * Caching : 빠른 매체로 정보를 읽어들여서 쓰는 것. 재사용을 목적으로 한다. 처음 요청 때는 필연적으로 아래에서 위로 데이터를 읽어 간다. 그러나 일단 한 번 위로 읽어 들여놓으면 같은 것을 두 번째 요청할 땐 밑에까지 가지 않고 위에서 바로 읽을 수 있다.

 

<프로그램의 실행 (메모리 load) >

 

출처 : 이화여자대학교 반효경 교수님 '운영체제' 강의

 

 프로그램은 실행파일 형태로 하드디스크에 저장되어 있다.

 실행파일을 실행시키면 메모리에 올라가서 '프로세스'가 되고 실행이 되는 것이다.

 그러나 물리적인 메모리에 바로 올라가는 것이 아니라 중간에 한 단계를 더 거친다. 그 단계가 바로 virtual memory이다.

 

출처 : 이화여자대학교 반효경 교수님 '운영체제' 강의

 

 어떤 프로그램을 실행시키면 그 프로그램의 주소 공간(address space)이 형성된다.

 프로그램마다 0번지부터 시작되는 독자적인 주소 공간이 만들어지는 것이다.

 주소 공간은 code, data, stack 영역으로 구성된다.

 

- code : CPU에서 실행할 기계어 코드를 담는다.

- data : 변수 등 프로그램이 사용하는 자료구조를 담는다.

- stack : code는 함수 구조로 되어 있는데, 함수를 호출하거나 return 할 때 어떤 데이터를 쌓았다가 꺼내는 용도로 사용된다.

 

 주소 공간의 내용들을 물리적인 메모리(physical memory)에 올려서 실행시킨다.

 그러나 프로그램의 주소 공간을 물리적인 메모리에 통째로 다 올려놓는 것이 아니라(메모리 낭비), 당장 필요한 부분만 올려놓는다.

 필요하지 않은 부분은 swap area라는 디스크 공간에 내려놓는다.

 

 

<커널 주소 공간의 내용>

 

커널도 하나의 프로그램이기 때문에 code, data, stack으로 이루어진 주소 공간으로 구성되어 있다.

 

출처 : 이화여자대학교 반효경 교수님 '운영체제' 강의

 

1. code

 자원을 효율적으로 관리하기 위한 코드, 사용자에게 편리한 인터페이스를 제공하는 코드가 있다.

 또한 인터럽트를 받으면 CPU를 얻게 되는데, 각각 인터럽트마다 무슨 일을 처리해야 하는지에 대한 코드도 있다.

2. data

 운영체제가 사용하는 여러 자료구조

 운영체제는 CPU, memory, disk 같은 하드웨어를 직접 관리하고 통제하는데, 이런 하드웨어를 관리하기 위해 하드웨어 종류마다 자료구조를 하나씩 만들어서 관리한다.

3. stack

 운영체제도 함수 구조로 code가 짜여 있으므로 함수를 호출하거나 return할 때 이 stack 영역을 사용해야 한다.

 어떤 사용자 프로그램이 커널 코드를 실행 중인가에 따라서, 즉 사용자 프로그램마다 커널 스택을 따로 둔다.

 

 

<사용자 프로그램이 사용하는 함수>

 

모든 프로그램은 함수 구조로 짜여져 있다. 

함수의 종류는 총 세 가지이다.

 

1. 사용자 정의 함수

 내가 만든 프로그램에서 직접 작성한 함수이다.

 

2. 라이브러리 함수

 기능이 유용해서 누군가 만들어 놓은 함수이다. 이를 가져다 쓰기만 하면 된다.

 

3. 커널 함수

 운영체제 안에서 정의된 함수이다. 

 

 

* 사용자 정의 함수와 라이브러리 함수는 컴파일해서 실행파일을 만들면, 실행파일 안에 이 함수들이 포함되어 있다.

* 그러나 커널 함수는 내 프로그램 안에 있지 않고, 커널 코드 안에 들어 있다.

 

 

<프로그램의 실행>

 

 

출처 : 이화여자대학교 반효경 교수님 '운영체제' 강의

 

 위 그림은 A 프로그램의 시작부터 종료까지의 과정을 나타낸다.

 

1. user mode

 프로그램이 직접 CPU를 잡고 있는 상태이다.

2. kernel mode

 시스템 콜을 하면 프로그램의 주소 공간의 code가 아니라, 운영체제 커널의 code가 실행된다.

3. user mode

 시스템 콜이 끝나면 A에게 다시 CPU 제어권이 넘어온다. 본인의 주소 공간의 code가 실행된다.

4. kernel mode

 다시 시스템 콜을 하면 CPU 제어권이 커널로 넘어간다.

 

 


* 본 글은 이화여자대학교 반효경 교수님 강의 '운영체제와 정보기술의 원리(반효경 지음)' 서적에 기반하여 작성하였습니다.