배경

lazy laoding을 보면서, 내부에서 install_page 함수가 사용되는것을 보았다. 이 함수는 kpage가 가리키는 실제 메모리 주소를 upage와 매핑될 수 있도록 pml4에 추가해주는 작업을 담당한다.

static bool
install_page(void *upage, void *kpage, bool writable)
{
	struct thread *t = thread_current();

	/* Verify that there's not already a page at that virtual
	 * address, then map our page there. */
	return (pml4_get_page(t->pml4, upage) == NULL && pml4_set_page(t->pml4, upage, kpage, writable));
}

의문점

kpage는 palloc을 통해 얻은 주소인데, 프로세스에서 다루는 주소는 전부 가상주소라고 들었다. pml4에 kpage, upage를 등록하는걸로 보이는데, pml4에는 가상 주소들간의 매핑정보가 들어가는건가? 실제 주소로 변환해주기 위해서 추가 작업이 있는것인가?

피드백

pml4에는 가상주소와 실제 프레임 주소 매핑 정보가 들어간다.

install_page에서 하는 작업은 kpage가 가리키는 프레임에 대해 upage 와 매핑 정보를 pml4에 추가하는거시다. 아래 pml4_set_page 에서 어떤 일이 일어나는지 보면 된다.

/* Adds a mapping in page map level 4 PML4 from user virtual page
 * UPAGE to the physical frame identified by kernel virtual address KPAGE.
 * UPAGE must not already be mapped. KPAGE should probably be a page obtained
 * from the user pool with palloc_get_page().
 * If WRITABLE is true, the new page is read/write;
 * otherwise it is read-only.
 * Returns true if successful, false if memory allocation
 * failed. */
bool
pml4_set_page (uint64_t *pml4, void *upage, void *kpage, bool rw) {
	ASSERT (pg_ofs (upage) == 0);
	ASSERT (pg_ofs (kpage) == 0);
	ASSERT (is_user_vaddr (upage));
	ASSERT (pml4 != base_pml4);

	uint64_t *pte = pml4e_walk (pml4, (uint64_t) upage, 1);

	if (pte)
		*pte = vtop (kpage) | PTE_P | (rw ? PTE_W : 0) | PTE_U;
	return pte != NULL;
}

여기서 vtop이라는 매크로가 등장하는데, 이게 실제 메모리 주소를 계산하는 역할을 한다. pintos에서는 실메 메모리주소는 커널 영역 주소에서 KENR_BASE 를 빼주어 구한다. AI에게 물어보니, 최신 OS에서는 더 복잡한 방법을 사용하지만, 이런 흐름으로 커널 주소와 실제 물리 주소를 구한다고 한다.

/* Returns physical address at which kernel virtual address VADDR
 * is mapped. */
#define vtop(vaddr) \
({ \
	ASSERT(is_kernel_vaddr(vaddr)); \
	((uint64_t) (vaddr) - (uint64_t) KERN_BASE);\
}) 

정리

내가 헷갈린것은 install_page에서 매개인자로 kpage, upage가 들어가는것을 보고, 가상주소간 매핑 정보가 pml4에 들어간다고 착각한 것이다.

실제로는 가상주소와 실제 주소 매핑정보가 들어가는고, kpage가 가리키는 물리 주소를 구하기 위해서 kpage가 매개인자로 들어간 것이다.

kpage와실제메모리관계.png

추가로 알아낸 사실

같은 프레임을 가리키는 두 가상주소가 있다.

결론을 통해 upage, kpage는 결국 같은 프레임을 가리킨다는걸 알 수 있었다. 그렇다면 프레임에 접근하는데 2개의 주소가 생긴걸까?

내가 이해한걸로는 역할 분리때문이다.