페이지 테이블은 주소를 어떻게 실제 메모리 위치로 바꿀까
프로그램이 가상 주소를 읽으면 CPU는 실제 RAM에서 어느 위치를 찾아야 하는지 알아야 한다. 페이지 테이블은 가상 페이지와 물리 프레임 사이의 대응을 보관하는 자료구조다. 주소 변환표라고 부를 수 있지만 단순한 위치 목록만은 아니다. 접근 권한과 페이지 상태도 담아 메모리 보호와 운영체제의 관리 결정을 돕는다.
페이지 번호는 변환되고 페이지 안의 오프셋은 유지된다.
주소를 두 부분으로 나눈다
페이지 크기가 4KiB인 설명용 시스템에서는 한 페이지 안의 위치를 12비트로 표현한다. 가상 주소의 나머지 부분은 가상 페이지 번호다. 변환할 때는 페이지 번호를 물리 프레임 번호로 바꾸고, 페이지 내부 오프셋은 그대로 사용한다. 프레임과 페이지가 같은 크기라 가능한 방식이다. 실제 시스템은 여러 페이지 크기와 추가 주소 규칙을 지원할 수 있다.
가상 주소 0x3123을 예로 들면 페이지 번호는 3, 오프셋은 0x123이다. 페이지 3이 물리 프레임 9에 연결돼 있다면 결과 주소는 0x9123이 된다. 이는 4KiB 페이지, 단순한 번호 매김을 가정한 예제다. 주소 변환에서 바뀌는 부분과 보존되는 부분을 구분하면 계산을 기계적으로 암기할 필요가 없다.
항목에 들어가는 보호 정보
페이지 테이블 항목에는 프레임 위치 외에 존재 여부, 읽기·쓰기·실행 권한, 접근 및 수정 상태 등이 들어갈 수 있다. 어떤 비트가 있고 누가 갱신하는지는 CPU 구조마다 다르다. Linux의 페이지 테이블 문서는 계층 구조와 페이지 테이블 항목의 역할을 설명한다. 운영체제는 이런 정보를 통해 읽기 전용 코드에 쓰는 접근을 거부할 수 있다.
각 프로세스에 거대한 단일 배열을 두면 비어 있는 주소 영역에도 항목 공간이 필요하다. 그래서 여러 단계의 표를 두고 실제로 쓰는 영역에 필요한 하위 표만 만드는 방식이 흔하다. 상위 표는 하위 표의 위치를 가리키고, 마지막 단계가 실제 물리 페이지를 가리킨다. 넓고 드문드문 사용하는 주소 공간에서 관리 메모리를 아낄 수 있다.
공간을 아끼면 탐색 단계가 늘어난다
다단계 표는 변환 하나에 여러 항목을 따라가야 한다는 비용이 있다. 이 비용을 매번 지불하지 않기 위해 CPU는 최근 변환을 TLB라는 캐시에 보관한다. TLB에서 필요한 변환을 찾으면 전체 페이지 테이블 탐색을 생략할 수 있다. TLB 실패와 페이지가 RAM에 없는 상태는 서로 다르며, 표를 읽어 정상적인 변환을 찾는 것만으로 해결되기도 한다.
페이지 테이블을 수정할 때는 이미 캐시에 남아 있는 옛 변환을 고려해야 한다. 접근 권한을 바꿨는데 다른 코어가 이전 정보를 계속 쓰면 의도한 보호가 적용되지 않을 수 있다. 운영체제는 필요한 범위의 변환 캐시를 무효화하고 여러 코어와 상태를 맞춘다. 이 동기화 비용은 큰 메모리 영역의 매핑을 자주 바꾸는 작업에서 드러날 수 있다.
큰 페이지를 쓰면 같은 메모리를 나타내는 항목 수를 줄이고 TLB가 덮는 범위를 넓힐 수 있다. 반면 작은 할당에 큰 페이지를 사용하면 내부 낭비가 늘거나 연속 물리 공간 확보가 어려워질 수 있다. 페이지 테이블은 주소 변환의 정확성과 공간·시간 비용을 함께 설계하는 지점이며, 단순히 표를 더 크게 만드는 것만으로 모든 문제를 해결하지 않는다.