본문 바로가기
CS/OS

운영체제(OS)-WEEK6 (2) Disadvantage of Linear Tables, Hybrid Approach, Multi-Level Page tables

by assidu 2026. 4. 9.

모든 프로세스는 각자 페이지 테이블을 가진다.

프로세스 하나는 페이지 테이블을 가지는데, (가상 메모리 공간 / 페이지 크기) * PTE 크기 = 페이지 테이블 크기!

페이징 기법: 선형 테이블의 한계가 드러난다. 가상 공간에서 쓰지 않는 공간까지 페이지로 다 할당하고 그것들의 PTE를 모두 페이지 테이블에 저장하니 페이지 테이블이 필요한 것보다 더 커진다. (메모리를 필요한 것보다 더 잡아먹음)

 

 

PTE 개념 리마인드>>

 

더보기

PTE는 **Page Table Entry(페이지 테이블 엔트리)**의 약자로, 말 그대로 페이지 테이블이라는 거대한 표 안에 들어있는 **'각각의 항목(한 줄)'**을 의미합니다.

 

개념을 명확히 나누어 보자면 다음과 같습니다.

  • 페이지 테이블 (Page Table): 전체 페이지들의 매핑 정보를 담고 있는 거대한 '표' 전체.
  • PTE (Page Table Entry): 그 표를 구성하는 낱개의 '행(Row)'. 즉, 특정 페이지 1개에 대한 번역 정보가 담긴 단일 데이터 패키지.

💡 전화번호부 비유

  • 페이지 테이블: 서울시 전체 전화번호부 책
  • PTE: 그 책에 적혀 있는 '김철수 - 010-XXXX-XXXX'라는 딱 한 사람의 정보(한 줄)

이 자그마한 PTE (보통 4바이트 크기) 안에는 단순히 물리 프레임 번호(PFN)만 있는 것이 아니라, 이 페이지가 현재 유효한지(Valid), 램에 있는지 디스크에 있는지(Present), 쓰기가 가능한지(Protect, Dirty) 등의 아주 중요한 제어 비트들이 함께 꽉꽉 채워져 저장되어 있습니다!

 

 

선형 테이블 구조에서 안쓰는 공간까지 페이지 할당해서 페이지 테이블 크기가 커지는 문제의 해결책

해결책으로 페이지 테이블 크기를 줄이기 위해 페이지 사이즈를 늘린다. -> 페이지 수 줄어듦 -> 저장할 PTE 수 줄어듦 -> 테이블 크기 작아짐.

 

그러나 페이지 테이블 크기를 줄이자고 페이지 사이즈를 늘려보니 Segmentation에서 발생했던 '내부 파편화' 문제가 다시 생긴다.

페이지 크기를 키우니 각 페이지에서 남는 공간(안쓰는 공간) 생김.

비유하자면 용돈 10000원 받고 3000원만 쓰고 7천원이 남는 상황?!

 

 

선형 테이블 구조에서 안쓰는 공간까지 할당해서 물리(실제)메모리를 잡아먹고 있는 상황 보여줌>>

페이지 4~5: 근본적인 원인은 '주소 공간의 희소성(Sparsity)'입니다. 실제 프로그램은 Code, Heap, Stack 영역만 쓰고 그 사이는 텅텅 비어있습니다. 그런데 선형 구조는 이 사용하지도 않는 빈 공간을 위해서도 무조건 Valid=0인 PTE를 빼곡하게 만들어 두어야 하기 때문에 메모리가 낭비되는 것입니다.

 

더보기

이전에 배우셨던 TLB의 Valid 비트페이지 테이블의 Valid 비트는 이름만 같을 뿐 역할이 완전히 다릅니다. 이 둘을 명확하게 비교해서 정리

