
process_exec() 부터 코드를 차근차근 따라가다 보면..
뭔가 이상한 걸 발견했을 것이다.
static bool
load_segment (struct file *file, off_t ofs, uint8_t *upage,
uint32_t read_bytes, uint32_t zero_bytes, bool writable) {
ASSERT ((read_bytes + zero_bytes) % PGSIZE == 0);
ASSERT (pg_ofs (upage) == 0);
ASSERT (ofs % PGSIZE == 0);
// read_bytes : 마지막 페이지 읽어야할 크기 / zero_bytes: 페이지 - read_bytes
// 페이지 단위로 나눠서 반복문 돌림.
// page_read_bytes : 페이지 크기 만큼 읽는다. * 마지막 페이지일 때? -> read_bytes
// page_zero_bytes : 0 * 마지막 페이지일 때? -> zero_bytes
while (read_bytes > 0 || zero_bytes > 0) {
/* Do calculate how to fill this page.
* We will read PAGE_READ_BYTES bytes from FILE
* and zero the final PAGE_ZERO_BYTES bytes. */
size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
size_t page_zero_bytes = PGSIZE - page_read_bytes;
struct file_info *aux = malloc(sizeof(struct file_info));
if (aux == NULL) return false;
aux->file = file;
aux->page_read = page_read_bytes;
aux->page_zero = page_zero_bytes;
aux->offset = ofs;
// ‼️ 이 곳 ‼️ //
if (!vm_alloc_page_with_initializer (VM_ANON, upage,
writable, lazy_load_segment, aux))
return false;
/* Advance. */
read_bytes -= page_read_bytes;
zero_bytes -= page_zero_bytes;
upage += PGSIZE;
ofs += page_read_bytes;
}
return true;
}
여기서 갑자기 VM_ANON 으로 타입을 설정해버린다.
당황스럽다.
가상메모리 구조를 열심히 공부했을 것이다.
VM_ANON/ VM_FILE에 대해서 실컷 공부했는데 ..
놀랍게도, 우리의 편의를 위해 우선 VM_FILE을 없는 셈 친다.
FILE은 extra에서 다룰 것이다.
VM_ANON이든, VM_FILE이든 모두 VM_ANON로 가정하고 구현해야할 것이다.
( 이걸 몰라서 한참을 헤맸다. 😢 )

그림 오른쪽 위에, uninit_page를 보면
vm_type 이라는 멤버가 있다.
이곳에, UNINIT page의 최종 목표인 VM_ANON/VM_FILE이 저장되어 있다.
하지만, 앞서 말했듯이 UNINIT은 모두 최종 목표가 VM_ANON으로 설정되어 있을 것이다.
(추후 과제를 수행하려면 수정해야함)

process_exec() 에서 프로세스가 실행이 되고,
load() 에서 프로세스에 해당하는 데이터를 모두 page 구조체로 만들어 둔다.
이전 글에서 설명
그다음 load_segment()
vm_alloc_page_with_initializer() 에서,
VM_ANON 과 lazy_load_segment를 인자로 넘겨준다.
여기서 uninit_new()를 호출하여, UNINIT 페이지 구조체를 완성한다 !
정리하면, UNINIT 페이지 구조체는
- 최종 목표가 (type) = ANON
- init = lazy_load_segment
- initializer = anon_initialzer
.swap_in함수가 실행된다.uninit_initialize가 실행된다.static bool
uninit_initialize (struct page *page, void *kva) {
struct uninit_page *uninit = &page->uninit;
/* Fetch first, page_initialize may overwrite the values */
vm_initializer *init = uninit->init;
void *aux = uninit->aux;
/* TODO: You may need to fix this function. */
/* 목표 initializer 실행 & 현재 init 함수 실행 ! */
return uninit->page_initializer (page, uninit->type, kva) &&
(init ? init (page, aux) : true);
}
page_initializer 와 init 함수가 실행된다.anon_initializer 와 lazy_load_segment가 실행되는 것 !anon_initializerlazy_load_segment최종적으로 VM_ANON 타입의,
frame과 연결된 = 데이터가 로드된
page가 완성이 됐다.
mmap에서 쓴다고 하네요 ^^;