VM_TYPE

vm_type : Pintos VM에서 "이 가상 페이지가 어떻게 관리해야 하는지"를 담당
Pintos VM의 전체 구조
가상주소(VA)
↓
PML4 (HW page table)
↓
물리 frame (PA)
+ 추가 정보는 SPT가 관리
| 역할 | 담당 |
| 주소 변환 | PML4 |
| 페이지의 의미/상태 | SPT + struct page |
| 실제 물리 메모리 | frame |
| 물리 메모리 관리 | frame table |
1. PML4
PML4는 CPU/MMU가 사용하는 실제 페이지 테이블
역할은 딱 하나
가상주소 -> 물리주소 변환
하지만 PML4는 이런건 모름
ⓐ. 이 페이지가 mmap인지
ⓑ. swap-out 되었는지
ⓒ. lazy loading 대상인지
ⓓ. stack 인지
ⓔ. file-backed인지
ⓕ. 어디서 다시 읽어와야 하는지
즉, "주소 변환"만 가능하고 "운영체제 정책 정보"는 저장 못함
그래서 필요한 것 : SPT
2. Supplemental Page Table (SPT)
SPT는 운영체제가 따로 관리하는 테이블
여기엔 struct page들이 들어감
SPT는 아래 정보를 저장 (파일이)
- anon인가
- file-backed인가
- swap에 있나
- dirty한가
- 어디서 다시 읽어와야 하나?
- 현재 frame이 있나?
즉 PML4의 부족한 정보를 보충(supplement)하기 위한 테이블
3. 그럼 vm_type은 어디서 쓰이나?
struct page 안에서 사용
struct page {
const struct page_operations *operations;
void *va; /* Address in terms of user space */
struct frame *frame; /* Back reference for frame */
/* Your implementation */
/* Per-type data are binded into the union.
* Each function automatically detects the current union */
union {
struct uninit_page uninit;
struct anon_page anon;
struct file_page file;
#ifdef EFILESYS
struct page_cache page_cache;
#endif
};
};
즉, SPT 안의 page 객체가 "나는 어떤 종류 페이지인가?"를 나타내는 값
| 페이지 타입 | page fault 시 |
| anon | swap/file 없이 새 페이지 |
| file | 파일에서 읽어야 함 |
| mmap | 파일과 동기화 필요 |
| uninit | lazy load 필요 |
4. enum vm_type
ⓐ. VM_UNINIT
초기화 안된 페이지
가상주소만 존재하고 아직 실제 frame은 없음 (lazy loading 상태)
예시
ELF 로딩 시 코드 영역 전체를 RAM에 올리지 않음
대신 "나중에 fault 나면 여기서 읽어"라는 정보만 저장
그래서 page fault 발생 시
UNINIT -> 실제 타입으로 변환
VM_UNINIT
↓ first fault
VM_FILE
ⓑ. VM_ANON
anonymous page
파일과 연결되지 않은 페이지
ex. stack, heap, malloc, anonymous mmap
이 페이지는 eviction 시
swap disk로 감 (원본 파일이 없기 때문)
page out -> swap
page in -> swap에서 복구
ⓒ. VM_FILE
파일 기반 페이지
ex. ELF code, mmap file
이 페이지는 eviction 시
dirty면 -> 파일에 write back
clean이면 -> 그냥 버림 (원본 파일이 이미 존재하기 때문)
ⓓ. VM_PAGE_CACHE
FileSystem용 페이지 캐시 (파일 시스템 캐시용)
disk block cache 같은 역할
5. MARKER 비트가 있는 이유
VM_MARKER_0 = (1 << 3) : 추가 상태 비트
기본 타입 + 추가 속성을 비트 OR로 표현 가능
#define VM_STACK (VM_ANON | VM_MARKER_0)
보통 stack 표시 등에 사용 (anon인데 stack 페이지다)
Page & Frame

page : 가상 페이지의 관리자 ( pml4가 모르는 정보들을 담기위해 page가 존재 )
frame : 실제 RAM 4KB 공간의 관리자 ( kva는 실제 물리 프레임을 커널이 접근하기 위한 주소 )
struct page struct frame
+-----------+ +-----------+
| va | user page | kva | physical frame
| frame ----+--------------> | page |
+-----------+ +-----+-----+
|
v
back reference
page는 있어도 frame은 없을 수 있음
예를 들어 lazy loading 상태
SPT에는 page가 있는데, 아직 RAM에는 안 올라옴 [page->frame == NULL]
이 상태에서 유저가 해당 주소에 접근하면 page fault 발생
이 때
1. SPT에서 page 찾음
2. frame 하나 할당
3. 파일/swap/zero page에서 내용 채움
4. page->frame 연결
5. PML4에 va -> frame->kva 매핑
1. 왜 union 구조일까?
struct page는 "부모 클래스"처럼 쓰임
왜냐하면 페이지 종류마다 필요한 정보가 다르기 때문
예시
uninit_page : 아직 로딩 안 된 페이지 (initializer, aux 같은 lazy loading 정보 필요)
anon_page : swap slot 정보 필요
file_page : file 객체, offset, read_bytes, zero_bytes 정보 필요
한 page는 동시에 anon이면서 file 일 수 없기 때문
그래서 union을 써서 필요한 타입 하나의 정보만 저장해서 메모리 절약
2. Operations는 무엇일까?
const struct page_operations *operations;
타입별 함수 테이블
C에서 객체지향을 흉내 내는 방식
예를 들어 page 타입에 따라
swap_in, swap_out, destroy 동작이 달라짐
1. anon page의 swap_out : swap disk에 씀
2. file page의 swap_out : dirty면 파일에 write back
3. uninit page의 swap_in : initializer 실행
실제로 page->operations->swap_in(page, kva)처럼 호출하면, 실제 타입에 맞는 함수가 실행되게 설계
3. 전체 흐름
user가 0x8048000 접근
→ PML4에 매핑 없음
→ page fault
→ 커널은 SPT에서 page를 찾음 spt_find_page(0x8048000)
SPT
└── page
va = 0x8048000
operations = uninit_ops
frame = NULL
union.uninit = "파일의 어느 offset에서 읽을지"
→ frame 할당 후
page
va = 0x8048000
frame ─────┐
v
frame
kva = 0x...
page ─────┘
→ PML4 에는 [0x8048000 → frame->kva 매핑이 생김]
4. eviction 될 때도 둘 다 필요
RAM이 부족하면 frame table에서 victim frame을 고름
victim frame
↓
frame->page 로 어떤 가상 페이지인지 찾음
↓
page type 확인
↓
VM_ANON이면 swap으로 내보냄
↓
VM_FILE이면 dirty 여부 보고 파일에 write back
↓
PML4 매핑 제거 (하지만 SPT에 페이지는 남아 있음)
page->frame = NULL
frame->page = NULL
[나중에 다시 접근하면 page fault가 나고, SPT의 page 정보를 보고 다시 page in 해야 하므로]
'정글캠프-WIL > 서브아이템' 카테고리의 다른 글
| Pintos - vm [페이지 할당 초기화 과정을 위한 흐름도] (0) | 2026.05.14 |
|---|---|
| Pintos - SPT(Supplemental Page Table)와 Hash Table (1) | 2026.05.12 |
| Pintos - 사용자 프로그램 흐름 (0) | 2026.05.11 |
| Pintos - 어떻게 부팅해서 운영체제가 되는가? [2] (0) | 2026.05.01 |
| Pintos - 어떻게 부팅해서 운영체제가 되는가? [1] (0) | 2026.04.30 |