1. 페이지 테이블에서의 Valid 비트 (현재 그림)

  • 의미: "이 가상 주소(VPN) 공간이 이 프로그램에게 합법적으로 할당된 내 땅인가?"
     
  • 1인 이유: 그림 왼쪽 가상 주소 공간을 보면 Code(VPN 0), Heap(VPN 4), Stack(VPN 14, 15) 공간에서 물리 메모리를 향해 빨간색 선으로 Allocate(할당)라고 적혀 있습니다. 즉, 프로그램이 만들어질 때 운영체제로부터 "이 공간을 쓰라"고 허락받은 합법적인 영역이기 때문에 1인 것입니다. 메모리에 처음 올라가는 그 순간부터 1로 세팅됩니다.
  • 0인 이유: 할당받지 않은 회색 빈 공간들입니다. 만약 프로그램의 버그로 인해 valid = 0인 곳을 읽거나 쓰려고 하면, 운영체제가 "네 땅도 아닌데 왜 허락 없이 접근해!"라며 그 유명한 **Segmentation Fault (세그멘테이션 오류)**를 발생시키고 프로그램을 강제 종료해 버립니다.

2. TLB에서의 Valid 비트 (이전에 배 내용)

  • 의미: "이 캐시(TLB) 칸에 들어있는 주소 번역 정보가 현재 믿고 쓸 수 있는 최신 정보인가?"
  • **"전에 접근해서 1이 되었다"**는 설명은 바로 이 TLB 캐시 메모리에 적용되는 아주 정확한 설명
  • 문맥 교환 시 항상 FLUSH해야하냐? -> ASID 유무에 따라 다름(ASID 있으면 안함)

💡 추가 지식: Present 비트와의 차이

그림 우측 표를 자세히 보면 valid 옆에 present라는 비트도 전부 1로 되어 있습니다.

 
  • valid = 1: "이곳은 내 땅이 맞다" (합법적 소유권)
  • present = 1: "그 내 땅에 해당하는 데이터가 지금 물리 메모리(RAM) 방 안에 들어 있다" (만약 present=0이라면, 물리 메모리 용량이 꽉 차서 하드디스크의 Swap 공간으로 임시로 쫓겨났다는 뜻입니다.)

페이지 테이블 선형 구조가 메모리 낭비를 하는 것의 해결책 = 하이브리드 접근! (페이징 + 세그먼트)

주소 공간을 논리적 단위로 나눈다(세그먼트) -> Code, Heap, Stack (각 세그먼트는 가변적임)

이 후 각 세그먼트 내부를 페이지 크기로 나눈다. -> 각 세그먼트마다 페이지 테이블을 가진다. (원래는 프로세스 하나당 페이지 테이블 하나였음) 각 세그먼트는 각 페이지 테이블의 BASE와 limit(bound)를 추적한다.

 

 

 

그럼 하이브리드 접근방식일 때 세그먼트 내부에서 페이지 크기로 나눈 뒤, 세그먼트 내부에서 쓰는 영역만 PTE를 만드나???

  • (세그먼트 바깥에서): Code, Heap, Stack 세그먼트들 사이에 있는 엄청나게 넓은 빈 공간(할당되지 않은 공간)에 대해서는 아예 페이지 테이블을 만들지 않습니다. 이 덕분에 선형 페이지 테이블의 엄청난 메모리 낭비를 극적으로 줄일 수 있습니다.
  • 틀린 부분 (세그먼트 내부): 하지만 특정 세그먼트 '내부'의 페이지 테이블은 여전히 기존의 선형 구조(Linear)를 유지합니다.
    • 만약 프로그램이 Heap 영역을 아주 크게(예: 100페이지 크기) 할당해 놓고, 정작 데이터는 1번 페이지와 100번 페이지만 쓰고 중간의 2~99번 페이지는 텅텅 비워두었다고 가정해 볼게요. (Sparsely-used heap)
    • 하이브리드 기법에서는 이 100페이지짜리 Heap 세그먼트를 덮기 위해 어쩔 수 없이 100개의 PTE를 가진 페이지 테이블을 통째로 만들어야 합니다. 중간에 안 쓰는 2~99번 페이지를 위한 쓸데없는 PTE(valid=0)들도 다 만들어야 하는 것이죠.

