
어제에 이어서 Gitbook의 Memory Management 구현을 이어가 보겠습니다
static struct frame *
vm_get_frame (void) {
struct frame *frame = NULL;
/* TODO: Fill this function. */
void *kva = palloc_get_page(PAL_USER); // user pool에서 새로운 physical page를 가져온다.
if (kva == NULL) // page 할당 실패
{
struct frame *victim = vm_evict_frame();
victim->page = NULL;
return victim;
}
vm_get_frame 함수는 가상 메모리 관리를 위해 프레임(물리 메모리 페이지)을 가져오는 역할을 합니다
struct frame *vm_get_frame(void): 물리 프레임(물리 페이지)을 할당하기 위한 함수입니다. 반환 값으로 struct frame 포인터를 반환합니다.
frame 변수를 NULL로 초기화합니다.
palloc_get_page(PAL_USER) 함수를 사용하여 사용 가능한 물리 페이지를 할당합니다. PAL_USER 플래그는 사용자 영역에서 페이지를 할당하도록 지정합니다.
할당된 물리 페이지의 주소를 kva 변수에 저장합니다.
만약 페이지 할당에 실패하여 kva가 NULL인 경우, vm_evict_frame 함수를 호출하여 물리 프레임을 억류시킵니다. 이를 위해 희생 프레임(victim frame)을 얻어온 후, 해당 프레임의 page 멤버를 NULL로 설정하고 반환합니다.
페이지 할당에 성공한 경우, frame 변수를 초기화한 물리 프레임으로 설정합니다. 즉, frame->page은 현재 할당된 페이지를 가리키게 됩니다.
페이지 테이블 엔트리를 설정하여 페이지의 가상 주소(page->va)와 물리 주소(frame->kva)를 매핑합니다. 이는 가상 주소를 물리 주소로 변환하여 페이지 테이블에 등록하는 과정입니다.
swap_in 함수를 호출하여 스왑 공간에서 페이지를 물리 메모리로 복사합니다.
frame 포인터를 반환합니다.
위의 코드는 주석으로 TODO: Fill this function.이 적혀있는 부분으로, 실제로 물리 프레임을 할당하고 페이지 테이블 엔트리를 설정하는 부분이 구현되어야 합니다. 이 함수는 Pintos 프로젝트의 가상 메모리 관리 시스템에서 사용되며, 구체적인 동작은 해당 프로젝트의 목적과 구현에 따라 달라질 수 있습니다
static bool
vm_do_claim_page (struct page *page) {
struct frame *frame = vm_get_frame ();
/* Set links */
frame->page = page;
page->frame = frame;
/* TODO: Insert page table entry to map page's VA to frame's PA. */
struct thread *current = thread_current();
pml4_set_page(current->pml4, page->va, frame->kva, page->writable);
return swap_in (page, frame->kva);
}
위의 코드는 vm_do_claim_page 함수입니다.
bool vm_do_claim_page(struct page *page): 페이지를 할당하고 매핑하는 함수입니다. 페이지를 할당하고 페이지 테이블 엔트리를 설정한 후, 페이지를 물리 메모리로 스왑 인(swap in)합니다. 반환 값으로 성공 여부인 불리언 값을 반환합니다.
vm_get_frame 함수를 호출하여 물리 프레임(물리 페이지)을 얻어옵니다. vm_get_frame 함수는 사용 가능한 물리 페이지를 할당하고, 해당 페이지를 가리키는 struct frame 포인터를 반환합니다.
frame->page에 현재 할당된 페이지(page)를 설정하여 프레임과 페이지 간의 링크를 설정합니다.
page->frame에도 할당된 프레임(frame)을 설정합니다. 이를 통해 페이지와 프레임 간의 상호 참조를 구성합니다.
현재 스레드(thread_current())의 페이지 매핑 레벨 4 테이블(PML4)에 페이지 테이블 엔트리를 설정합니다. pml4_set_page 함수를 사용하여 가상 주소(page->va), 물리 주소(frame->kva), 그리고 페이지의 쓰기 가능 여부(page->writable)를 매핑합니다.
swap_in 함수를 호출하여 페이지를 물리 메모리로 스왑 인합니다. 스왑 공간에서 해당 페이지의 내용을 물리 메모리로 복사합니다.
스왑 인이 성공한 경우 true를 반환하고, 실패한 경우 false를 반환합니다.
이 함수는 페이지를 할당하고 페이지 테이블 엔트리를 설정하여 가상 주소와 물리 주소를 매핑한 후, 스왑 인을 수행하여 페이지의 내용을 물리 메모리로 가져옵니다. 이를 통해 페이지에 대한 접근이 가능해지며, 페이지 테이블과 관련된 작업을 수행할 수 있습니다.
위의 코드에서 주석으로 TODO가 달린 부분은 페이지 테이블 엔트리를 설정하는 코드입니다. 실제로 페이지 테이블 엔트리를 설정하려면 해당 부분을 구현해주어야 합니다. 구체적인 페이지 테이블 엔트리 설정 방식은 사용하는 가상 메모리 관리 시스템과 프로젝트의 구현 방식에 따라 달라질 수 있습니다. 따라서, 해당 부분은 프로젝트의 목적과 구현에 맞게 수정되어야 합니다
bool
vm_claim_page (void *va UNUSED) {
struct page *page = NULL;
/* TODO: Fill this function */
page = spt_find_page(&thread_current()->spt, va);
if (page == NULL)
return false;
return vm_do_claim_page (page);
}
위의 코드는 vm_claim_page 함수입니다.
bool vm_claim_page(void *va): 주어진 가상 주소(va)에 해당하는 페이지를 할당하고 매핑하는 함수입니다. 가상 주소를 사용하여 페이지를 찾은 후, vm_do_claim_page 함수를 호출하여 페이지를 할당하고 매핑합니다. 반환 값으로 성공 여부인 불리언 값을 반환합니다.
spt_find_page 함수를 호출하여 현재 스레드의 보충 페이지 테이블에서 주어진 가상 주소(va)에 해당하는 페이지를 찾습니다. spt_find_page 함수는 주어진 가상 주소를 해시 테이블에서 검색하여 페이지를 반환합니다.
찾은 페이지가 NULL인 경우, 즉 페이지가 존재하지 않는 경우 false를 반환합니다.
vm_do_claim_page 함수를 호출하여 페이지를 할당하고 매핑합니다. 이 함수는 위에서 설명한대로 페이지를 할당하고 페이지 테이블 엔트리를 설정하여 페이지를 물리 메모리로 스왑 인합니다.
vm_do_claim_page 함수의 반환 값을 그대로 반환합니다.
이 함수는 주어진 가상 주소에 해당하는 페이지를 찾아서 vm_do_claim_page 함수를 호출하여 페이지를 할당하고 매핑하는 역할을 합니다. 즉, 가상 주소와 관련된 페이지를 보충 페이지 테이블에서 찾아 할당하는 작업을 수행합니다.
위의 코드에서 주석으로 TODO가 달린 부분은 페이지를 찾아 할당하는 부분입니다. 실제로 페이지를 찾는 방식은 spt_find_page 함수 내부에서 구현되어야 합니다. 또한, 페이지를 할당하고 매핑하는 부분은 vm_do_claim_page 함수 내부에서 처리됩니다. 이 부분들은 프로젝트의 목적과 구현 방식에 따라 수정되어야 합니다.