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물리 주소를 설정해서 주소 공간을 전환함