반응형

메모리 관리 기법은 크게 '페이징 기법'과 '세그먼테이션' 두가지 존재한다. 

세그먼테이션

원하는 크기로 잘라쓸 수 있는 공간. 즉, 전체 영역을 원하는 크기로 나누어 관리하는 방식.

세그먼테이션은 세그먼트 레지스터에 '세그먼트 시작 주소' 혹은 '디스크립터(Descriptor)'라고 불리는 자료 구조 위치를 설정해야 한다.


페이징

정해진 크기로 잘라져 있는 공간. 일정한 단위로 잘라진 조각을 모아 원하는 크기로 관리하는 방식. 페이징은 컨트롤 레지스터 중에 'CR3' 레지스터에 페이지 디렉터리라고 불리는 자료구조의 물리 주소를 설정해야 사용할 수 있다.


하지만, 모든 운영 모드가 세그먼트와 페이징을 지원하는 것은 아니다. 각 모드에 따라 지원하지 않거나 지원하지만 일부 기능이 제한되는 경우도 존재한다. 또한, 같은 메모리 관리 기법을 사용하더라도 모드에 따라 필드의 의미가 달라지는 경우가 있다.


리얼 모드의 메모리 관리 방식

최대 1MB까지 주소 공간을 사용하며 세그먼테이션만 지원한다. 리얼 모드에서 세그먼트 크기는 64K로 고정이고, 세그먼트의 시작 어드레스는 세그먼트 레지스터에 직접 설정한다. 세그먼테이션에서 세그먼트의 시작 어드레스는 코드나 메모리에 접근할 때 기준 어드레스(Base Address)로 사용된다.

아래의 그림은 리얼모드의 세그먼트 레지스터와 세그먼트, 물리 주소의 관계를 보여준다

리얼 모드는 페이징을 사용하지 않아서 물리주소로 변환하는 방식이 비교적 간단하다. 세그먼테이션을 거쳐 나온 어드레스가 바로 '물리 주소' 가 된다.리얼 모드의 세그먼테이션은 세그먼트 레지스터의 값에 범용 레지스터 값을 더하는 방식으로 동작한다.

CF)리얼모드에서의 물리주소 계산방법 

세그먼테이션 레지스터(레지스터에 설정된값X16) + 범용레지스터(레지스터에 설정된값X16)

☞보호모드에서도 이러한 세그먼테이션 기법을 사용하긴 하지만, 페이징 기법이 추가되어서 계산결과는 물리주소가 아닌 '선형 주소'라고 불리는 논리주소로 바뀌엇고, 선형주소는 페이징을 거쳐 물리 주소로 바뀌게 된다.


보호모드의 메모리 관리 방식

보호 모드는 리얼모드와 달리 '세그먼테이션' 과 '페이징' 모두 지원한다. 또한, 보호 모드의 세그먼테이션은 리얼모드의 세그먼테이션보다 많은 기능을 제공한다. 더불어 보호모드의 세그먼테이션은 세그먼트 레지스터에 세그먼트 기준 주소를 직접설정하는 대신 디스크립터 자료구조 위치(OFFSET)를 설정하는 방식으로 바뀌었다. 세그먼트 레지스터의 명칭도 세그먼트 디스크립터를 선택한다는 의미에서 '세그먼트 설렉터'로 변경되었다.

~>디스크립터는 메모리 영역의 정보를 저장하는 구조로 여러 종류가 있고, 그중에서 세그먼트에 대한 정보를 나타내는 디스크립터를 '세그먼트 디스크립터'라고 부른다.

~> 세그먼트 디스크립터에는 세그먼트의 시작 어드레스와 크기, 권한(Previlege), 타입(Type)등의 정보가 있다. 세그먼트 

