/////
Search
📄

Introduction

Project3: 가상 메모리

이제 여러분은 핀토스의 내부 작동 방식에 어느 정도 익숙해졌을 것입니다. 여러분의 OS는 적절한 동기화로 다중 스레드 실행을 제대로 처리할 수 있고, 여러 사용자 프로그램을 동시에 로드할 수 있습니다. 그러나 실행할 수 있는 프로그램의 수와 크기는 머신의 주 메모리 크기에 의해 제한됩니다. 이 과제에서는 무한 메모리의 환상을 구축하여 이러한 제한을 제거할 것입니다.
이 과제는 이전 과제를 기반으로 구축됩니다. 프로젝트 2의 테스트 프로그램들도 프로젝트 3에서 작동해야 합니다. 프로젝트 3 작업을 시작하기 전에 프로젝트 2 제출물의 버그를 수정하는 것이 중요한데, 이는 이러한 버그들이 프로젝트 3에서도 같은 문제를 일으킬 가능성이 높기 때문입니다.
프로젝트 3에서는 편의를 위해 단계별 지침을 제공합니다.

배경

소스 파일

이 프로젝트에서는 vm 디렉토리에서 작업하게 됩니다. Makefile-DVM 설정을 켜도록 업데이트되었습니다. 우리는 엄청난 양의 템플릿 코드를 제공합니다.
주어진 템플릿을 반드시 따라야 합니다. 즉, 주어진 템플릿을 기반으로 하지 않은 코드를 제출하면 0점을 받습니다. 또한 "DO NOT CHANGE"로 표시된 템플릿은 절대 변경해서는 안 됩니다. 여기서는 수정할 각 템플릿 파일에 대한 세부 정보를 제공합니다.
include/vm/vm.h, vm/vm.c 가상 메모리를 위한 일반적인 인터페이스를 제공합니다. 헤더 파일에서 가상 메모리 시스템이 지원해야 하는 다양한 vm_type의 정의와 설명을 볼 수 있습니다 -- VM_UNINIT, VM_ANON, VM_FILE, VM_PAGE_CACHE (지금은 VM_PAGE_CACHE를 무시하세요. 이는 프로젝트 4용입니다). 또한 여기서 보조 페이지 테이블을 구현할 것입니다.
include/vm/uninit.h, vm/uninit.c 초기화되지 않은 페이지(vm_type = VM_UNINIT)에 대한 연산을 제공합니다. 현재 설계에서는 모든 페이지가 처음에 초기화되지 않은 페이지로 설정된 다음, 익명 페이지나 파일 지원 페이지로 변환됩니다.
include/vm/anon.h, vm/anon.c 익명 페이지(vm_type = VM_ANON)에 대한 연산을 제공합니다.
include/vm/file.h, vm/file.c 파일 지원 페이지(vm_type = VM_FILE)에 대한 연산을 제공합니다.
include/vm/inspect.h, vm/inspect.c 채점을 위한 메모리 검사 연산을 포함합니다. 이 파일들을 변경하지 마세요.
이 프로젝트에서 작성할 대부분의 코드는 vm 디렉토리의 파일들과 이전 프로젝트에서 소개된 파일들에 있을 것입니다.
처음 접하는 몇 개의 파일들도 있을 것입니다:
include/devices/block.h, devices/block.c 블록 장치에 대한 섹터 기반 읽기 및 쓰기 액세스를 제공합니다. 이 인터페이스를 사용하여 스왑 파티션을 블록 장치로 액세스할 것입니다.

메모리 용어

메모리와 저장소에 대한 몇 가지 용어부터 시작하겠습니다. 이러한 용어 중 일부는 프로젝트 2에서 익숙할 것이지만, 대부분은 새로운 내용입니다.

페이지

페이지(때로는 가상 페이지라고 불림)는 크기가 4,096바이트(페이지 크기)인 가상 메모리의 연속 영역입니다. 페이지는 페이지 정렬되어야 하며, 즉 페이지 크기로 균등하게 나누어지는 가상 주소에서 시작해야 합니다. 따라서 64비트 가상 주소의 마지막 12비트는 페이지 오프셋입니다. 상위 비트들은 페이지 테이블의 인덱스를 나타내는 데 사용됩니다. 64비트 시스템에서는 4단계 페이지 테이블을 사용하여 가상 주소가 다음과 같이 보입니다:
63 48 47 39 38 30 29 21 20 12 11 0 +------+-------+-------+-------+-------+--------+ |Sign |Page- |Page- |Page- |Page- | Page | |Extend|Map |Dir. |Dir. |Table | Offset | | |L4 Off.|Pointer|Offset |Offset | | +------+-------+-------+-------+-------+--------+
Shell
복사
각 프로세스는 독립적인 사용자(가상) 페이지 세트를 가지며, 이는 가상 주소 KERN_BASE(0x8004000000) 아래의 페이지들입니다. 반면 커널(가상) 페이지 세트는 전역적이며, 어떤 스레드나 프로세스가 실행되든 같은 위치에 남아있습니다.