결론적으로, 하이브리드 기법은 "세그먼트와 세그먼트 사이의 빈 공간"에 대한 PTE 낭비는 없앴지만, "세그먼트 내부의 듬성듬성 빈 공간"에 대한 PTE 낭비(Waste)는 여전히 해결하지 못했다는 한계가 있습니다. (이걸 완벽하게 해결하려고 나온 최종 보스가 바로 '멀티 레벨 페이지 테이블'입니다!)

 

2. 각 세그먼트가 각자의 페이지 테이블의 시작/끝 주소를 계속 본다는 건가요?

개념적으로는 완벽하게 맞습니다! 다만, 주체가 '세그먼트 자신'이 아니라 **'컴퓨터의 하드웨어(CPU/MMU)'**라는 점만 살짝 다듬으시면 됩니다.

교안 6페이지와 8페이지의 동작 원리를 보면 다음과 같습니다.

  • 프로세스가 실행될 때, 하드웨어 안에는 Code, Heap, Stack 세그먼트를 위한 Base 레지스터(시작 주소)와 Bounds/Limit 레지스터(끝 주소/크기) 쌍이 각각 준비되어 있습니다.
  • 여기서 Base 레지스터는 세그먼트 자체의 시작 주소가 아니라, 그 세그먼트의 '페이지 테이블'이 물리 메모리 어디에 있는지를 가리킵니다. Bounds 레지스터는 그 페이지 테이블이 몇 줄짜리인지(어디서 끝나는지)를 나타냅니다.

💡 하드웨어의 동작 순서 (교안 8페이지 공식)

  1. 가상 주소가 들어오면, 하드웨어가 앞의 2비트(Seg bit)를 보고 "아, 이건 Heap 꺼네!" 하고 Heap용 Base/Bounds 레지스터를 쳐다봅니다.
  2. 들어온 주소가 Bounds 레지스터를 넘어서는지(할당된 크기를 벗어나는지) 확인합니다. 넘어가면 에러를 띄웁니다.
  3. 문제가 없으면, Base 주소 + (VPN * PTE 크기) 공식을 계산해서 물리 메모리에 있는 그 세그먼트의 페이지 테이블로 정확히 찾아가 PTE를 읽어옵니다!

하드웨어가 주소 변환을 할 때마다 **해당 세그먼트의 Base(시작)와 Bounds(끝) 레지스터를 계속해서 확인(참조)**하며 안전하고 정확하게 번역을 수행하는 것이 맞습니다!

 

 

순수 세그멘테이션 때 Base레지스터, Bound 레지스터와의 차이점>> 

더보기

과거와 현재의 Base/Bound 레지스터의 역할 변화를 명확히 비교해 드릴게요.

1. 과거: 순수 세그멘테이션 (페이징 이전)

  • Base 레지스터: 실제 데이터(Code, Heap, Stack)가 들어있는 물리 메모리의 진짜 시작 주소를 가리켰습니다.
  • Bound 레지스터: 그 세그먼트 자체의 크기(한계선)를 나타냈습니다.

2. 현재: 하이브리드 기법 (세그멘테이션 + 페이징)

 
  • Base 레지스터: 이제는 세그먼트 자체가 아니라, 해당 세그먼트의 '페이지 테이블'이 저장된 물리 메모리의 시작 주소를 가리키도록 역할이 완전히 바뀌었습니다!
  • Bound 레지스터: 마찬가지로 세그먼트의 크기가 아니라, **'페이지 테이블의 끝(크기)'**을 나타내는 용도로 사용됩니다.

💡 왜 이렇게 바뀌었을까요?

하이브리드 기법에서는 세그먼트 내부가 페이지 단위로 조각조각 나뉘어 물리 메모리 곳곳에 흩어지게 됩니다. 따라서 옛날처럼 "힙 영역은 물리 메모리 1000번지부터 2000번지까지야!"라고 하나의 큰 Base 주소로 퉁칠 수가 없게 되었습니다.

