PML4

PML4말고 그냥 큰 페이지 테이블과 그 안에 포인터 사용하면 되는거 아닌가?

PML4

PML4는 64비트 시스템에서 사용하는 페이지 테이블 구조의 일부로, 정확히는 다단계 페이지 테이블이다. 그러면 여기서 드는 의문이 “그냥 큰 페이지 테이블과 그 안에 포인터 사용하면 되는거 아닌가?” 라고 생각할수도 있다.

왜 PML4가 필요한가?

64비트 시스템에서는 2⁶⁴ = 16엑사바이트(EB)의 주소 공간을 표현할 수 있다.

하지만 현실적으로는:

  • x86-64 아키텍처는 48비트만 실제로 사용함 → 2⁴⁸ = 256 테라바이트(TB)

  • 이걸 4KB 페이지로 나누면? → 256 TB / 4 KB = 약 2^36 = 68,719,476,736 개의 페이지 필요

단일 페이지로 쓴다면?

  • 페이지 하나당 엔트리 크기가 보통 8바이트 (64bit)

  • 2³⁶개의 페이지 * 8바이트 = 512 기가바이트의 단일 테이블 필요

단일 테이블은 메모리 낭비가 엄청나고, 프로세스마다 별도로 이만한 걸 관리해야 함

다단계 피이징 (Multi-levle Paging)을 사용한다면?

핵심 아이디어

  • 희소한 공간만 매핑하자

  • 전체 주소 공간 중 실제로 쓰는 부분만 테이블 만들어서 메모리 절약하자

계층 구조

  • PML4: 512개 엔트리 → PDP

  • PDP: 512개 엔트리 → PD

  • PD: 512개 엔트리 → PT

  • PT: 512개 엔트리 → 실제 물리 페이지

즉, 테이블을 트리 구조로 나눠서 필요한 만큼만 할당하게 하는 방식이야.

PML4 구조의 장점

장점설명
메모리 절약안 쓰는 주소 공간에 대해서는 테이블 자체를 안 만들면 됨
유연성프로세스마다 필요한 주소 영역만 테이블 구성 가능
격리 및 보호계층 구조에서 각 테이블을 독립적으로 관리 가능

PML4 개념

실제 엔트리 수 계산 (x86-64, 4KB 페이지 기준)

가정:

  • 가상 주소 공간: 48비트

  • 페이지 크기: 4KB = 2¹² 바이트

  • 각 페이지 테이블 엔트리 (PTE) 크기: 8바이트 = 64비트

  • 각 페이지 테이블은 512개 엔트리 (2⁹)

가상 주소 구조(48비트)

| PML4 (9bit) | PDP (9bit) | PD (9bit) | PT (9bit) | Offset (12bit) |
  • 각 테이블에서 9비트 = 512개 엔트리

  • Offset 12비트는 4KB 페이지 내부 주소

총 페이지 수

2^(48 - 12) = 2^36 개의 4KB 페이지

단일 테이블이면?

2^36 * 8B = 512GB 단일 테이블 필요

절대 비효율! → 다단계 구조가 필요하다는 게 바로 여기서 보임.

다단계 페이지 테이블 구조 시각화 (트리 형태)

        [PML4]
         |
       512개 중 하나 선택 → [PDP]
                              |
                            512개 중 하나 선택 → [PD]
                                                     |
                                                   512개 중 하나 선택 → [PT]
                                                                 |
                                                           512개 중 하나 선택 → 물리 페이지 (4KB)

  • 가상 주소를 따라 4단계 테이블을 타고 내려가서 물리 주소를 얻음

  • 이 중 필요한 테이블만 동적으로 생성함

예를 들어, 하나의 4KB 페이지만 쓴다면? PML4 + PDP + PD + PT 테이블 단 4개 + 1 물리 페이지만 있으면 됨!

PintOS와 다단계 페이징 구조

PintOS는 기본적으로 x86-64 기반의 4단계 페이징 구조를 사용해

  • pml4_create() - 새로운 PML4 테이블을 만든다

  • pml4_set_page(pml4, va, pa, writable) - va(가상주소)를 pa(물리주소)에 매핑

  • 여기서 va와 pml4가 같이 사용되는데, pml4는 지도, va는 좌표라고 생각하면 이해하기 쉽다

  • pml4_get_page(pml4, va) - va에 매핑된 pa를 조회

  • pml4_activate(pml4) - 현재 CPU가 사용할 페이지 테이블로 설정

프로세스마다 pml4가 다르다

  • struct thread 안에 pml4 멤버가 있음

  • 프로세스 전환 시, 커널은 cr3 레지스터에 해당 프로세스의 pml4 물리 주소를 설정해서 주소 공간을 전환함


© 2022 JeongHwan Yun.