반응형

→ 선형 주소와 4단계 페이징 기법

 

이전에 4KB 페이지를 사용하는 5단계 페이징 기법과 주소 변환 과정을 배웠었습니다.

 

2MB 페이지를 사용하는 페이징 역시 이와 크게 다르지 않으며, 차이점이라면 페이지 테이블이 사라지고 페이지 디렉터리가 직접 해당 페이지의 시작 주소를 가리킨다는 것입니다.

 

아래는 IA-32e 모드의 4단계 페이징 기법과 주소 변환 과정입니다.

 

IA-32e 모드의 4단계 페이징과 주소 변환 과정

 

페이징에 사용하는 각 테이블은 512(2^9) 개의 엔트리로 구성되며, 다음 레벨에서 사용할 테이블의 기준 주소를 포함합니다.

 

가장 마지막 레벨인 페이지 디렉터리의 엔트리는 2MB 페이지의 기준 주소를 포함합니다.

 

위의 그림과 같이 선형 주소에 9비트씩 할당된 영역은 해당 테이블 내의 엔트리 오프셋을 나타내며, 이를 통해 최종 엔트리와 테이블을 찾아 실제 물리 주소로 변환합니다.

 

 

▶ 선형 주소를 실제 물리 주소로 변환 단계

 

1. CR3 레지스터에 설정된 PML4 테이블의 기준 주소

2. PML4 엔트리

3. 페이지 디렉터리 포인터 인트리

4. 디렉터리 엔트리

5. 2MB 페이지의 기준 주소에 선형 주소의 하위 21bit 오프셋을 더합니다.

 

 

4단계 페이징 기법을 사용하려면 페이지 맵 레벨 4 테이블(PML4 Table), 페이지 디렉터리 포인터 테이블, 페이지 디렉터리 등 세 가지 자료구조를 생성해야 합니다.

 

각 테이블은 8byte 크기의 엔트리로 구성되고, 각 엔트리는 다음 레벨 테이블의 기준 주소 외에도 다양한 필드를 포함합니다.

 

아래는 페이지 테이블을 구성하는 엔트리의 구조를 나타낸 것엔트리를 구성하는 필드를 정리한 것입니다.

 

페이지 테이블을 구성하는 엔트리의 구조

 

페이지 테이블을 구성하는 엔트리의 각 필드와 의미

 

페이지 엔트리도 컨트롤 레지스터만큼이나 복잡하고 다양합니다.

 

페이지 엔트리의 설정할 값을 고민하기 전사용하고자 하는 페이징의 역할에 대해서 정리할 겸 FS64 OS를 실행하는 데 필요한 페이지의 역할은 다음과 같습니다.

 

● 선형 주소와 물리 주소를 1:1로 매핑하여 직관적인 주소 변환을 수행해야 함

2MB 페이지를 사용하여 최대 64GB의 물리 메모리를 매핑해야 함

물리 메모리 전체 영역에 대해 캐시를 활성화하여 수행 속도를 향상시켜야

 

위에서 언급한 기능 외에 다른 기능은 사용하지 않습니다.

 


 

→ 페이지 테이블 구성과 공간 할당

 

페이징 기능을 사용하려면 메모리 영역의 정보를 담고 있는 페이지 테이블을 생성하여 프로세서에 설정해야 합니다.

 

64GB의 메모리 공간을 관리하는 데 필요한 페이지 테이블의 크기를 알아보고 페이지 엔트리의 속성 필드를 설정하는 방법을 살펴보겠습니다.

 


 

→ 64GB의 물리 메모리 관리를 위한 메모리 계산

 

FS64 OS2MB 크기의 페이지를 사용하여 최대 64GB의 물리 메모리를 매핑합니다.

 

64GB 메모리를 관리하려면 최소한 몇 개의 페이지 테이블이 필요한지 계산해봅니다.

 

▶ 페이지 디렉터리의 개수

페이지 디렉터리8byte 크기인 엔트리 512(2^9)개로 구성되며, 각 엔트리는 2MB 페이지에 대한 정보를 담고 있기 때문페이지 디렉터리 하나로 관리할 수 있는 메모리 영역은 (2MB x 512개)가 되어 1GB까지이며, 페이지 디렉터리 하나가 차지하는 메모리 크기는 (8byte x 512개)가 되어 4KB가 됩니다.

 

