이 섹션에서, 우리는 메모리에 매핑된 페이지를 구현할 것이다. anonymous page와 달리, memory-mapped page, 즉 file-backed mapping을 구현한다.(memory-mapped = file-backed) 페이지 내 내용은 일부 기존 파일 데이터를 미러링한다. page fault가 발생하면 물리 프레임이 즉시 할당되고 내용은 파일에서 메모리로 복사된다. 메모리 매핑된 페이지가 매핑 해제되거나 교체되면 내용 변경사항이 파일에 반영된다.

참고: mmap()에 대한 Linux Manual

mmapmunmap 시스템 호출

mmap, munmap 메모리 매핑 파일에 대한 두 가지 시스템 콜을 구현한다. 우리의 가상 메모리 시스템은 반드시 페이지를 lazy하게 mmap 영역에 load해야만 하고 mmaped file 자체를 매핑에 대한 백업 저장소로 사용해야 한다. 우리는 이 두 시스템 콜을 구현하기 위해 반드시 do_mmapdo_munmap을 사용해야 한다.

void *mmap (void *addr, size_t length, int writable, int fd, off_t offset);

파일 디스크립터 fd로 오픈한 파일을 offset byte 위치에서부터 시작해 length 바이트 크기만큼 addr에 위치한 프로세스 가상 주소 공간에 매핑한다. 전체 파일은 addr에서 시작해 연속적으로 이어지는 가상 페이지에 매핑된다. 만약 파일의 길이가 PGSIZE의 배수가 아니면, 매핑된 최종 페이지의 일부 바이트가 파일 끝을 넘어 삐져나온다. page fault가 일어났을 때 이 바이트를 0으로 세팅해라. 그리고 이 페이지를 디스크에 다시 쓸 때(swap out) 버린다. 만약 매핑에 성공하면, 이 함수는 파일이 매핑된 곳의 가상 주소를 리턴한다. 실패하면, 파일을 매핑하는데 유효한 주소가 아닌 반드시 NULL을 리턴해야 한다.

[참고: mmap vs malloc](http://www.differencebetween.net/technology/hardware-technology/difference-between-mmap-and-malloc/#:~:text=When malloc is running%2C it gathers all available system facilities.&text='mmap' on the other hand,of several pages of memory.)

mmap을 호출하는 것은 실패할 수도 있는데, 만약 fd로 open한 파일이 0바이트 길이를 가지고 있을 경우이다. 만약 addr이 page-align되어있지 않거나 매핑된 페이지 범위가 기존에 존재하는 매핑된 페이지 집합을 어떤 경우에도 덮어씌우는 경우에는 반드시 fail로 처리해야 한다. 리눅스에서, 만약 addr이 NULL이라면, 커널은 적절한 주소를 찾는데 이 주소는 매핑을 생성하기에 적절한 곳이다. 간단히 우리는 주어진 addr에 대해 그냥 mmap을 시도할 수 있다. 그에 따라, 만약 addr이 0이면, 이는 반드시 fail이다. 왜냐면 몇몇 pintos 코드는 가상 페이지 0을 매핑되지 않은 곳으로 간주하기 때문이다. 우리의 mmap 함수는 length가 0인 케이스에도 fail이어야 한다. 마지막으로, 콘솔 입력 및 출력을 나타내는 file descriptor는 매핑할 수 없다.

메모리 매핑 페이지도 anon page와 마찬가지로 lazy하게 할당되어야 한다. vm_alloc_page_with_initializer 또는 vm_alloc_page를 사용해 페이지 객체를 만들 수 있다.

void munmap (void *addr);

addr 범위의 정해진 주소에 대한 메모리 매핑을 해제한다. 이 addr은 반드시 아직 매핑되지 않은 동일한 프로세스에 의한 mmap 호출로부터 반환된 가상주소여야만 한다.

모든 매핑은 exit을 통해서나 혹은 다른 방법을 통해 내재적으로 프로세스가 exit할 때 unmapped된다. 명시적으로든 내재적으로든 매핑이 unmapped될 때, 해당 프로세스에 의해 기록된 모든 페이지는 파일에 다시 기록된다. 기록되지 않은 페이지는 기록되지 않아야 한다. 그 다음, 페이지는 프로세스의 가상 페이지 목록에서 제거된다.