프레임

프레임(때로는 물리 프레임이나 페이지 프레임이라고 불림)은 물리 메모리의 연속 영역입니다. 페이지와 마찬가지로 프레임은 페이지 크기여야 하고 페이지 정렬되어야 합니다.

페이지 테이블

페이지 테이블은 CPU가 가상 주소를 물리 주소로, 즉 페이지를 프레임으로 변환하는 데 사용하는 데이터 구조입니다. 페이지 테이블 형식은 x86-64 아키텍처에 의해 결정됩니다.

스왑 슬롯

스왑 슬롯은 스왑 파티션의 페이지 크기 디스크 공간 영역입니다.

자원 관리 개요

다음 데이터 구조들을 설계/구현해야 합니다:
보조 페이지 테이블 페이지 테이블을 보완하여 페이지 폴트 처리를 가능하게 합니다.
프레임 테이블 물리 프레임의 축출 정책을 효율적으로 구현할 수 있게 합니다.
스왑 테이블 스왑 슬롯의 사용을 추적합니다.

보조 페이지 테이블 관리

보조 페이지 테이블은 각 페이지에 대한 추가 데이터로 페이지 테이블을 보완합니다. 이는 페이지 테이블 형식의 제한 때문에 필요합니다.
보조 페이지 테이블은 적어도 두 가지 목적으로 사용됩니다. 가장 중요하게는 페이지 폴트 시 커널이 보조 페이지 테이블에서 폴트된 가상 페이지를 찾아 어떤 데이터가 있어야 하는지 알아냅니다. 둘째, 프로세스가 종료될 때 커널이 보조 페이지 테이블을 참조하여 어떤 자원을 해제할지 결정합니다.

페이지 폴트 처리

보조 페이지 테이블의 가장 중요한 사용자는 페이지 폴트 핸들러입니다. 프로젝트 2에서는 페이지 폴트가 항상 커널이나 사용자 프로그램의 버그를 의미했습니다. 프로젝트 3에서는 더 이상 그렇지 않습니다. 이제 페이지 폴트는 단순히 페이지를 파일이나 스왑 슬롯에서 가져와야 함을 의미할 수 있습니다.

프레임 테이블 관리

프레임 테이블은 각 프레임에 대해 하나의 엔트리를 포함합니다. 프레임 테이블의 각 엔트리는 현재 그것을 차지하고 있는 페이지에 대한 포인터와 기타 선택한 데이터를 포함합니다.
사용자 페이지에 사용되는 프레임은 palloc_get_page(PAL_USER)를 호출하여 "사용자 풀"에서 얻어야 합니다.

액세스 및 더티 비트

x86-64 하드웨어는 페이지 교체 알고리즘 구현을 위해 각 페이지의 페이지 테이블 엔트리(PTE)에 한 쌍의 비트를 통해 지원을 제공합니다. 페이지에 대한 읽기나 쓰기 시 CPU는 페이지의 PTE에서 액세스 비트를 1로 설정하고, 쓰기 시에는 더티 비트를 1로 설정합니다.

스왑 테이블 관리

스왑 테이블은 사용 중이거나 여유 있는 스왑 슬롯을 추적합니다. 프레임에서 스왑 파티션으로 페이지를 축출할 때 사용하지 않는 스왑 슬롯을 선택할 수 있어야 합니다.
vm/build 디렉토리에서 pintos-mkdisk swap.dsk --swap-size=n 명령을 사용하여 n-MB 스왑 파티션을 포함하는 swap.dsk라는 디스크를 생성하세요.
스왑 슬롯은 지연 할당되어야 하며, 즉 축출에 실제로 필요할 때만 할당되어야 합니다.

메모리 매핑 파일 관리

파일 시스템은 가장 일반적으로 readwrite 시스템 콜로 액세스됩니다. 보조 인터페이스는 mmap 시스템 콜을 사용하여 파일을 가상 페이지에 "매핑"하는 것입니다. 그러면 프로그램이 파일 데이터에 메모리 명령을 직접 사용할 수 있습니다.
파일이 주소 0x5000에서 시작하여 메모리에 매핑되면, 0x5000...0x5fff 위치에 대한 모든 메모리 액세스가 해당하는 파일의 바이트에 액세스하게 됩니다.
여러분의 제출물은 메모리 매핑 파일이 사용하는 메모리를 추적할 수 있어야 합니다. 이는 매핑된 영역에서 페이지 폴트를 적절히 처리하고 매핑된 파일이 프로세스 내의 다른 세그먼트와 겹치지 않도록 하는 데 필요합니다.

실제로 수정할 주요 파일들

1.
vm/vm.c: 보조 페이지 테이블 관리
2.
userprog/exception.c: page_fault() - 지연 로딩 구현
3.
vm/anon.c, vm/file.c: 각 페이지 타입별 처리
4.
userprog/syscall.c: mmap(), munmap() 시스템 콜