대신, "힙 영역의 조각들이 어디 흩어져 있는지 적어놓은 지도(페이지 테이블)가 물리 메모리 500번지에 있어!"라고 지도의 위치(Base)를 알려주는 방식으로 진화한 것입니다.

궁금증: 세그먼트 갯수만큼 base, bound 레지스터 쌍이 존재하고(cpu에) base는 그 세그먼트에 대응되는 페이지 테이블의 물리 주소에서 시작 주소, bound는 마지막 주소를 의미?

 

1. "세그먼트 갯수만큼 base, bound 레지스터 쌍이 (cpu에) 존재하고" 👉 정답입니다. 프로그램이 Code, Heap, Stack이라는 3개의 세그먼트를 사용한다면, CPU 내부에는 이들을 각각 전담하는 딱 3쌍의 Base/Bound 레지스터만 존재합니다.

2. "base는 그 세그먼트의 페이지 테이블의 물리 주소에서 시작 주소를" 👉 정답입니다. 메모리(RAM)에 저장된 해당 세그먼트 전용 '페이지 테이블'이 물리적으로 정확히 몇 번지에서 시작하는지, 그 첫 출발점을 가리킵니다.

3. "bound는 마지막 주소를 의미?" 👉 정답입니다. 페이지 테이블이 어디서 끝나는지(즉, 할당된 페이지 테이블의 총 크기나 한계선)를 나타냅니다. 하드웨어는 가상 주소가 들어올 때마다 이 Bound 값을 확인해서, 페이지 테이블의 마지막 주소를 벗어나는 불법적인 접근을 차단합니다.

 

 

세그먼트로 나누고 각 세그먼트 내부를 페이지 크기로 나누는데 페이지 크기가 세그먼트 크기보다 크다면???>>

더보기

결론부터 말씀드리면, 세그먼트의 크기가 1페이지보다 작더라도 무조건 최소 1개의 온전한 페이지(물리 프레임)를 통째로 할당해야 합니다.

 

그 이유는 다음과 같습니다.

 

1. 하드웨어의 최소 관리 단위 고정 

하이브리드 기법에서 세그먼트 내부를 페이징으로 쪼개기로 한 순간, 하드웨어가 물리 메모리에 데이터를 올리고 주소를 변환하는 최소 단위는 무조건 '페이지 크기(예: 4KB)'로 고정됩니다. 0.5페이지나 0.1페이지만 잘라서 할당하는 것은 불가능합니다.

 

2. 권한(Protection) 분리의 한계

 "그럼 남는 공간에 다른 세그먼트를 룸메이트로 같이 넣으면 안 되나?"라고 생각하실 수 있습니다. 하지만 이는 보안상 불가능합니다. 메모리 접근 권한(읽기/쓰기/실행)은 오직 '페이지 단위'로만 부여됩니다. Code 세그먼트는 읽기/실행(r-x) 권한이, Heap 세그먼트는 읽기/쓰기(rw-) 권한이 필요합니다. 권한이 완전히 다른 두 세그먼트가 하나의 페이지 방을 공유할 수는 없습니다.

 

결과: 최소한의 내부 단편화(Internal Fragmentation) 발생

 만약 페이지 크기가 4KB인데 세그먼트가 1KB밖에 안 된다면, 할당된 1페이지 중 나머지 3KB 공간은 아무도 쓰지 못한 채 낭비됩니다. 이것이 교안 앞부분에서 큰 페이지를 쓸 때 발생한다고 언급되었던 내부 단편화(Internal Fragmentation) 현상입니다.

 

즉, 하이브리드 기법은 페이지 테이블의 전체 덩치를 획기적으로 줄여주는 엄청난 이득을 얻는 대신, 각 세그먼트의 끝부분이나 아주 작은 세그먼트에서는 어쩔 수 없이 내부 단편화라는 작은 손해를 감수하는 구조로 설계

 

 

 

