물리 메모리 내의 각 프레임의 정보를 갖고 있는 frame table을 구현하도록 하자. Frame table은 frame entry의 리스트로 구성되는데, 각 엔트리는 물리 메모리
프레임 테이블로 인해 eviction 정책, 즉 SWAP OUT/IN을 위한 프레임 교체 정책을 수행할 수 있게 된다.
커널 가상 주소 kva와 page 구조체를 가리키는 주소 포인터로 이루어져 있다.
frame을 리스트화 시키기 위해 list_elem
변수를 추가한다.
struct frame {
void *kva; // 프레임 구조체에 대응하는 물리 메모리는 프로세스의 커널 가상 주소에 매핑된다. 그 매핑된 커널 가상 주소를 의미한다.
struct page *page; // 프레임과 매핑되는 프로세스 유저 가상 주소의 페이지
struct list_elem frame_elem; // 추가!
};
그리고 vm.h
에 frame들의 리스트를 선언해준다.
struct list frame_table;
<aside> 💡 물리 메모리의 유저 풀에서 페이지를 할당받아 커널 가상 주소 공간에 해당 페이지를 관리할 프레임 구조체를 만든다.
</aside>
palloc_get_page
으로 물리 메모리의 USER POOL에서 프레임을 프로세스의 커널 가상 주소 공간으로 할당받는다. 할당이 성공적으로 이루어졌다면 frame 구조체의 멤버들을 초기화하고 프레임의 주소를 리턴한다.
만약 USER POOL이 꽉 차서 페이지 할당에 실패하면 이미 할당되어 있는 프레임 중(frame_list 내에 있는 프레임)에서 적당한 프레임을 EVICT(REPLACE)한다. 일단 여기서는 EVICTION까지는 고려하지 않는 것으로 한다.
After you implement vm_get_frame
, you have to allocate all user space pages (PALLOC_USER) through this function. You don't need to handle swap out for now in case of page allocation failure. Just mark those case with PANIC ("todo")
for now.
static struct frame *
vm_get_frame (void) {
// struct frame *frame = NULL;
struct frame *frame = (struct frame*)malloc(sizeof(struct frame));
frame->kva = palloc_get_page(PAL_USER); /* USER POOL에서 커널 가상 주소 공간으로 1page 할당 */
/* if 프레임이 꽉 차서 할당받을 수 없다면 페이지 교체 실시
else 성공했다면 frame 구조체 커널 주소 멤버에 위에서 할당받은 메모리 커널 주소 넣기 */
if(frame->kva == NULL)
{
// frame = vm_evict_frame();
frame->page = NULL;
return frame;
}
// list_push_back (&frame_table, &frame->frame_elem);
frame->page = NULL;
ASSERT (frame != NULL);
ASSERT (frame->page == NULL);
return frame;
}