미초기화 페이지 생성 및 페이지 폴트 시 초기화 흐름 - Week12-13-GOAT/pintos-vm GitHub Wiki


  • 흐름 따라가기
    1. vm_alloc_page_with_initializer는 load 내에서 호출되어서 해당 파일의 모든 페이지를 미초기화 페이지로 만들어 준다

      1. 해당 페이지가 요구되어 로드될 때 필요한 정보들을 file_info같은 구조체를 만들어서 필드 내에 저장하여 aux로 저장한다
    2. vm_alloc_page_with_initializer에서 타입에 따른 uninit_new를 사용해서 uninit page를 만들고, 해당 페이지 내의 init 필드에 lazy_load_segment를 등록한다. aux 필드에서 인자로 넘겨받은 aux를 저장한다. 이는 나중에 lazy_load_segment에 aux를 인자로 넘겨줄 수 있다

      1. 이때 미초기화 페이지가 초기화 시에 어떤 함수로 초기화 될 것인지 인자로 넘겨주어야 함
    3. 해당 미초기화 페이지는 SPT에 저장해둔다

    4. 미초기화 페이지의 가상 주소를 요구받고 페이지 폴트가 발생하면 vm_try_handle_fault가 호출되고, 가상 주소에 해당하는 페이지를 만든 다음, vm_do_claim_page가 호출되면서 실제 프레임을 할당받고 매핑해줌

    5. 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도 가져와서 인자로 넘겨주면 된다 !!
    6. lazy_load_segment에서는 aux를 통해 실제 가져와야할 정보를 가져오고, 실제 파일의 정보를 가져오게 된다.

      1. aux 내부에는 파일 포인터, 파일 오프셋, zero-byte, read-byte 등이 필요할듯