개념

Part 1 : Memory Management

Part 2 : Anonymous Page & Lazy Loading

Part 3 : Stack Growth

Part 4 : Memory Mapped Files(File Backed mapping)

Part 5 : Swap In/Out

현재 핀토스 가상 메모리는 어떻게 관리되고 있는가(참조)?

핀토스 유저 메모리

핀토스 유저 메모리

핀토스뿐만 아니라 x86-64 시스템은 다이렉트로 물리 메모리에 접근할수는 없다. 하지만 물리 메모리 주소를 알고 그것을 이용해 접근해야 하는 경우가 있으므로, 각 프로세스의 가상 주소 공간에서 커널 주소 공간과 실제 물리 메모리를 일대일 매칭시킨다.

Untitled

핀토스에서 각 프로세스의 가상 메모리는 크게 두 가지, kernel space와 user space로 나눠진다. 가상 메모리는 페이지 단위로 나뉘어 물리 메모리의 각 프레임에 매핑된다. 이 때, 프로세스의 kernel space는 물리 메모리와 일대일 매핑이 된다는 것을 기억하자.

vtop()를 통해 커널 가상 주소를 물리 메모리 주소로 변환할 수 있는데, 위 그림에서 보는 것처럼 KERN_BASE를 빼 주면 된다.

#define vtop(vaddr) \\
({ \\
	ASSERT(is_kernel_vaddr(vaddr)); \\
	((uint64_t) (vaddr) - (uint64_t) KERN_BASE);\\
})

palloc_get_page()를 통해 물리 메모리를 프로세스의 커널 가상 메모리로 할당 및 매핑 가능하다.

process.c의 load_segment()를 보면 이 과정이 좀 더 명확하다. 이 함수는 프로세스 가상 주소 공간에 코드 세그먼트를 매핑하는 과정이다.

먼저 palloc_get_page(PAL_USER)로 USER POOL 물리 메모리에 page 크기의 메모리를 할당하고, 이에 매핑된 프로세스의 커널 가상 주소를 리턴받는다.

그 후 install_page(void *upage, void *kpage, bool writable)에서 프로세스의 커널 주소 공간의 메모리를 유저 주소 공간으로 매핑시킨다. 이 때 kpage는 물리 메모리의 USER POOL에서 할당된 메모리여야 한다.