디스크립터에 포함된 특권 레벨(DPL, Descriptor Privilege Level)은 해당 세그먼트에 접속하기 위한 최소한의 권한을 나타내며, 특권 레벨은 0~3 사이를 가진다.(숫자가 작을수록 권한이 높고, 세그먼트에 접근하려면 현재 수행중인 특정레벨(CPL,Current Privilege Leve)이 적어도 디스크립터에 설정된 권한가 같거나 높아야 한다.

~>여기서 조건을 만족하지 않는다면 프로세서는 예외를 발생시켜 문제가 발생했음을 알린다. 접근하는 어드레스가 세그먼트의 크기를 넘어서는 경우도 역시 예외가 발생한다.


보호모드에서 세그먼트 레지스터는'세그먼트 디스크립터의 위치'를 가리킨다. 세그먼트 디스크립터는 메모리 상에 위치하는 자료구조의 일종으로 GDT(Global Descriptor Table)라 불리는 곳에 모여있다(나중에 GDT에 관한 자세한 포스팅을 따로 하나 올리도록 하겠다)

GDT는 연속된 디스크립터의 집합이며, 최대 8192개의 디스크립터를 포함할 수 있는 테이블 형태의 자료구조이다. GDT역시 메모리에 위치하는 자료구조에 불과하므로 프로세서에 GDT의 위치를 직접 알려야 한다.GDT와 관련있는 레지스터는 GDTR 레지스터이며, 16비트 GDT 크기 필드와 32비트 기준 주소 필드로 구성된 자료구조의 물리 주소를 넘겨받는다.

~> 프로세서는 이 값을 내부에 저장했다가 세그먼트 설렉터를 통해 어드레스에 접근할 때마다 GDT의 위치를 찾는데 참조한다.

보호모드에서 주소를 계산하는 방법은 리얼모드와 마찬가지로 계산을 한다. 하지만 위에서 설명했듯 이 주소는 선형주소이므로  프로세서는 실제 메모리 주소와는 다를수도 있고 같을 수 도있다(페이징 기법이 적용되기 떄문이다). 

*선형주소는 이후에 나올 페이징의 입력값이 되며, 페이징을 사용하지 않는다면 선형주소는 리얼모드처럼 물리주소와 1:1 대응한다.


페이징

 물리 메모리를 페이지(Page)라고 불리는 일정한 크기로 나누고, 선형 주소와 물리주소를 나눠 놓은 페이지로 연결하는 방식. 페이징을 사용하면 물리 메모리 크기보다 더 큰 영역의 선형 주소도 물리 페이지만 연결하면 사용이 가능하므로, 주소 공간을 더 넓게 사용할 수 있는 장점이 있다. 또한, 같은 물리 페이지를 여러 선형 주소에 연결함으로써 응용프로그램끼리 공유하는 메모리를 손쉽게 처리할 수 있다.

보호모드에서 페이징은 페이지 크기에 따라 크게 두가지 방식으로 구분한다.

1. 물리 메모리를 4KB 크기로 나누고 선형 주소를 3단계로 구분하는 방식

2.물리 메모리를 4MB 크기로 나누고 선형 주소를 2단계로 구분하는 방식

~>기본원리는 두가지 방법 모두 같다.

3단계 페이징은 선형주소를 디렉터리, 테이블, 오프셋 세 부분으로 나누며 물리 메모리를 4KB 페이지로 나누어 관리하는 방식이다. 선형 주소의 디렉터리 부분과 테이블 부분은 각기 페이지 디렉터리와 테이블에 있는 엔트리의 위치를 나타낸다.

~>페이지 디렉토리와 테이블은 앞서 설명한 GDT와 마찬가지로 메모리 공간에 있는 자료구조일 뿐이다.

프로세서가 페이징 처리과정에서 해당 테이블을 사용하려면 우리가 직접 위치를 알려줘야 한다. GDT에서  GDTR이 존재하듯 페이징에는 CR3 컨트롤 레지스터가 존재한다. CR3 컨트롤 레지스터는 페이지 디렉토리의 '시작 주소'를 가리키며 페이지 디렉초리 엔트리의 위치 계산에 사용한다(페이지 디렉토리 엔트리와 페이지 테이블 엔트리는 크기가 모두 4Byte, 페이지 크기가 최소 4KB이므로 비트 12~비트 31로 기준 주소를 나타내고 비트 11~비트 0은 속성 필드로 사용한다).

요약 해보면 선형주소에서 물리주소를  구하는 과정은 다음과 같다

1.CR3 레지스터에 설정된 어드레스로 페이지 디렉토리의 '시작 주소'를 찾는다

2. 페이지 디렉토리의 시작 주소에 선형 주소의 '디렉토리 오프셋'을 이용해서 해당 페이지 테이블 엔트리를 찾는다(페이지 테이블 엔트리에 설정된 값이  페이지 테이블의 시작주소)

3. 페이지 테이블의 시작 주소에 선형 주소의 오프셋을 이용해서 해당 페이지 테이블 엔트리를 찾는다(페이지 테이블 엔트리에 설정된 값이 4KB 페이지의 시작주소)

4. 페이지의 시작 주소에 선형 주소의 페이지 '오프셋 값을 더해 실제 물리주소로 변환한다.


다음 포스팅에서는 나머지 한개 IA-32e 모드의 메모리 관리에 대해 살펴볼 것이다.





반응형
,