최대 64GB 영역을 매핑해야 하므로 필요한 페이지 디렉터리의 수는 64개이고 총 256KB(4KB x 64개)의 메모리가 필요합니다.

 

▶ 페이지 디렉터리 포인터 테이블의 개수

두 번째에 있는 페이지 디렉터리 포인터 테이블도 마찬가지로 8byte 크기인 엔트리 512(2^9) 개로 구성됩니다.

 

페이지 디렉터리 포인터의 각 엔트리는 하위 레벨인 페이지 디렉터리에 대한 정보를 포함하며, 위에서 계산했던 페이지 디렉터리 64개를 관리하려면 엔트리가 총 64개 필요합니다.

 

페이지 디렉터리 포인터 테이블 한 개로 관리할 수 있는 페이지 디렉터리의 수는 512개이므로 1개의 페이지 디렉터리 포인터 테이블로 충분하며, 페이지 디렉터리 포인터 테이블을 위해서는 총 4KB(4KB x 1개)의 메모리가 필요합니다.

 

PML4 테이블

다른 테이블과 동일하게 8byte 크기인 PML4 테이블 엔트리 512(2^9)개로 구성됩니다.

 

각 엔트리는 하위 레벨인 페이지 디렉터리 포인터 테이블의 정보를 담고 있으며, 위에서 계산했던 페이지 디렉터리 포인터 테이블 1개를 관리하려면 엔트리 1개만 있으면 됩니다.

 

PML4 테이블 한 개는 페이지 디렉터리 포인터 테이블을 최대 512개까지 관리할 수 있으므로 충분하고, PML4 테이블을 위해 필요한 메모리는 총 4KB(4KB x 1개)가 됩니다.

 

 

 

이것으로 64GB 물리 메모리를 매핑하는 데 필요한 페이지 테이블의 개수가 총 66개(64개의 페이지 디렉터리 + 1개의 페이지 디렉터리 포인터 테이블 + 1개의 PML4 테이블)이며, 필요한 메모리는 총 264KB입니다. (아래 그림 참조)

 

이러한 공간을 커널 이미지에 포함하여 이미지 크기를 늘리면 부팅 시간을 지연시키므로 별로 바람직하지 못합니다.

 

또한, 페이지 테이블이 4KB로 정렬된 메모리에 있어야 한다는 제약 사항을 고려할 때 OS 이미지에 포함시켰다가는 메모리 정렬을 위해 불필요한 공간이 낭비될 수 있습니다.

 


참고)

만약 PML4 테이블 하나를 전부 매핑한다고 했을 때 최대 몇 GB까지 매핑할 수 있는지 계산해 보면, 2MB 페이지를 사용하는 4단계 페이징을 사용한다는 가정하에 가장 하위 레벨인 페이지 디렉터리 한 개로 1GB를 매핑할 수 있습니다.

 

페이지 디렉터리의 상위 레벨인 페이지 디렉터리 포인터 테이블 하나는 최대 512개의 페이지 디렉터리에 대한 정보를 가질 수 있으니, 페이지 디렉터리 포인터 테이블 하나는 최대 512GB(1GB x 512개)를 매핑할 수 있습니다.

 

같은 원리로 최상위 레벨인 PML4 테이블 역시 최대 512개의 페이지 디렉터리 포인터 테이블에 대한 정보를 가질 수 있으므로 최대 256TB(512GB x 512개)를 매핑할 수 있습니다.

 

PML4 테이블 하나로 최대 256TB까지 관리할 수 있습니다.

 


→ 페이지 테이블을 위한 공간 할당

 

264KB나 되는 영역을 OS 이미지나 IA-32e 모드 커널 주소 공간(0x200000 ~ 0x600000)에 두는 것은 좋은 방법이 아니므로 별도의 공간을 할당합니다.

 

이전에 IA-32e 모드용 커널 이미지가 0x200000(2MB)에서 시작한다고 배웠습니다.

 

0x100000(1MB) ~ 0x200000(2MB) 영역을 IA-32e 모드용 커널 자료구조 영역으로 사용하기 때문이며, 이 공간의 가장 앞부분에 페이지 테이블이 위치합니다.

 

페이지 테이블의 순서는 최상위 레벨인 PML4 테이블 → 페이지 디렉터리 포인터 테이블 → 페이지 디렉터리이며, 0x100000(1MB) ~ 0x142000(1MB + 264KB)의 주소에 위치합니다.

 

아래는 페이지 테이블이 있는 영역의 메모리 맵을 나타낸 것입니다.

 

