#메모리가상화 #주소변환 #동적재배치 #베이스 #바운드레지스터

초기 컴퓨터는 사용자에게 간단한 메모리 공간을 제공했다.(개념,abstraction을 제공했다 라고 표현하기도 함) 낮은 번지에는 OS를 올리고, 높은 번지에는 응용프로세스가 실행할 수 있는 메모리 공간을 할당하는 방식으로.. 그러나 이경우엔 하나의 프로세스만 사용할 수 있다. 시간이 지나면서 다음 2가지 이유로 좀 더 발전되었다.

1. 멀티프로그래밍

여러개의 프로세스를 동시에 실행시키는 멀티프로그래밍 환경이 등장했다. 동시에 존재하고, OS가 프로세스간에 자원을 분배하면서 CPU 이용률을 높일 수 있다. 대표적인 예로 Time Sharing이 있다.

2. Time Sharing

Round Robin 알고리즘으로 Time Sharing이 일어난다. 그런데 물리메모리가 하나의 프로세스만 가질 수 있다면(왼쪽이미지), OS는 메모리를 차지하고 있던 프로세스의 컨텍스트 정보를 모두 디스크에 저장하고 실행시킬 프로세스의 컨텍스트를 디스크에서 가져와 메모리에 올려야하는 큰 오버헤드가 발생한다. 그래서 물리메모리 안에 여러프로세스가 공존하는 구조를 생각할 수 있다.(오른쪽이미지)

⚠️ Protection Issue

오른쪽이미지처럼 여러 프로그램이 메모리에 동시에 존재하다보니 보호가 중요한 문제가 된다. 예를들어 프로세스C가 B메모리에 접근하려는 경우가 있겠다.

image

🔗 Address Space 정의

위에서 설명한 Protection Issue를 해결하기 위해 응용프로그램이 물리메모리에 자기가 어디있는지 몰라도 가상적으로 메모리를 갖고있다고 추상화(abstraction)를 제공해 주는 개념이다.

image

🔗 OS가 해야할 일

가상 메모리를 구현해야하는 OS는 어떤 목표를 가져야 할까. 3가지로 나눌 수 있다.

1. 투명성 : 실행중인 프로그램이 자기가 물리메모리 전체를 소유한 것 마냥 느낄 수 있게 해야한다.

2. 효율성 : 가상화를 할때 너무 많은 메모리를 사용하면 안된다. 그러면서도 너무 느리게 실행되서도 안된다. 그래서 다음에 얘기할 TLB 같은 하드웨어의 지원을 받아야 한다.

3. 보호 : OS자신도 그렇고 프로세스들을 보호해야한다.

📌 스택과 힙

스택은 함수가 호출될떄 지역변수를 할당할때 컴파일러가 조작한다. 응용프로그램을 짤때 스택을 조작하진 않는다. 콜이나 리턴으로 함수를 호출, 반환할때 내부적으로 스택을 조작하기 위한 어셈블리 코드를 컴파일러가 넣어준다. 마찬가지로 지역변수도 메모리가 할당 될때 컴파일러가 스택을 조작한다.

힙의 경우는 malloc이라던지 명시적인 메모리 할당 함수를 통해 메모리에 할당한다.

🔗 주소 변환

여러개의 프로세스가 메모리 자원을 공유하고, OS가 context switch하면서 0번지부터 max까지 자기공간이 있다고 생각하지만 OS가 내부적으로 많은 일을 해야한다.

프로그램 내부에서는 가상주소에 접근하기 때문에 물리메모리로 변환해야한다. 그 작업을 OS가 하는것이다. 메모리를 접근할때마다 주소변환이 일어나야하는데, 사실 하드웨어가 주어지는 메카니즘에 의해 변환된다. 그렇다고 하드웨어가 다 해주는게 아니라 도구만 제공해주고 자료구조와 레지스터 세팅은 OS에의해 이루어진다. 이때 OS가 중요하게 생각해야할 3가지는 다음과 같다.

  • 코드 스택 힙 메모리 영역들에 대해 하나의 address space가 지원되어야 한다.
  • 메모리 스페이스는 해당 프로세스만 안전하게 접근하게 해야한다.
  • 이 외에 OS에 필요한 자료구조 등을 효율적으로 해야한다.

간단하게 물리메모리를 만들어보자. 그 전에 3가지 가정이 필요하다.

1. 한프로세스에 대한 address space는 물리적으로 연속되어야 한다.
2. 한프로세스에 필요한 메모리가 너무 크지 않아야 한다.
3. 모든 프로세스의 address space는 같은 크기여야 한다.

🔗 동적 재배치

하드웨어관점의 주소 변환을 이해해보자. 프로세스들은 각각 address space를 위한 슬롯(한 프로세스가 사용하는 메모리 공간)들의 시작위치가 바뀔 수 있다. 이때 필요한 하드웨어의 도움은 base와 bound 레지스터다. base는 각각의 address space마다 시작점을, bound는 끝지점을 저장한다. 유효한 address space의 시작점부터 끝지점을 명시해 줄 수 있는 레지스터다.

physical address = virtual address + base

bound address space의 끝지점 이니까 메모리 가상주소가 bound보다 크거나 음수면 보호를 어긴다고 판단할 수 있다.

✏️ 요약

가상주소를 위한 하드웨어와 OS의 요구사항을 정리한 표다.

하드웨어 요구사항 내용
특권모드 사용자 모드 프로세스가 특권 연산을 실행하는 것을 방지하기 위해 필요
베이스/바운드 레지스터 주소 변환과 범위 검사를 지원
가상 주소 변환, 범위 검사 능력 주소 변환과 범위 검사를 위한 회로
베이스/바운드 갱신 특권 명령어 프로그램 시작 전에 OS가 베이스와 바운드 레지스터 값을 지정할 수 있어야 한다 (context switch, 프로세스 생성될때 사용)
예외 핸들러 등록을 위한 특권 명령어 OS가 예외처리 코드를 하드웨어에게 알려줄 수 있어야 한다
예외 발생 기능 프로세스가 특권 명령 실행을 시도하거나 범위를 벗어난 메모리 접근을 시도할때 예외를 발생시킨다
OS 요구사항 내용
메모리 관리 새 프로세스 메모리 할당에 필요, 종료 프로세스로부터 메모리 회수, 빈 공간 리스트를 통한 일반적인 메모리 관리
베이스/바운드 레지스터 문맥 교환 시 올바른 베이스, 바운드 설정
가상 주소 변환, 범위 검사 능력 예외 발생할때 실행할 코드