프로세스는 3개의 페이지 테이블 가지게됨(Code,Heap,Stack)

 

프로세스 실행될 때, 각 세그먼트에 대한(각 페이지 테이블의) base register는 세그먼트의 선형 페이지 테이블의 물리 시작 주소를 가짐.

가상 공간 32bit가 있으면 맨 앞 2bit는 세그먼트의 유형을(이 때 선형아), 페이지 크기 4KB는 Offset을 (12비트), 남은 18비트는 VPN을 나타내게 된다.

 

원하는 세그먼트 내부의 페이지의 PTE 주소를 구하는 코드

 

이 슬라이드의 제목이 **"TLB miss on Hybrid Approach"**인 이유

 

CPU가 초고속 캐시인 TLB를 뒤졌는데 원하는 번역 정보가 없을 때(TLB Miss), 하드웨어는 어쩔 수 없이 메인 메모리(RAM)에 있는 실제 페이지 테이블을 직접 찾아가야 합니다. 이때 하드웨어가 "도대체 메모리 몇 번지에 내가 원하는 PTE가 있지?"를 스스로 계산하기 위해,  이 공식을 사용하여 **원하는 페이지의 PTE 물리 주소(AddressOfPTE)**를 조합해 내는 것입니다.

 

 

 

하이브리드 접근의 문제점

하이브리드 접근도 문제점이 있다. 매우 큰 세그먼트로 나누었을 때, 세그먼트 내부는 선형 구조를 가지므로 그 세그먼트에 해당하는 페이지 테이블을 쓸데없이 메모리를 잡아먹는 상황이 벌어질 수 있다... -> 만약 그런다면 다시 외부 파편화 발생......

 

 

 

끝판왕!

하이브리드 접근방식도 보완한 최종 보스.. 

궁극의 해결책: 멀티 레벨 페이지 테이블 (페이지 10 ~ 14)

드디어 현대 운영체제가 사용하는 구조가 등장합니다. 핵심 아이디어는 **"선형 테이블을 트리(Tree) 구조로 만들자"**입니다.

 
  • 페이지 10: 거대한 페이지 테이블 자체를 페이지 크기(예: 4KB) 단위로 뚝뚝 자릅니다. 그리고 잘라낸 덩어리 안에 유효한 항목(Valid=1)이 단 하나도 없다면, 그 덩어리는 아예 물리 메모리에 할당하지 않습니다.

 

 

  • 페이지 11~12: 할당된 덩어리들과 안 된 덩어리들을 관리할 '총괄 지도'가 필요해졌습니다. 이것이 바로 **페이지 디렉터리(Page Directory)**입니다. 페이지 디렉터리는 '페이지 디렉터리 엔트리(PDE)' (하위 페이지 테이블, 페이지 테이블의 페이지들)들로 구성되며, 각 PDE는 하위 페이지 테이블 덩어리가 유효한지, 그리고 물리 메모리 어디에 있는지(PFN)를 가리킵니다.

 

 

위 페이지에서 생긴 궁금증: PTBR는 뭐지 멀티 레벨 페이지테이블 소개하려고 생긴게 아니고 원래 앞서 페이지 테이블 접근할 때 있던 건데 교안에 안나온건가? 그리고 내가 이해한 페이지 디렉토리, 하위페이지 개념이 맞나?

더보기

1. PTBR은 이전부터 존재했던 레지스터가 맞습니다

네, 맞습니다! PTBR(Page Table Base Register)은 "현재 실행 중인 프로세스의 페이지 테이블이 물리 메모리 어디서 시작하는지"를 알려주는 필수 하드웨어 레지스터입니다.

  • 교안 앞부분의 기본 선형 페이징 파트에서는 '페이징의 기본 원리' 자체에 집중하느라 굳이 그림에 그려 넣지 않고 생략했을 뿐, 실제로는 무조건 존재해야 하는 녀석입니다.
     
  • 왼쪽(Linear)의 PTBR: 거대한 단일 선형 페이지 테이블의 첫 시작점(PFN 201)을 가리킵니다. 동일하게 주소공간을 일정 크기로 나누고 각 덩어리 내부 .
     
  • 오른쪽(Multi-level)의 PTBR: 역할이 살짝 바뀌어서, 여러 조각들을 총괄하는 최상위 지도인 **'페이지 디렉터리'의 시작점(PFN 200)**을 가리킵니다 .

