include/vm/vm.h에 정의되어 있는 page는 가상 메모리에서의 페이지를 의미하는 구조체
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
};
};
operations
, virtual address
, physical frame
( + union
멤버(=필드))하나의 메모리 영역에 다른 타입의 데이터를 저장하는 것을 허용
uninit_page
, anon_page
, file_page
, page_cache
struct anon_page anon
을 멤버 중 하나로 가지고 있다.anon_page
은 익명 페이지를 위해 우리가 기억해야 하는 필수적인 정보들을 담고 있다.struct page_operations {
bool (*swap_in) (struct page *, void *);
bool (*swap_out) (struct page *);
void (*destroy) (struct page *); //
enum vm_type type;
};
VM_UNINIT
인 경우#define destroy(page)
if ((page)->operations->destroy) (page)->operations->destroy (page)
vm/uninit.c
static const struct page_operations uninit_ops = {
.swap_in = uninit_initialize,
.swap_out = NULL,
.destroy = uninit_destroy,
.type = VM_UNINIT,
};
/* vm/file.c -> type = VM_FILE & .destroy = file_destroy
* vm/anon.c -> type = VM_ANON & .destroy = anon_destroy
*/
보충 페이지 테이블 : 각 페이지에 대한 추가적인 정보를 담고 있기 때문에, 페이지 폴트와 자원 관리를 처리 가능
- pml4 : 가상 메모리와 물리 메모리를 매핑하는 것을 관리
보조 페이지 테이블를 초기화
void supplemental_page_table_init (struct supplemental_page_table *spt);
인자로 넘겨진 보조 페이지 테이블에서로부터 가상 주소(va)와 대응되는 페이지 구조체를 찾아서 반환
실패했을 경우 NULL를 반환
struct page *spt_find_page (struct supplemental_page_table *spt, void *va);
인자로 주어진 보조 페이지 테이블에 페이지 구조체를 삽입
bool spt_insert_page (struct supplemental_page_table *spt, struct page *page);
/* The representation of "frame" */
struct frame {
void *kva;
struct page *page;
};
kva
는 커널 가상 주소, page
는 페이지 구조체를 담기
palloc_get_page
함수를 호출함으로써 유저 메모리 풀 에서 새로운 물리메모리 페이지 (프레임) 를 가져오기
static struct frame *vm_get_frame (void);
반환 성공 : 프레임을 할당하고 프레임 구조체의 멤버들을 초기화한 후 해당 프레임을 반환
항상 유효한 주소를 반환
사용 가능한 페이지가 없을 때 즉, 사용자 풀 메모리가 가득 찬 경우에는 페이지를 제거하고 반환
page에 물리 메모리 프레임을 할당
bool vm_do_claim_page (struct page *page);
인자로 주어진 va에 페이지를 할당하고, 해당 페이지에 프레임을 할당
bool vm_claim_page (void *va);