• CPU의 착각: C언어 프로그램(프로세스)이 실행될 때 CPU는 가상 주소(Virtual Address)를 받아 동작합니다. OS는 가상 주소를 통해 CPU를 속이며, 실제 물리 주소(Physical Address)와의 연결은 하드웨어인 MMU(주소 변환 장치)가 처리합니다.
• PML4 (4단계 페이지 테이블 구조): 핀토스는 64비트 가상 주소 체계를 사용합니다.
• 주소 파싱: 총 64비트 중 상위 16비트는 버리고, 9비트 / 9비트 / 9비트 / 9비트 / 12비트(Offset)로 쪼개어 물리 주소를 찾습니다.
• 페이지 크기: 최하위 12비트((2^{12}))가 오프셋이 되므로, 기본 페이지 크기는 4KB가 됩니다.
• 테이블 구조: 질문하신 "가로 8바이트, 세로 512개"의 구조를 가진 엔트리 테이블을 페이지 테이블(Page Table) 또는 핀토스 내에서 PML4라 부릅니다. 각 엔트리(8바이트)는 다음 단계 테이블의 물리 주소를 가리키며, 마지막 4단계 테이블 엔트리가 실제 물리 프레임 주소를 저장합니다. 만약 가리키는 주소가 없으면 Page Fault가 발생합니다.
• 16진수를 쓰는 이유: 16진수 수치(예: 0xF000)는 2진수 비트 연산 및 변환이 매우 직관적이고 용이하기 때문입니다.
• 커널 가상 주소 (KVA) 매핑: 모든 프로세스는 커널 영역이 미리 매핑된 PML4를 가집니다. 핀토스 커널은 물리 주소와 가상 주소가 1대1로 다이렉트 매핑되어 있습니다.
• (\text{KVA} = \text{PA} + \text{Kernel Base Address}) (예시: kva = pa + 0x8004000000)
• 초기화와 ELF: 커널이 초기화된 후 사용자 프로그램을 실행할 때, 디스크의 ELF 파일을 읽습니다. ELF 파일 안에는 프로그램의 코드와 데이터가 가상 주소(VA) 기준으로 어디에 위치해야 하는지 명시되어 있습니다.
• 메모리 풀 (Kernel Pool vs User Pool):
• Kernel Pool: 커널 내부 자료구조, 스레드 구조체 등을 위한 공간입니다.
• User Pool: 사용자 프로그램(프로세스)에게 할당되는 4KB 단위의 프레임(Frame) 공간입니다. 유저 가상 주소(UVA)와 커널 가상 주소(KVA)를 통해 모두 접근할 수 있는 영역입니다.
• 요청 재고(Demand Paging): 모든 ELF 데이터를 한 번에 User Pool에 담을 수 없으므로, 사용하는 시점(주소 요청 시점)에 디스크에서 메모리로 가져옵니다.
• 보조 페이지 테이블 (SPT): 핀토스 가상 메모리(VM) 과제의 핵심 자료구조입니다. 각 스레드(프로세스) 구조체 내부에 하나씩 존재합니다.
• 역할: 하드웨어 PML4만으로는 디스크의 어디(ELF 파일 내 오프셋 등)에 데이터가 있는지, 이 페이지의 타입이 무엇인지 알 수 없습니다. SPT가 가상 주소(VA)별로 디스크 위치 정보 및 페이지 타입을 보관합니다.
• 초기 실행: Main 함수가 실행되기 전, ELF 파일을 읽어 가상 주소 구조만 SPT에 등록(uninit 상태)해 두고 실제 물리 메모리(User Pool)는 할당하지 않은 채 실행을 시작합니다.
CPU가 명령어를 Fetch/Decode/Execute 하는 도중, 메모리에 없는 가상 주소에 접근하면 CPU Exception인 Page Fault가 발생합니다.
1. 핸들러 작동: Page Fault 핸들러가 가동되어 실패한 가상 주소를 확인하고 SPT를 조회합니다.
2. 경우의 수 (Page Life Cycle):
• Uninitialized (한 번도 접근 안 한 상태): SPT에서 ELF 파일 위치를 확인하고, User Pool에서 4KB 프레임을 하나 할당받아 디스크의 내용을 메모리로 읽어옵니다(Lazy Loading). 그 후 PML4에 가상 주소-물리 주소를 1대1 매핑합니다.
• Swapped-out (스왑 배치 상태): 과거에 메모리가 모자라 디스크로 쫓겨났던 상태라면, Swap Disk에서 데이터를 다시 메모리로 가져옵니다 (Swap-In / Anonymous Page 유형).
• 진짜 오류: 핸들러가 SPT를 뒤졌는데도 해당 주소 정보가 전혀 없다면 유효하지 않은 접근입니다. 이 경우 프로세스를 종료하고 관련 SPT 및 메모리를 Free(삭제)합니다.
• 프레임 테이블 (Frame Table): 시스템 전체에 단 하나만 존재하는 전역 자료구조입니다. 현재 User Pool의 어느 물리 프레임이 쓰이고 있고(Allocated), 어느 SPT(또는 PML4) 페이지와 연결되어 있는지 관리합니다.
• 메모리 고갈과 Clock 알고리즘:
• User Pool이 가득 찬 상태에서 새로운 페이지 폴트가 발생하면 물리 메모리를 비워야 합니다.
• 프레임 테이블을 순회하며 Clock 알고리즘(가장 오랫동안 쓰이지 않은 페이지 참조 비트를 체크하여 선택)을 통해 쫓아낼 프레임(Victim)을 고릅니다.
• 페이지 타입별 교체 방식 (Swap-Out):
1. Anonymous Page (스택, 힙 등): 쫓겨날 때 내용이 보존되어야 하므로 디스크의 Swap Disk(swap.dsk)에 메모리 내용을 저장합니다 (Swap-Out).
2. File-backed Page (ELF, Read-only 파일 등): 데이터가 이미 디스크(ELF 파일)에 그대로 존재하며, 수정되지 않는(Read-only) 데이터라면 굳이 스왑 공간에 쓸 필요 없이 그냥 메모리에서 버려도(Free) 됩니다. 나중에 다시 필요하면 원래 파일에서 다시 읽어오면 되기 때문입니다.