미초기화 페이지 생성 및 페이지 폴트 시 초기화 흐름 - Week12-13-GOAT/pintos-vm GitHub Wiki
- 흐름 따라가기
-
vm_alloc_page_with_initializer
는 load 내에서 호출되어서 해당 파일의 모든 페이지를 미초기화 페이지로 만들어 준다- 해당 페이지가 요구되어 로드될 때 필요한 정보들을 file_info같은 구조체를 만들어서 필드 내에 저장하여 aux로 저장한다
-
vm_alloc_page_with_initializer
에서 타입에 따른 uninit_new를 사용해서 uninit page를 만들고, 해당 페이지 내의 init 필드에lazy_load_segment
를 등록한다. aux 필드에서 인자로 넘겨받은 aux를 저장한다. 이는 나중에 lazy_load_segment에 aux를 인자로 넘겨줄 수 있다- 이때 미초기화 페이지가 초기화 시에 어떤 함수로 초기화 될 것인지 인자로 넘겨주어야 함
-
해당 미초기화 페이지는 SPT에 저장해둔다
-
미초기화 페이지의 가상 주소를 요구받고 페이지 폴트가 발생하면 vm_try_handle_fault가 호출되고, 가상 주소에 해당하는 페이지를 만든 다음, vm_do_claim_page가 호출되면서 실제 프레임을 할당받고 매핑해줌
-
swap_in을 통해 그 페이지의 init를 호출한다. init에는 lazy_load_segment를 등록해두었기 때문에 에 해당 함수가 호출된다.
static const struct page_operations uninit_ops = { .swap_in = uninit_initialize, .swap_out = NULL, .destroy = uninit_destroy, .type = VM_UNINIT, };
- uninit 페이지는 이렇게 swap_in에서 uninit_initialize가 등록되어있음
static bool uninit_initialize (struct page *page, void *kva) { struct uninit_page *uninit = &page->uninit; /* Fetch first, page_initialize may overwrite the values */ vm_initializer *init = uninit->init; void *aux = uninit->aux; /* TODO: You may need to fix this function. */ return uninit->page_initializer (page, uninit->type, kva) && (init ? init (page, aux) : true); }
- uninit_initialize는 uninit_page 필드에 들어있는 함수 lazy_load_segment를 *init에 가져와서 사용하게 된다.
- 또한 uninit_page에 저장되었던 aux도 가져와서 인자로 넘겨주면 된다 !!
-
lazy_load_segment에서는 aux를 통해 실제 가져와야할 정보를 가져오고, 실제 파일의 정보를 가져오게 된다.
- aux 내부에는 파일 포인터, 파일 오프셋, zero-byte, read-byte 등이 필요할듯
-