2 분 소요

이해 중…

일단 Git Book을 따라가며 진행 중이나
몇 가지 생각해야 할 부분이 존재한다

pml4 와 spt

일단 기본적인 va -> pa에 대한 ‘전환’은 pml4 내부에서
얻을 수 있는 것으로 확인하였음
(고로 ‘가상 주소’에서 ‘물리 주소’로 변환하는 것에 대해서
이미 pml4가 그 역할을 하고 있다는 의미이다)

그렇다면 spt는 ‘왜’ 필요하지?
기본적인 개요는
‘페이지’에 대한 ‘추가적인 정보’를 뜻한다

또한 git book 에서 설명하는 ‘spt’의 역할은 크게 2가지로

  1. Page Fault 발생 시, 커널이 spt에서 ‘오류가 발생한’ 가상 페이지를 조회하여
    그곳에 ‘어떠한 데이터’가 있어야 하는지를 알아야 함

  2. 커널이 프로세스를 종료할 때, SPT를 참고하여 ‘어떤 리소스’를 해제할지 결정한다

먼저 ‘Page’ 구조체는 이렇게 생겼다

struct page {
	const struct page_operations *operations;
	void *va;              /* Address in terms of user space */
	struct frame *frame;   /* Back reference for frame */

	/* Your implementation */

	/* Per-type data are binded into the union.
	 * Each function automatically detects the current union */
	union {
		struct uninit_page uninit;
		struct anon_page anon;
		struct file_page file;
#ifdef EFILESYS
		struct page_cache page_cache;
#endif
	};
};

기본적으로 ‘pte’와 유사하며,
우리는 이것으로 spt를 만들면 된다고 생각하는데…

이것은 ‘물리 페이지’의 ‘프레임’과 연결되어 서로를 가리키도록 한다

/* The representation of "frame" */
struct frame {
	void *kva;
	struct page *page;
};

현재 정리된 생각은
‘pml4’ 내부에서도 일부 bit 플래그를 이용하여
몇몇 비트를 활용할 수 있지만
‘추가적인 정보’를 pml4에 담을 수 없기에
‘spt’를 이용하여 추가적인 정보를 나타내는
‘page’ 구조체를 따로 저장하는 방식을 의미한다고 생각한다

고로

  • VA -> PA
    pml4로 인하여 주소 변환
  • Page -> Frame
    Spt 를 hash(선택 사항)으로 구현하여
    Page를 담아둔다
    (Page 에 hash_elem을 넣어두고, Spt에 hash를 넣는다)
    (이후 va를 통해 ‘page’ 구조체를 찾을 때,
    해당 thread 내부의 spt->hash를 통해 page를 찾는다)

그러므로 spt는
va -> spt를 통한 ‘page’ 체크 -> 물리 메모리 반환
이 사이의 역할을 해야 한다고 생각한다

현재 다소 헷갈리는 점
frame 은 ‘물리 메모리’에 위치하므로
어떻게 보자면 palloc으로 할당하는 것이 당연하다
(palloc_get_page(PAL_USER | PAL_ZERO))

다만, page는 원래 ‘가상 메모리’를 나타내는 것인데
palloc으로 할당하는 것이 조금 헷갈린다(개념상)

일단 정리하자면

처음에
page 를 동적할당하되
frame은 나중에 할당
(이는 page Fault를 발생시켜 lazy loading을 위함)

이후, 페이지 필요에 따라
page Fault 발생시, 늦은 initalize 가 호출되도록 한다
(이 때, frame이 할당되도록)

page는 uninit 상태에서
처음 lazy loading으로 호출될 때
VM_ANON인 ‘anonymous memory’로 다시 initalize 된다

lazy loading

현재 고민되는 것은
aux로 어떻게 데이터를 보내줄 수 있는지에 대한 것이다

이전 userprog 에서는
사실상 ‘바로바로’ page를 로딩하였기에
load_segment 시점에서 바로 file_read를 호출하였으나

이번엔 lazy_load 가 호출되는 시점에 해주어야 할 것 같다
개인적으로 고민되는 점은 aux 하나로 어떻게 그 인자들을 전달하냐는 점이다

댓글남기기