[PintOS] Project 3 : Virtual Memory

CorinBeom·2025년 5월 30일

PintOS

목록 보기
8/19
post-thumbnail

드디어 Virtual Memory 주간으로 들어왔다. 여러 사람에게 들은 악명높은 VM을 직접 구현할 때가 왔다 !

일단 구현으로 들어가기 전, 개념을 잡는 포스팅을 작성하려고 한다.
VM에 필요한 개념들과 흐름을 알아보고 가자


Virtual Memory란?

가상 메모리 또는 가상 기억 장치는 메모리 관리 기법의 하나로, 컴퓨터 시스템에 실제로 이용 가능한 기억 자원을 이상적으로 추상화하여 사용자들에게 매우 큰 (주) 메모리로 보이게 만드는 것을 말한다.
각 프로그램에 실제 메모리 주소가 아닌 가상의 메모리 주소를 주는 방식이다.

CSAPP 9장을 보면 Virtual Memory에 관한 내용이 상세하게 나와있다.

각각의 용어들과 그 용어들이 무엇을 의미하고 어떤 인과관계를 가지고 있는지 같이 알아보자


주소 관련 핵심 용어들

VA(Virtual Address) : CPU가 메모리를 참조할 때 사용하는 주소이다. 가상의 세계 주소

PA(Physical Address) : 진짜 DRAM(물리메모리)에 접근할 때 쓰는 주소


페이지 관련 용어들

VP(Virtual Page) : VA를 페이지 단위로 쪼갠 것. 프로그램마다 독립적인 주소 공간을 가진다 !

PP(Physical Address) : 실제 물리 메모리를 페이지 단위로 쪼갠 것

VPO(Virtual Page Offset) : 가상 페이지 내부의 바이트 오프셋

VPN(Virtual Page Number) : VA에서 상위 비트, 어떤 가상 페이지인지를 나타낸다

PPO(Physical Page Offset) : VPO와 동일. 페이지 내부 위치라서 주소 변환을 안해도 된다.

PPN(Physical Page Number) : 변환된 물리 페이지 번호.


페이지 테이블 관련 용어들

PTE(Page Table Entry) :

- VP와 PP 간 매핑 정보를 담은 테이블 항목. Valid BIt, 권한, dirty bit 등을 포함하고 있다

PTBR(Page Table Base Register) :

- 현재 페이지 테이블이 어디 있는지 가리키는 레지스터

TLB(Translation Lookaside Buffer) :

- 최근에 참조한 PTE를 빠르게 캐싱해두는 CPU 내부 캐시

  • TLBI/ TLBT : TLB 인덱스와 태크. VPN으로부터 파생

권한 및 상태 비트들

  • Valid Bit : 해당 VP가 물리 메모리에 올라와 있는지?

  • Dirty Bit : 해당 페이지가 수정된 적이 있는지? (수정한 적이 있으면 깨끗하지 못하여 Dirty)

  • Reference Bit : 최근에 접근한 적이 있는지?

  • R/W Bit : 읽기/쓰기 권한

  • U/S Bit : 유저 모드/커널 모드 접근 가능 여부

  • XD Bit : 실행 금지 비트 (보안용)


CPU는 주소를 참조할 때, 실제 물리 주소를 직접 사용하는 것이 아니라, 가상 주소를 사용한다 !

이 가상 주소는 MMU에 의해 물리 주소로 변환되며, 변환 정보는 페이지 테이블(Page Table)에 저장되어 있다.

하지만 이 변환 정보가 TLB에 없거나, 페이지가 메모리에 로드되어 있지 않다면 Page Fault가 발생한다.

이떄 OS는 보조 페이지 테이블, SPT를 참조하여 해당 주소의 메모리 정보를 확인하고, 필요한 경우 물리 메모리 프레임을 할당하고 페이지를 로딩한 뒤 다시 접근을 시도할 수 있도록 매핑 정보를 갱신한다.

아래에 이 과정을 도식화 해보았다. 👇


[Pintos 가상 메모리 흐름도]

(접근 시부터 MMU 매핑까지의 흐름)