2. 그림 좌우측의 구조 해석도 완벽합니다

  • 왼쪽 (선형 테이블): 통째로 이어진 거대한 표입니다. 중간에 valid=0인 텅 빈 공간(원래라면 PFN 202, 203에 해당하는 자리)도 억지로 빈칸(-)으로 빼곡하게 다 만들어두어 메모리가 낭비되는 전통적인 구조를 보여줍니다 .
     
    • 디렉터리 내부를 보면 중간에 있는 두 개의 항목이 valid=0으로 되어 있죠?
    • 그래서 그 텅 빈 공간에 해당하는 하위 페이지 테이블 조각들은 아예 물리 메모리에 할당조차 하지 않았습니다 ([Page 1 of PT: Not Allocated], [Page 2 of PT: Not Allocated]) .
    • 결과적으로 진짜 데이터가 있는 첫 번째 덩어리(PFN 201)와 마지막 덩어리(PFN 204)라는 하위 테이블 조각들만 쏙쏙 알뜰하게 메모리에 올려둔 모습을 명확하게 보여줍니다
  • 오른쪽 (멀티 레벨 테이블):  PTBR이 가리키는 최상위 **'페이지 디렉터리(PFN 200)'**가 중심을 잡고 있습니다 .

추가 궁금증:

 

1. 페이지디렉토리를 구성하는 PDE도 PTE처럼 여러 정보를 담고 있나? 메모리를 할당한 주소에 대해서만 PDE가 VALID, PFN 정보를 담고 있는것처럼 보여.

2. 페이지 디렉토리에 할당되지 않은 PFN은 -표시와 VALID=0으로 표기되어있는걸 보아 페이지 디렉토리도 선형 구조구나?

 

[답변]

1. PDE의 정보 맞습니다. 교안에 따르면 PDE는 하위 페이지 테이블이 유효한지 나타내는 Valid 비트와 해당 페이지 테이블의 물리적 위치를 나타내는 PFN을 담고 있습니다. PTE가 실제 데이터가 담긴 프레임을 가리킨다면, PDE는 번역표(하위 페이지 테이블)가 담긴 프레임을 가리킨다는 역할의 차이만 있습니다.

 

2. 페이지 디렉터리의 선형 구조 예리한 통찰입니다! 페이지 디렉터리 1장 자체는 선형(Linear) 표 구조가 맞습니다 . 가상 주소의 최상위 인덱스에 따라 모든 PDE의 자리를 연속적으로 만들어두며, 하위 페이지 테이블이 할당되지 않은 구역은 자리를 없애는 것이 아니라 빈칸(Valid=0, -)으로 남겨두어 인덱스를 통한 빠른 접근을 보장합니다 .

 

 

 

덩어리 나누고 그 안에서 쪼갠 부분들이 유효한 부분(페이지 속의 페이지들)이 있는지 없는지 확인 -> 있으면 그 덩어리(부분) 페이지테이블 메모리 할당! (페이지 디렉토리에 PDE 있음) / 유효 부분 아예 없으면 그 덩어리(부분)의 페이지테이블 없음(페이지 디렉토리에 PDE없음)

덩어리 전체가 아니라 그 안에서 "실제로 사용하는 유효한 부분(페이지)에 대해서만" 메모리를 할당합니다.

이해를 위해 여기서 할당되는 메모리를 두 가지로 정확히 나누어 보셔야 합니다.

 

1. 실제 데이터(Code, Heap 등)를 위한 메모리 할당

덩어리(페이지 디렉터리 1칸이 커버하는 가상 주소 구역)의 크기가 예를 들어 4MB라고 가정해 보겠습니다.

