본문 바로가기
2️⃣ 개발 지식 B+/OS

[OS] PML4 이해하기 (w. PintOS)

by ddubbu 2024. 10. 14.
Page Table을 이용해 가상 주소로 물리 주소를 변환하는 과정을 학습했다는 전제하에 글이 작성되었습니다.

Multi-Level Page Table 등장 배경

  • 단일 레벨 페이지 테이블의 경우 거대한 연속된 페이지 테이블이 필요. 미사용 PTE가 존재할텐데, 메모리 낭비 발생
  • Multi-Level PT : 필요한 부분만 테이블 생성. Outer PT만 커널에 유지하고 나머지 하위단계 PT는 필요 시 생성

 

이때, 자료구조는? radix-tree page table

흐린점 감안, (왼) radix-tree vs (오) 연속된 정적 배열

  • sparse한 physcal memory 사용 시 적은 메모리 사용으로 표현 가능
  • Challenge 💪 vs hashed page table [출처]

 

PML4 구현 in PintOS

 

사전 지식; 매크로

64bit 가상 주소 (PPN 이론: 52bit / 현실 = 40bit)

  1. [비트 연산: right shift] 하위 몇 bit를 버릴지 결정 (각 Page Table 마다 상이함)
  2. [비트 연산: &] 0x1FF = 0b1 1111 1111 즉, Page Table 인덱스 추출

 

PML4 walk 요약

 

여기서 기가 막힌건, 다음 PT 시작 주소를 알아내고, PTE를 탐색하는 과정이
마치 (walk) 걸어가는 것처럼 표현되었다.

 

pgdir_walk

  • Page-directory Table에서 바로 물리 주소 찾아 ptov
  • (next) Page-Table 시작 물리 주소 + PTE_SIZE * PTE 오프셋
  • ** 64bit PTE_SIZE 는 8byte 

 

 


추가로 신기했던 점 1
: 모든 페이지 테이블 크기가 4KB

  • (64bit) 9bit * 8byte = 4KB
  • (32bit) 10bit * 4byte = 4KB

신기했던 점 2 : PTE 에서 PPN(Pysical Page Number) 외에 하위 12bit는 언제 쓰일까?

  • 우선, PTE Level 별로 같은 정보를 담고 있다.
    • Q. Outer/Inner Table 모두 중복된 정보를 왜 갖고 있을까?
    • A. 최적화. valid 여부를 outer에서 알 수 있다면, 말단까지 타고갈 필요가 없음
  • 각 bit는 boolean 정보를 담고 있다.

코드와 함께 사용 방법 이해하기

uint64_t *pml4e_walk(uint64_t *pml4e, const uint64_t va, int create) {
    uint64_t *pte = NULL;
    int idx = PML4(va);
    if (pml4e) {
        uint64_t *pdpe = (uint64_t *)pml4e[idx];
        if (!((uint64_t)pdpe & PTE_P)) { // Present Bit & 연산으로 swap in/out 여부 파악
            // 생략; page table 생성 및 null 반환
        }
        pte = pdpe_walk(ptov(PTE_ADDR(pml4e[idx])), va, create);
    }

	// 생략; 해제
    return pte;
}