어떤 가상/물리 메모리가 있을 때, 이 메모리가 사용되고 있는지, 목적은 무엇인지, 누구에 의해 사용되는지 등등, 메모리를 트랙킹할 수 있는 환경을 먼저 구축한다.

이를 위해 큰 목표 2가지를 세운다.

Step 1 : Supplemental Page Table 구현

Step 2 : Physical Frames 구현

struct page

페이지에 대한 모든 정보를 담고 있는 구조체이다.

<aside> 💡 struct page 자체가 페이지는 아니다. 다만, 유저 가상 메모리에 우리가 만들어준 페이지를 관리해주기 위해 프로세스의 커널 주소 영역에 선언해준 구조체이다. 유저 가상 메모리 내 페이지의 실제 주소는 page->va에 있다.

</aside>

include/vm/vm.h

struct page {
  const struct page_operations *operations;
  void *va;              /* Address in terms of user space */
  struct frame *frame;   /* Back reference for frame */

  union {
    struct uninit_page uninit;
    struct anon_page anon;
    struct file_page file;
#ifdef EFILESYS
    struct page_cache page_cache;
#endif
  };
};

구성 요소

page operations

해당 페이지가 가지고 있는 연산의 종류를 나타내는 필드이다. struct thread 안의 필드로 들어가 있다. 현재 크게 세 가지 연산이 존재하는데, 차례대로 swap_in, swap_out, destroy이다. 해당 페이지가 어떤 타입을 가지고 있느냐에 따라 해당 연산을 실제로 수행하는 함수들이 달라진다.

함수 포인터를 활용하여 각 페이지 유형에 맞는 연산을 수행할 것이다.

vm.h/struct page_operations

struct page_operations {
	bool (*swap_in) (struct page *, void *);  
	bool (*swap_out) (struct page *);
	void (*destroy) (struct page *);
	enum vm_type type;
};

#define swap_in(page, v) (page)->operations->swap_in ((page), v)
#define swap_out(page) (page)->operations->swap_out (page)
#define destroy(page) \\
	if ((page)->operations->destroy) (page)->operations->destroy (page)