티스토리 뷰

반응형

안녕하세요 Pingu입니다!

 

지난 글까지는 CPU 가상화에 대해 알아봤고 이번 글부터는 메모리 가상화에 대해 알아보려고 합니다! 이번 글에서는 메모리 가상화의 목적과 메모리 가상화를 위한 메모리 사용의 변화 과정, 주소 공간을 추상화하는 개념에 대해 알아보려고 합니다. 제가 공부할 때 참고하고 있는 OSTEP 책에선 Chapter 13 - Address Space부분입니다. 

The Abstraction: Address Spaces

그럼 초기의 컴퓨터에서 지금의 컴퓨터로 발전하는 과정을 메모리 사용 관점에서 살펴보도록 하겠습니다.

Early Systems

메모리의 관점에서 보면 초기의 컴퓨터는 사용자에게 추상화를 지금처럼 많이 제공하지 않았습니다.

이게 초기 컴퓨터의 메모리 구성입니다. 위와 같이 OS와 현재 사용 중인 프로그램의 데이터가 올라가 있을 뿐 다른 복잡한 건 보이지 않습니다. OS는 메모리의 시작 주소부터 메모리를 사용하고 있으며 OS가 사용 중인 메모리 다음에는 바로 현재 실행 중인 프로그램이 메모리를 사용 중입니다. 이때 프로세스의 수는 하나입니다. 즉 위의 메모리 상태는 OS와 프로세스 하나만 실행 중인 것입니다. 즉 프로그램을 동시에 하나만 실행했기 때문에 이렇게 메모리를 단순하게 사용하더라도 문제가 없었습니다. 하지만 저희가 CPU 가상화 단원에서도 알아봤듯 요즘 컴퓨터는 여러 개의 프로그램을 동시에 실행하기 때문에 위의 방법은 발전이 필요합니다.

 

Multiprogramming and Time Sharing

즉 지금까지 공부한 대로 컴퓨터는 여러 개의 프로세스를 동시에 실행하기 때문에 아까처럼 메모리를 사용하면 안 됩니다. 따라서 CPU 가상화 부분에서 배운 time sharing 기법을 사용해서 여러 개의 프로세스를 동시에 실행해야겠죠? 그런데 CPU는 어떻게 가상화하는지를 알아봤었는데 메모리는 어떻게 가상화를 해서 여러 개의 프로세스를 실행할 수 있을까요? 혹시나 잊으셨을까 봐 CPU 가상화를 간단하게 설명하면, CPU는 실제로는 1개인데 여러 개의 프로세스들은 마치 CPU가 여러 개 인 것으로 착각해서 사용자가 볼 때는 여러 프로세스가 동시에 실행되는 것처럼 보이게 하는 것입니다. 그렇다면 메모리 가상화는 어떨까요? 메모리 가상화도 똑같이 실제로 메모리는 한 개뿐이지만 프로세스들은 마치 여러 개의 메모리가 있다고 착각하게 만드는 거예요!

실제로 메모리 가상화를 하면 위의 그림과 같이 여러 개의 프로세스들이 메모리의 일정 부분을 함께 사용하게 됩니다. 위의 그림과 같이 말이죠! 그런데 이렇게 여러 프로세스들이 한 번에 메모리에 존재하게 되면 보안 상 문제가 발생할 수 있습니다. 예를 들어 C 프로세스의 경우 128KB~192KB에 있는 데이터에만 접근해야 하는데 갑자기 B 프로세스의 메모리 공간에 침입해서 데이터를 조작하게 되면 이는 큰 보안상 문제입니다. 따라서 이러한 문제를 잘 해결해야 하는 과제가 있습니다. 실제로 이렇게 자신의 메모리 공간 말고 다른 공간에 접근하려고 하면 Segmentation Fault라는 오류가 나타나는 것을 코딩 중에 자주 볼 수 있습니다.

 

The Address Space

OS는 실제 메모리를 추상화해서 프로세스들에게 나눠 줍니다. 이러한 추상화한 메모리를 address space(주소 공간)이라고 하며 프로세스는 자신의 주소 공간에만 접근해야 합니다. 그럼 주소 공간에는 어떤 정보가 있는지 살펴보겠습니다.

 

프로세스의 주소 공간에는 당연한 말일 수 있지만 해당 프로세스의 코드가 포함되어야 합니다. 그리고 전역 변수를 저장하는 공간(Data), 지역 변수를 저장하는 공간(Stack), 동적 할당받은 데이터(Heap)를 저장하는 공간이 있습니다. 예전에 CPU를 공부할 때도 참고한 그림을 다시  한 번 보면 바로 어떤 구조인지 알 수 있을 거예요!