이 4MB 구역 안에서 승규님의 프로그램이 딱 4KB(1페이지)만 사용한다면, 운영체제는 물리 메모리(RAM)에 4MB를 몽땅 주지 않고 딱 필요한 4KB(1프레임)만 할당합니다.

 

2. 하위 '페이지 테이블 조각'을 위한 메모리 할당 (교안 10, 11페이지 기준)

이 부분이 멀티 레벨 기법의 핵심입니다.

  • 덩어리 안에 유효한 페이지가 하나도 없다면: 하위 페이지 테이블 조각을 아예 할당하지 않습니다 .
  • 덩어리 안에 유효한 페이지가 단 1개라도 있다면: 그 구역을 번역해 줄 하위 페이지 테이블 조각(보통 4KB 크기 1장)은 물리 메모리에 통째로 할당되어야 합니다 .
  • 즉, 교안 11페이지의 PFN 201 하위 테이블처럼, 그 조각 표 안에는 쓰는 항목(valid=1)과 안 쓰는 항목(valid=0)이 섞여 있게 됩니다 .

💡 요약 덩어리라는 것은 주소를 찾기 위해 나눈 '가상의 논리적 구역'일 뿐입니다. 실제 물리 메모리(RAM)는 언제나 가장 작은 단위인 **'페이지(프레임) 단위'**로, 꼭 필요한 유효 부분과 그것을 관리할 표 조각에 대해서만 알뜰하게 할당됩니다 !

 

 

- 페이지 13:

 

장점: 사용하는 주소 공간에 비례해서만 메모리를 콤팩트하게 쓰므로 공간이 엄청나게 절약됩니다. OS가 빈 페이지를 할당하기도 편해집니다.

단점: 구조가 복잡해지고, TLB Miss가 났을 때 메모리를 두 번(디렉터리 1번, 페이지 테이블 1번)이나 방문해야 하므로 속도가 느려집니다. 전형적인 **시간-공간 트레이드오프(Time-space trade-off)**입니다.

 
  • 페이지 14: 디렉터리라는 간접 참조(Indirection) 계층이 생겼기 때문에, 페이지 테이블 덩어리들을 물리 메모리의 아무 곳에나 자유롭게 흩뿌려 놓을 수 있게 되었습니다.

 

 

4. 상세 분해 예시: 주소 변환 과정 (페이지 15 ~ 20)

멀티 레벨에서 가상 주소가 어떻게 쪼개지는지 보여주는 아주 중요한 예시입니다.

  • 페이지 15: 가상 주소가 14비트, 페이지 크기가 64바이트(2^6)인 미니 시스템입니다. 오프셋은 6비트이고, 나머지 VPN은 8비트입니다.
  • 페이지 16~17: VPN 8비트를 어떻게 자를 것인가?
    • PTE 하나의 크기가 4바이트이므로, 64바이트짜리 페이지 1장에는 16개의 PTE(64/4)가 딱 들어갑니다.
    • 16개의 방을 가리키려면 이진수 4비트가 필요합니다. 따라서 VPN 8비트 중 하위 4비트는 **페이지 테이블 인덱스(PTI)**가 됩니다.
    • 자연스럽게 남은 상위 4비트는 최상위 지도인 **페이지 디렉터리 인덱스(PDI)**가 됩니다.

페이지 크기가 64바이트이므로 offset이 6비트, VPN이 8비트임.

  • 페이지 18~20 (더 깊은 트리): 만약 시스템이 커져서 페이지 디렉터리 자체가 1장(예: 512바이트)을 훌쩍 넘어가면 어떻게 될까요? 페이지 20의 예시처럼 128장이나 필요하다면, 페이지 디렉터리마저도 여러 개로 쪼개어 또 다른 상위 디렉터리를 만듭니다.. 이렇게 되면 VPN이 PD Index 0, PD Index 1, Page Table Index로 3단 분해되는 등 아주 깊은 다단계 트리가 완성됩니다.