물리 메모리 내의 각 프레임의 정보를 갖고 있는 frame table을 구현하도록 하자. Frame table은 frame entry의 리스트로 구성되는데, 각 엔트리는 물리 메모리

프레임 테이블로 인해 eviction 정책, 즉 SWAP OUT/IN을 위한 프레임 교체 정책을 수행할 수 있게 된다.

struct frame 수정

커널 가상 주소 kva와 page 구조체를 가리키는 주소 포인터로 이루어져 있다.

frame을 리스트화 시키기 위해 list_elem 변수를 추가한다.

struct frame {
	void *kva;  // 프레임 구조체에 대응하는 물리 메모리는 프로세스의 커널 가상 주소에 매핑된다. 그 매핑된 커널 가상 주소를 의미한다.
	struct page *page;  // 프레임과 매핑되는 프로세스 유저 가상 주소의 페이지
	struct list_elem frame_elem;  // 추가!
};

그리고 vm.h에 frame들의 리스트를 선언해준다.

struct list frame_table;

vm_get_frame(void)

<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;
}