좀 더 자세히 살펴보면 함수를 호출하여 사용할 때 위치를 추적할 수 있도록 하는 return address라는 것을 Stack 공간에서 사용합니다. 또한 지역변수, 매개 변수도 Stack에 저장합니다. Heap에서는 malloc()를 사용한 동적 할당된 데이터가 저장됩니다. 위의 그림에서는 한 프로세스에게 제공한 메모리의 크기가 64KB인가 봅니다. 프로그램의 코드는 0KB에서 시작합니다. 코드가 끝나면 전역 변수들을 위한 메모리 공간이 있고 그다음은 Heap을 위한 공간이 있습니다. 그리고 맨 위에는 Stack이 존재합니다. Text, Data와는 다르게 Stack, Heap은 크기가 변할 수 있기 때문에 위의 그림과 같이 빈 공간을 사이에 두고 서로 커집니다. 물론 위의 그림과 같은 구조는 여러 구조중 가장 일반적인 것이고 다르게 배치할 수 도 있습니다.

 

여기서 봐야 할 것은 주소 공간입니다. 위의 그림에서 보면 추상화된 주소 공간은 0~64KB라는 주소를 가지고 있지만 실제 메모리에서도 0~64KB를 뜻하는 것은 아닙니다. 아까 본 그림을 다시 가져와보면...

위와 같이 해당 위치에 실제로는 OS가 존재합니다. 예를 들어서 위의 그림에서 프로세스 A의 추상화된 주소 공간이 0~64KB라고 해보겠습니다. 하지만 실제 OS가 프로세스 A를 수행하려고 할 때 실제 메모리의 0KB에 접근하는 것이 아닌 320KB에 접근합니다. 그곳이 실제 프로세스 A의 주소 공간이기 때문이죠. 즉 이것이 메모리 가상화의 핵심 부분입니다. 어떻게 0~64KB라는 가상 주소를 320KB~384KB로 변환해야 할까요? 

Goals

이제 OS는 아까 본 메모리 가상화를 수행해야 합니다. 근데 가상화를 할 때 몇 가지 목표가 있습니다. 이러한 목표는 나중에 다시 자세하게 다룰 예정이니 지금은 간단하게 뭔지만 알고 가도록 하겠습니다!

 

첫 번째 목표는 Transparency(투명성)입니다. OS는 실행 중인 프로그램이 메모리가 가상화된다는 사실을 모르게 해야합니다. 프로그램은 마치 자신에게 하나의 독립적인 실제 메모리가 있는 것처럼 작동해야 합니다.

 

두 번째 목표는 Efficiency(효율성)입니다. OS는 시간과 공간적 측면에서 효율적으로 가상화를 수행하도록 해야 합니다. 시간 효율을 위해서 OS는 TLB와 같은 하드웨어 지원을 받아야 합니다.

 

마지막 목표는 Protection(보안)입니다. OS는 프로세스들로부터 프로세스를 보호하고 OS 자신도 프로세스로부터 보호해야 합니다. 아까 여러 개의 프로세스들이 하나의 메모리에 있을 때 자신의 주소 공간이 아닌 다른 프로세스의 주소 공간에 접근하는 경우를 방지해야 한다고 했습니다. 즉 이러한 침입을 막기 위해 보안 부분을 잘 구현해야 합니다.

 

다음 글에서는 하드웨어와 OS 지원을 사용해 메모리 가상화에 필요한 기본 메커니즘들을 알아볼 예정입니다. 또한 메모리의 여유 공간을 관리하는 방법, 메모리가 부족할 때 어떻게 처리할 것인지에 대해서도 알아볼 예정입니다! 이를 통해 메모리 가상화가 실제로 어떻게 작동하는지 이해할 수 있을 거예요.

Summary

이번 글에서 메모리 가상화에 대해 간단하게 알아봤습니다. 메모리 가상화는 하나의 실제 메모리를 여러 프로세스들에게 메모리 추상화를 사용한 주소 공간을 줌으로써 여러 프로세스를 동시에 실행할 수 있도록 해주는 것이었습니다. 주소 공간은 Text, Data, Heap, Stack으로 구성되어 있다는 것도 알아봤습니다. 이렇게 메모리 추상화를 통해 만든 주소 공간은 실제 주소 공간과는 차이가 있기 때문에 이를 어떻게 처리할지에 대한 부분과 메모리를 함께 사용하는 다른 프로세스로부터 프로세스를 보호하고 OS도 보호하는 방법에 대해 다음 글에서부터 알아볼 예정입니다.

 

감사합니다!

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
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
글 보관함