PintOS/Project 3 : VIRTUAL MEMORY

[PintOS] Proejct 3 : VM Memory Management - frame, page, SPT, frame table

넌뭐가그렇게중요해 2025. 6. 5. 13:51

PintOS의 Project 3(Virtual Memory)에서는 메모리 관리 구조체들을 직접 설계해야 합니다. 이 과정에서 저희 팀은 계층적인(hierarchy) 구조를 이용하여 page, frame, SPT(Supplemental Page Table), frame table 등 다양한 구조체를 설계하고, 서로 연결해 효율적으로 메모리를 관리합니다.

이 포스팅에서는 vm.h를 기준으로 구조체들이 어떻게 설계되어 있고, 어떤 의미를 가지며, 이러한 계층적 구조가 가지는 장점은 무엇인지에 대해 정리해 보겠습니다.


전체 구조 개요

저희 팀의 PintOS의 가상 메모리 구조입니다. 

[Supplemental Page Table (SPT)]
         └── 여러 개의 SPT Entry (key: va, value: page)
                    └── struct page (가상 주소 공간에서의 페이지)
                              └── struct frame (실제 물리 메모리에 올라간 경우)

1. struct page - 사용자 가상 주소 공간에서의 페이지

// ..include/vm/vm.h
/* "page"의 표현입니다.
 * 이것은 일종의 "부모 클래스"로, 네 개의 "자식 클래스"를 가집니다:
 * uninit_page, file_page, anon_page, 그리고 페이지 캐시(project4).
 * 이 구조체의 미리 정의된 멤버는 제거/수정하지 마세요. */
struct page
{
	const struct page_operations *operations;
	void *va;			 /* 사용자 공간 기준의 주소 */
	struct frame *frame; /* frame에 대한 역참조 */

	/* 구현 필드 */
	bool writable;
	// 매핑된 프레임이 스왑되어있는가??
	bool is_swap;

	/* 타입별 데이터는 union에 바인딩됩니다.
	 * 각 함수는 현재 union을 자동으로 감지합니다. */
	union
	{
		struct uninit_page uninit;
		struct anon_page anon;
		struct file_page file;
#ifdef EFILESYS
		struct page_cache page_cache;
#endif
	};
};

1.1 의미 분석

필드명 의미
va 이 페이지가 매핑될 사용자 가상 주소. 즉, 사용자 입장에서 보고 싶은 주소
frame 이 페이지가 실제로 물리 메모리에 올라갔다면 연결되는 frame 포인터.
없다면 스왑되었거나 아직 로드되지 않았을 수 있습니다. 
writable 이 페이지가 쓰기 가능한지 여부를 나타냅니다.
is_swap 이 페이지가 현재 스왑 영역에 있는지를 나타냅니다.
union 페이지의 타입(UNINIT, ANON, FILE 등)에 따라 실제 동작이 달라지므로, 타입에 따라 사용하는 구조체가 달라집니다.
operations 이 페이지가 어떤 타입인지에 따라 알맞은 함수 포인터 테이블이 연결됩니다.
(swap_in, swap_out, destroy 등)

1.2 구조적 특징 - C언어에서 구현한 '다형성(polymorphism)' 구조

struct page는 일종의 부모 객체처럼 동작합니다. union을 통해 타입에 따라 anon, file, uninit 페이지를 담고,
operations는 해당 타입에 따라 다르게 설정되는 함수 포인터 테이블입니다.

// ..include/vm/vm.h
struct page_operations {
    bool (*swap_in)(struct page *, void *);   // 메모리로 다시 불러오기
    bool (*swap_out)(struct page *);          // 스왑 아웃
    void (*destroy)(struct page *);           // 해제
    enum vm_type type;
};
  • 즉, page->operations->swap_in(page, aux)과 같이 호출하면,
    → anon_page라면 anon용 swap_in,
    → file_page라면 file용 swap_in이 자동으로 실행됩니다.
이것은 C언어에서 OOP의 다형성(polymorphism)을 구현한 대표적인 방식입니다. 
Java나 C++에서 다형성은 override 된 메서드를 가상 함수 테이블(V-Table)을 통해 호출하는데, C에서는 이를 명시적으로 struct에 함수 포인터를 넣어 직접 구성합니다.

비교: 객체지향 vs PintOS구조

개념 Java/C++ PintOS(C)
부모 클래스 class Page {} struct page {}
자식 클래스 class AnonPage extends Page union {struct anon_page anon; .... }
오버라이딩 메서드 @override swapIn() struct page_operations { ... }
다형성 호출 page.swapIn() page→operations→swap_in(page)

 

이 구조 덕분에 vm_get_page()나 vm_try_handle_fault() 같은 코드에서 페이지의 타입을 직접 검사하지 않고도,
페이지에 알맞은 행동(swap_in, destroy)을 자동으로 실행할 수 있어 코드의 유연성 및 유지보수성이 크게 향상됩니다.


2. struct frame - 실제 물리 메모리의 한 페이지(Frame)

/* The representation of "frame" */
struct frame
{
	void *kva;
	/* extra-cow */
	int ref_cnt;
	struct page *page;
	// frame_table 소속 elem
	struct list_elem elem;
};

2.1 의미 분석

필드명 의미
kva 해당 frame에 매핑된 커널 가상 주소(Kernel Virtual Address)입니다.
이것은 실제 물리 주소와 거의 1:1 매핑된 주소입니다.
ref_cnt COW(Copy-On-Write) 구현에 사용되는 참조 카운트입니다. 하나의 frame을 여러 ㅔㅍ이지가 공유할 수 있도록 합니다.
page 이 frame이 매핑되어 있는 가상 페이지를 역참조합니다. 
elem frame_table이라는 전역 리스트에서 이 frame을 연결할 때 사용하는 리스트 요소입니다.

장점 

  • 페이지 ← - → 프레임 간 양방향 연결을 유지하여 빠르게 Frame 찾기/해제 가능
  • 프레임 테이블을 통해 교체 알고리즘 적용 용이(clock algorithm 등)

3. struct supplemental_page_table (SPT) - 사용자 프로세스의 가상 메모리 공간

/* 현재 프로세스의 메모리 공간을 나타냅니다.
 * 이 구조체에 대해 특정 설계를 강제하지 않습니다.
 * 모든 설계는 여러분에게 달려 있습니다. */
struct supplemental_page_table
{
	struct hash SPT_hash_list;
};

SPT는 프로세스마다 존재하며, 가상 주소를 key로 하여 해당 주소에 매핑된 struct page를 저장하는 해시 테이블입니다.


3.1 SPT의 역할

  • 페이지 폴트 시 해당 주소가 어떤 페이지에 해당하는지 찾아냄
  • 프로세스 복사(fork) 시 자식 프로세스에게 가상 메모리 정보를 복사해 줌

4. struct SPT_entry - 해시 테이블 안의 개별 엔트리

struct SPT_entry
{
	/* 이 엔트리의 키 값이 될 가상 주소 */
	void *va;
	/* 페이지 */
	struct page *page;
	/* 해시 테이블 요소*/
	struct hash_elem elem;
};

5. 구조적 흐름 예시

1. 페이지 fault 발생 → spt_find_page()로 해당 va 검색
2. 해당 page 구조체를 찾음
3. page 구조체가 가리키는 frame 확인
    - 없다면 → 스왑에서 불러오거나 초기화(load)
4. 물리 메모리에 frame 할당 → page-frame 연결