┌────────────────────────────┐
│   사용자 프로그램에서 접근     	 │
│   *(0x8048000) 같은 코드     │
└────────────┬───────────────┘
             ↓ (TLB miss)
┌────────────────────────────┐
│     페이지 폴트 발생           │ 
│     → vm_try_handle_fault  │
└────────────┬───────────────┘
             ↓
┌────────────────────────────┐
│  SPT 조회: spt_find_page    │
│  → 해당 VA에 대응하는          │
│    struct page 찾기         │
└────────────┬───────────────┘
             ↓
┌────────────────────────────┐
│   물리 메모리 없음?            │
│   → vm_claim_page 호출      │
└────────────┬───────────────┘
             ↓
┌────────────────────────────┐
│   프레임 할당:                │
│   vm_get_frame → palloc    │
│   struct frame 생성         │
└────────────┬───────────────┘
             ↓
┌────────────────────────────┐
│   Page ↔ Frame 양방향 연결    │
│   page->frame = frame      │
│   frame->page = page       │
└────────────┬───────────────┘
             ↓
┌─────────────────────────────────┐
│   Lazy load or swap-in          │
│   → page->operations->swap_in() │
└────────────┬────────────────────┘
             ↓
┌────────────────────────────┐
│ PML4에 매핑 등록 (MMU 연결)    │
│ pml4_set_page(va, kva, rw) │
└────────────┬───────────────┘
             ↓
┌────────────────────────────┐
│   접근 성공 & 페이지 폴트 해결   │
└────────────────────────────┘

도식 내 객체 관계 요약


간단한 도식으로 우리는 흐름을 조금이나마 이해할 수 있을 것이다.

근데 여전히 헷갈리는 용어와 개념들... 이대로 구현을 한다면 GPT와의 뜨거운 대화를 피할 수 없을 것이다 !

시작하기 전 개념을 탄탄하게 잡고 가보자. 이번엔 Virtual Memory에서 주로 쓰이는 개념들에 대해 더 자세하게 알아보자


Supplemental Page Table(SPT)? 너 뭔데

  • SPT(Supplemental Page Table)는 운영 체제가 관리하는 가상 주소 공간의 추상화 테이블 이란다.
  • MMU가 단순히 VA → PA만을 담당하는 반명, SPT는 페이지의 의미, 유형, 복원 방식까지 알고 있어야 함.

SPT가 저장하는 정보 예시

struct page {
    void *va;
    struct frame *frame;
    enum vm_type type;  // VM_ANON, VM_FILE, ...
    bool writable;
    bool is_loaded;
    ...
};

즉, SPT는 단순히 "주소가 어디로 매핑되는가?" 가 아니라
"이 주소가 무엇을 의미하는가?" 를 아는 구조다 !


Lazy Allocation / Demand Paging

접근이 있기 전까지 물리 메모리를 할당하는 방식

  • malloc()은 단순히 VA만 등록하고 끝이다 ㅠ

  • 첫 접근 시 Page Falut → SPT에서 정보를 조회하고 프레임을 할당

  • vm_alloc_page_with_initializer() 로 등록 → vm_claim_page()로 실제 할당

흐름 요약

malloc()vm_alloc_page_with_initializer()(접근)
Page Fault
   ↓
vm_claim_page() → frame 할당

페이지 타입 비교 : Anonymous vs File-backed

  • Anonymous Page는 보통 익명 메모리 라고 불리며, 스왑 영역으로만 백업된다 !

  • File-backed Page는 파일 기반 매핑으로, 수정 시 dirty 여부를 보고 write-back 필요


우린 PintOS에서 이걸 어떻게 구현할 것인가?

  • vm.c : 가상 메모리의 핵심 흐름 (SPT, falut 핸들링 등)

  • anon.c : 익명 페이지에 대한 swap-in/out 처리

  • file.c : 파일 매핑 된 페이지 처리

  • uninit.c : 접근 전 초기화 정보 보관


부족한 부분이 있을 수 있으니 양해 바란다. 왜냐면 나도 아직 구현을 안해서 잘 모른다.
나중에 구현이 끝나고 부족한 부분이나 문제가 발생한 부분을 차차 수정해야겠다.

profile
Before Sunrise

0개의 댓글