페이지 테이블의 메모리 맵

 

이제 각 엔트리의 속성 필드를 설정하는 일만 남았습니다.

 


→ 공통 속성 필드 설정

 

PML4 테이블 엔트리, 페이지 디렉터리 포인터 테이블 엔트리, 페이지 디렉터리 엔트리는 공통적인 속성 필드를 가지고 있으며, A, PCD, PWT, U/S, R/W, P 필드가 바로 그것입니다.

 

▶ PCD 필드와 PWT 필드

FS64 OSIA-32e 모드 커널은 보호 모드 커널과 달리 실제 OS를 구성하는 핵심 역할을 하기 때문에 속도 향상을 위해 캐시를 사용하는 것이 좋습니다.

 

캐시 정책에는 Write-Through 방식Write-Back 방식이 있으며, 두 가지 방법 중에 Write-Back 방식의 효율이 더 좋습니다.

 

그렇기에 Write-Back 방식의 캐시를 사용하도록 PCD 비트와 PWT 비트 값을 설정하겠습니다.

 

위의 페이지 테이블을 구성하는 엔트리의 각 필드와 의미 표를 참고하면 PCD = 0, PWT = 0이 됩니다.

 

U/S 필드와 R/W 필드

FS64 OS의 최종 목표 중에 한 가지는 유저 레벨과 커널 레벨을 구분하여 잘못된 접근으로부터 보호(Protection)하는 것입니다.

 

하지만 이는 유저 레벨 애플리케이션이 등장하여 유저/커널 레벨이 구분된 이후의 문제이므로 지금은 유저 레벨과 커널 레벨을 굳이 구분할 필요가 없습니다.

 

코드 영역과 데이터 영역 또한 읽기/쓰기 속성을 따로 부여할 이유가 없으며, 속성을 따로 부여하려면 코드와 데이터를 페이지 단위(2MB)로 정렬해야 하는 제약 사항이 있기 때문에 지금은 모든 페이지를 커널 레벨 영역으로 지정하고 읽기와 쓰기가 가능하게 설정하는 것으로 충분합니다.

 

위의 페이지 테이블을 구성하는 엔트리의 각 필드와 의미 표를 참고하면 U/S = 0, R/W = 1이 됩니다.

 

EXB 필드, A 필드, P 필드, Avail 필드

FS64 OS에서는 페이징의 기본 기능 외에 다른 기능은 사용하지 않기 때문EXB 필드와 같이 해당 페이지 내에서 코드 실행을 막는 기능은 사용하지 않으므로 0으로 설정합니다.

 

코드 실행 도중에 특정 페이지에 접근(읽기 또는 쓰기)했는지 여부도 참조하지 않으므로 임의의 값(0)으로 설정합니다.

 

Avail 필드 역시 사용하지 않으므로 임의의 값으로 설정합니다.

 

P 필드해당 엔트리가 유효하다는 것을 나타내는 필드이므로 다른 필드와 달리 반드시 1로 설정하여 해당 엔트리에 접근했을 때 페이지 폴트 예외가 발생하지 않게 합니다.

 

이렇게 공통으로 사용되는 속성 필드의 값을 알아봤습니다.

 


 

→ 페이지 디렉터리 엔트리용 속성 필드 설정

 

페이지 디렉터리 엔트리는 공통 필드 외에도 PAT 필드, G 필드, D 필드가 있습니다.

 

하지만 그리 중요하진 않습니다.

 

 

▶ PAT 필드, G 필드, D 필드

페이지의 기본 기능 외에 다른 기능은 거의 사용하지 않기 때문PAT처럼 페이지 별로 특수한 옵션을 지정하는 필드는 사용하지 않으므로 0으로 설정합니다.

 

태크스 별로 페이지 매핑을 따로 구성하지 않으므로 페이지 테이블이 고정되어 있으니, 페이지 테이블 교체와 관련된 G 필드 역시 0으로 설정하고 D 필드는 A 필드와 마찬가지로 참조하지 않으므로 임의의 값(0)으로 설정합니다.

 


이것으로 FS64 OS를 실행하는 데 필요한 엔트리의 속성 값에 대해서 모두 알아보았습니다.

 

이제 엔트리 속성 값을 바탕으로 실제 0x100000 영역에 페이지 테이블을 생성하고 페이징 기능을 활성화하는 방법을 알아봅니다.

반응형

+ Recent posts