[PintOS] Introduction to User Program - Virtual Memory

JunHyeok Kim·2024년 5월 21일
1

User Program을 시작하기 앞서,

We strongly recommend you to read synchronization and virtual address before you start.

라는 ☢️ 엄중한 경고 🚥 를 받아들이고 Virtual Memory 부터 정리하기로 하였다!

🎬 Introduction

By now you should have some familiarity with the inner workings of Pintos. Your OS can properly handle multiple threads of execution with proper synchronization, and can load multiple user programs at once. However, the number and size of programs that can run is limited by the machine's main memory size. In this assignment, you will remove that limitation by buiding an illusion of infinite memory.

Thread 단원에서 우리는 여러 쓰레드를 다루며 동기화 하는 법을 했었죠?
이번에는 여러개의 userprog을 로드함은 물론, Main Memory 사이즈의 제약을 벗어나 각각의 프로세스가 Main Memory 전체를 활용한다는 환상을 심어줄 것 입니다!

🛎️ Background

Source Files

You will work in the vm directory for this project. The Makefile is updated to turn on the setting -DVM. We provide an enormous amount of template code. You MUST follow the given template. That is, if you submit the code, that is not based on the given template, you get 0pts. Also, you should never change the template where it is marked "DO NOT CHANGE". Here, we provide some details about each template file that you will be modifying.

반드시 주어진 템플릿을 따르세요!! 주어진 템플릿에 기반하지 않고 코드를 제출한다면 0점을 받습니다! 또한, “DO NOT CHANGE”라고 적혀있는 부분의 코드는 절대 수정하지 마세요. 아래에 각 템플릿 파일에서 당신이 수정하게 될 부분에 대한 자세한 설명을 하겠습니다.

하지 말라면 하지 말자!

include/vm/vm.h, vm/vm.c

enum vm_type {
	/* page not initialized */
	VM_UNINIT = 0,
	/* page not related to the file, aka anonymous page */
	VM_ANON = 1,
	/* page that realated to the file */
	VM_FILE = 2,
	/* page that hold the page cache, for project 4 */
	VM_PAGE_CACHE = 3,

	/* Bit flags to store state */

	/* Auxillary bit flag marker for store information. You can add more
	 * markers, until the value is fit in the int. */
	VM_MARKER_0 = (1 << 3),
	VM_MARKER_1 = (1 << 4),

	/* DO NOT EXCEED THIS VALUE. */
	VM_MARKER_END = (1 << 31),
};

VM_UNINIT.c

Provides operations for uninitialized pages (vm_type = VM_UNINIT). Under the current design, all pages are initially set up as uninitialized pages, then it transforms to anonymous pages or file-backed pages.

초기화되지 않은 페이지에 대한 연산을 제공함. 모든 페이지는 VM_UNINIT 로 설정된 다음VM_ANON 혹은 file-backed pages 로 변환됨.

vm/anon.c

Provides operations for anonymous pages (vm_type = VM_ANON).

vm/file.c

Provides operations for file-backed pages (vm_type = VM_FILE).

vm/inspect.c

grading을 위한 메모리 기능 검사. 수정 금지! 🚫

Memory Terminology

Pages

  • 출처 : [1]
63          48 47            39 38            30 29            21 20         12 11         0
+-------------+----------------+----------------+----------------+-------------+------------+
| Sign Extend |    Page-Map    | Page-Directory | Page-directory |  Page-Table |    Page    |
|             | Level-4 Offset |    Pointer     |     Offset     |   Offset    |   Offset   |
+-------------+----------------+----------------+----------------+-------------+------------+
              |                |                |                |             |            |
              +------- 9 ------+------- 9 ------+------- 9 ------+----- 9 -----+---- 12 ----+
                                          Virtual Address

A page, sometimes called a virtual page, is a continuous region of virtual memory of size 4,096 bytes (the page size) in length. A page must be page-aligned, that is, start on a virtual address evenly divisible by the page size. Thus, the last 12 bits of a 64-bit virtual address is the page offset (or just offset). The upper bits are used to indicate the index in the page table, which will be introduced soon. With 64-bit system, we use 4-level page table, which makes a virtual address to look like this:

가상 페이지는 크기가 4,096 bytes 인 가상 메모리의 연속적인 영역입니다. 페이지는 페이지 정렬이 되어 있어야 합니다, 즉 페이지 크기로 균등하게 나눌 수 있는 가상 주소에서 시작해야 합니다. 따라서 64비트 가상 주소의 마지막 12비트가 페이지 오프셋(또는 그냥 오프셋)입니다. 위쪽 비트는 페이지 테이블의 인덱스를 나타내는 데 사용되며, 이는 곧 소개할 페이지 테이블에 표시됩니다. 64비트 시스템에서는 가상 주소를 다음과 같이 보이도록 하는 4단계 페이지 테이블을 사용합니다:

4KB는 4096 바이트입니다.
4096은 212
따라서, 4KB 페이지의 주소를 나타내려면 12비트가 필요합니다.

Each process has an independent set of user (virtual) pages, which are those pages below the virtual address KERN_BASE (0x8004000000). The set of kernel (virtual) pages, on the other hand, is global, and thus remain in the same position regardless of what thread or process is running. The kernel may access both user and kernel pages, but a user process may access only its own user pages. See Virtual Memory Layout, for more information.

각 프로세스는 KERN_BASE(0x8004000000) '아래' 에 독립적인 공간을 갖는 user (virtual) pages를 갖고 있습니다. 반면에, kernel (virtual) pages 는 전역적으로 쓰이며, 항상 같은 위치에 존재합니다.

커널은 유저 페이지와 커널 페이지 모두에 접근할 수 있지만, 유저 프로세스는 본인의 유저 페이지에만 접근할 수 있습니다

KERN_BASE (0x8004000000) 🤔?

이 가상 주소는 커널 공간이 시작되는 지점을 나타냅니다. 즉, 이 주소 이상의 영역은 커널 전용이고, 이 주소 미만의 영역은 사용자 전용입니다.

Pintos provides several useful functions for working with virtual addresses. See Section Virtual Addresses, for details.
https://casys-kaist.github.io/pintos-kaist/appendix/virtual_address.html

Frames

A frame, sometimes called a physical frame or a page frame, is a continuous region of physical memory. Like pages, frames must be page-size and page-aligned. Thus, a 64-bit physical address can be divided into a frame number and a frame offset (or just offset), like this:

Frame 은 물리적 프레임 또는 page frame 으로 불리기도 하며, 물리적 메모리의 연속적인 영역입니다. 페이지와 마찬가지로 프레임은 page-sizepage-aligned이 되어 있어야 합니다. 따라서 64비트 물리적 주소는 다음과 같이 프레임 번호와 프레임 오프셋(또는 그냥 오프셋)으로 나눌 수 있습니다:

                          12 11         0
    +-----------------------+-----------+
    |      Frame Number     |   Offset  |
    +-----------------------+-----------+
              Physical Address

페이지 정렬 (page-aligned)은 메모리 주소가 페이지 크기의 배수인 경우를 의미합니다. 즉, 페이지의 시작 주소가 페이지 크기의 배수여야 합니다.
4KB 페이지의 경우, 페이지 정렬 주소는 0x0000, 0x1000, 0x2000 등과 같이 4096(0x1000)의 배수입니다.

x86-64 doesn't provide any way to directly access memory at a physical address. Pintos works around this by mapping kernel virtual memory directly to physical memory - the first page of kernel virtual memory is mapped to the first frame of physical memory, the second page to the second frame, and so on. Thus, frames can be accessed through kernel virtual memory.

x86-64는 물리적 주소에서 메모리에 직접 액세스하는 방법을 제공하지 않습니다. 핀토스는 커널 가상 메모리를 물리적 메모리에 직접 매핑하여 이 문제를 해결합니다. 커널 가상 메모리의 첫 번째 페이지는 물리적 메모리의 첫 번째 프레임에 매핑되고, 두 번째 페이지는 두 번째 프레임에 매핑됩니다. 따라서 프레임은 커널 가상 메모리를 통해 액세스할 수 있습니다.

Page Tables

A page table is a data structure that the CPU uses to translate a virtual address to a physical address, that is, from a page to a frame. The page table format is dictated by the x86-64 architecture. Pintos provides page table management code in threads/mmu.c.

페이지 테이블은 CPU가 가상 주소를 물리 주소, 즉 page에서 frame으로 변환하는 데 사용하는 자료구조 입니다. 페이지 테이블 형식은 x86-64 아키텍처에 의해 결정됩니다. 핀토스는 페이지 테이블 관리 코드를 스레드/mmu.c로 제공합니다.

The diagram below illustrates the relationship between pages and frames. The virtual address, on the left, consists of a page number and an offset. The page table translates the page number into a frame number, which is combined with the unmodified offset to obtain the physical address, on the right.

아래 다이어그램은 pageframe의 관계를 보여줍니다. 왼쪽의 가상 주소는 페이지 번호와 오프셋으로 구성되어 있습니다. 페이지 테이블은 페이지 번호를 프레임 번호로 변환하고 오른쪽의 수정되지 않은 오프셋과 결합하여 물리적 주소를 얻습니다.

Swap Slots

A swap slot is a page-size region of disk space in the swap partition. Although hardware limitations dictating the placement of slots are more flexible than for frames, swap slots should be page-aligned because there is no downside in doing so.

스왑 슬롯은 스왑 파티션에서 디스크 공간의 페이지 크기 영역입니다. 슬롯의 배치를 지시하는 하드웨어 제한이 프레임보다 더 유연하지만, 스왑 슬롯은 page-aligned 를 하던 안하던 큰 차이가 없기에 (단점은 없기에) 정렬해줍니다.

🕹️ Resource Management Overview

You will need to design/implement the following data structures:

Supplemental page table

Enables page fault handling by supplementing the page table. See Managing the Supplemental Page Table below.

page table 을 보조하여 page fault handling 처리를 활성화합니다. 아래 보충 페이지 테이블 관리를 참조하십시오.

Frame table

Allows efficient implementation of eviction policy of physical frames. See Managing the Frame Table below.

물리적 프레임의 퇴거 정책을 효율적으로 구현할 수 있습니다. 아래의 프레임 테이블 관리를 참조하십시오.

Swap table

Tracks usage of swap slots. See Managing the Swap Table below.

스왑 슬롯이 사용되는 것을 추적합니다. 아래의 스왑 테이블 관리 부분을 참고하세요.

You do not necessarily need to implement three completely distinct data structures: it may be convenient to wholly or partially merge related resources into a unified data structure.

For each data structure, you need to determine what information each element should contain. You also need to decide on the data structure's scope, either local (per-process) or global (applying to the whole system), and how many instances are required within its scope.

To simplify your design, you may store these data structures in non-pageable memory (e.g., memory allocated by calloc or malloc). That means that you can be sure that pointers among them will remain valid.

각 자료구조를 완전히 별개로 구현할 필요는 없습니다. 서로 관련된 자원을 통합된 자료구조로 합치는 것이 편리할 수 있습니다. 각 자료구조에서 각 원소가 어떤 정보를 담는지 결정해야 하고, 자료구조를 지역(프로세스별) 또는 전역(전체 시스템에 적용)으로 적용할지 결정해야 합니다. 또한 필요한 인스턴스의 수를 결정해야 합니다.

설계를 단순화하기 위해, non-pageable 메모리에 이러한 자료구조를 저장할 수 있습니다. 이는 calloc이나 malloc으로 할당된 메모리를 의미합니다. 즉, 자료구조들 사이의 포인터가 항상 유효한 상태로 유지될 것을 보장할 수 있습니다.

Choices of implementation (Performance perspective)

Possible choices for implementation include arrays, lists, bitmaps, and hash tables. An array is often the simplest approach, but a sparsely populated array wastes memory. Lists are also simple, but traversing a long list to find a particular position wastes time. Both arrays and lists can be resized, but lists more efficiently support insertion and deletion in the middle.

구현을 위해 선택할 수 있는 방법으로는 배열, 목록, 비트맵, 해시 테이블 등이 있습니다. 배열이 가장 간단한 방법인 경우가 많지만, 밀도가 희박한 배열은 메모리를 낭비합니다. lists는 간단하지만 특정 위치를 찾기 위해 긴 목록을 이동하는 것은 시간을 낭비합니다. 배열과 lists은 모두 크기를 조정할 수 있지만 lists은 중간에 삽입과 삭제를 더 효율적으로 지원합니다.

Pintos includes a bitmap data structure in lib/kernel/bitmap.c and include/lib/kernel/bitmap.h. A bitmap is an array of bits, each of which can be true or false. Bitmaps are typically used to track usage in a set of (identical) resources: if resource n is in use, then bit n of the bitmap is true. Pintos bitmaps are fixed in size, although you could extend their implementation to support resizing.

pintOS 는 비트맵 데이터 구조를 포함합니다. 비트맵은 비트들의 배열로, 각각 참이거나 거짓일 수 있습니다. 비트맵들은 일반적으로 자원들의 집합에서 사용을 추적하는 데 사용되는데, 자원 n이 사용 중이면 비트맵의 비트 n은 참입니다. 핀토스 비트맵들은 크기가 고정되어 있지만, re-sizing을 지원하도록 구현을 확장할 수 있습니다.

Pintos also includes a hash table data structure (See Hash Table). Pintos hash tables efficiently support insertions and deletions over a wide range of table sizes.

핀토스는 해시 테이블 재료 구조도 포함하고 있습니다(해시 테이블 참조). 핀토스 해시 테이블은 다양한 테이블 크기에서 삽입과 삭제를 효율적으로 지원합니다.

🎁 Managing the Supplemental Page Table

The supplemental page table supplements the page table with additional data about each page. It is needed because of the limitations imposed by the page table's format. Such a data structure is often called a "page table" also; we add the word "supplemental" to reduce confusion.

보조 페이지 테이블 은 각 페이지에 대한 추가 데이터로 페이지 테이블을 보완합니다. 페이지 테이블의 형식에 따른 제한 때문에 필요합니다. 이러한 데이터 구조는 종종 "page table"이라고도 불리는데, 우리는 혼란을 줄이기 위해 "보조"이라는 단어를 추가합니다.
Supplemental Page Table은 프로세스마다 존재하는 자료구조입니다.

→ 각각의 페이지에 대해서 데이터가 존재하는 곳(frame, disk, swap 중 어디에 존재하는지), 이에 상응하는 커널 가상주소를 가리키는 포인터 정보, active인지 inactive 인지 등

The supplemental page table is used for at least two purposes. Most importantly, on a page fault, the kernel looks up the virtual page that faulted in the supplemental page table to find out what data should be there. Second, the kernel consults the supplemental page table when a process terminates, to decide what resources to free.

보조 페이지 테이블은 적어도 두 가지 목적을 위해 사용됩니다. 가장 중요한 것은page fault 에 대해 커널이 보조 페이지 테이블에서 fault 가 발생한 가상 페이지를 검색하여 어떤 데이터가 있어야 하는지 확인하는 것입니다. 둘째, 커널은 프로세스가 종료될 때 보조 페이지 테이블을 조사하여 어떤 리소스를 free 할 것인지 결정합니다.

🧹 Organization of Supplemental Page Table

You may organize the supplemental page table as you wish. There are at least two basic approaches to its organization: in terms of segments or in terms of pages. A segment here refers to a consecutive group of pages, i.e., memory region containing an executable or a memory-mapped file.

우리가 원하는 대로 보조 페이지 테이블을 구성할 수 있습니다. 보조 페이지 테이블 구성에 대한 최소한 두 가지 기본적인 접근법이 있습니다: 세그먼트 측면 또는 페이지 측면.
여기서 세그먼트는 연속적인 페이지 그룹, 즉 실행 파일 또는 메모리 매핑된 파일을 포함하는 메모리 영역을 나타냅니다.

Optionally, you may use the page table itself to track the members of the supplemental page table. You will have to modify the Pintos page table implementation in threads/mmu.c to do so. We recommend this approach for advanced students only.

"advanced students only"

❌ Handling page fault

The most important user of the supplemental page table is the page fault handler. In project 2, a page fault always indicated a bug in the kernel or a user program. In project 3, this is no longer true. Now, a page fault might only indicate that the page must be brought in from a file or swap slot. You will have to implement a more sophisticated page fault handler to handle these cases. The page fault handler, which is page_fault() in userprog/exception.c, calls your page fault handler, vm_try_handle_fault() in vm/vm.c.

보조 페이지 테이블에서 가장 중요한 것은 page fault handler 입니다. project 2에서 page fault 는 항상 커널이나 사용자 프로그램의 버그를 나타냅니다. 하지만 Project 3에서는 아닙니다. 현재 프로젝트에서는 page fault 가 해당 페이지를 파일이나 스왑 슬롯에서 가져와야 한다는 것만 나타낼 수 있습니다. 이러한 경우를 처리하려면 보다 정교한 page fault handler를 구현해야 합니다. userprog/exception.c에서 page_fault()인 page fault handler는 vm/vm.c에서 우리의 코드의 page fault handler인 vm_try_handle_fault()를 호출합니다.

페이지 폴트 핸들러는 대략 다음 작업을 수행해야 합니다:

  1. Supplemental Page Table에서 오류가 발생한 페이지를 찾습니다: 메모리 참조가 유효한 경우, Supplemental Page Table 항목을 사용하여 해당 페이지에 들어가는 데이터를 찾습니다. 데이터는 파일 시스템이나 스왑 슬롯에 있을 수 있으며, 단순히 all-zero page 일 수도 있습니다. Copy-on-Write를 구현하는 경우, 페이지의 데이터는 이미 페이지 프레임에 있을 수 있지만 페이지 테이블에는 없을 수도 있습니다. Supplemental Page Table에서 사용자 프로세스가 접근하려는 주소에 데이터가 있을 것으로 기대해서는 안 됩니다. 페이지가 커널 가상 메모리 내에 있거나, 읽기 전용 페이지에 쓰기를 시도하는 경우, 접근이 유효하지 않습니다. 잘못된 접근은 프로세스를 종료하여 모든 리소스를 해제합니다.

  2. 페이지를 저장할 프레임을 얻습니다: Copy-on-Write를 구현한 경우 필요한 데이터가 이미 프레임에 있을 수 있으며, 이 경우 해당 프레임을 찾아야 합니다.

  3. 데이터를 프레임으로 가져옵니다: 파일 시스템에서 읽어오거나 스왑, zeroing 등을 통해 데이터를 프레임으로 가져옵니다. Copy-on-Write를 구현한 경우 필요한 페이지가 이미 프레임에 있을 수 있으며, 이 경우 이 단계에서 추가 조치가 필요하지 않습니다.

  4. 페이지 테이블 항목을 업데이트합니다: 폴트가 발생한 가상 주소의 페이지 테이블 항목을 물리 페이지로 매핑합니다. 이를 위해 threads/mmu.c의 기능을 사용할 수 있습니다.


🖼️ Managing the Frame Table

The frame table contains one entry for each frame. Each entry in the frame table contains a pointer to the page, if any, that currently occupies it, and other data of your choice. The frame table allows Pintos to efficiently implement an eviction policy, by choosing a page to evict when no frames are free.

Frame Table에는 각 Frame에 대해 하나의 항목이 포함됩니다. Frame Table의 각 항목에는 현재 해당 Frame을 점유하고 있는 Page에 대한 포인터와 기타 데이터가 포함되어 있습니다. Frame Table을 통해 Pintos는 Frame이 부족할 때 퇴출할 Page를 선택하여 효율적인 퇴출 정책을 구현할 수 있습니다.

The frames used for user pages should be obtained from the "user pool," by calling palloc_get_page(PAL_USER). You must use PAL_USER to avoid allocating from the "kernel pool," which could cause some test cases to fail unexpectedly. If you modify palloc.c as part of your frame table implementation, be sure to retain the distinction between the two pools.

사용자 페이지에 사용되는 Frameuser pool에서 얻어야 하며, 이를 위해 palloc_get_page(PAL_USER)를 호출해야 합니다. PAL_USER를 사용하여 kernel pool에서 할당하는 것을 피해야 합니다. 그렇지 않으면 일부 테스트 케이스가 예기치 않게 실패할 수 있습니다. Frame Table 구현의 일환으로 palloc.c를 수정하는 경우, 두 풀 간의 구분을 반드시 유지해야 합니다.

The most important operation on the frame table is obtaining an unused frame. This is easy when a frame is free. When none is free, a frame must be made free by evicting some page from its frame.

Frame Table에서 가장 중요한 작업은 사용되지 않은 Frame을 얻는 것입니다. Frame이 비어 있을 때는 이 작업이 쉽습니다. 그러나 비어 있는 Frame이 없을 경우, 어떤 Page를 퇴출하여 Frame을 비워야 합니다.

If no frame can be evicted without allocating a swap slot, but swap is full, panic the kernel. Real OS apply a wide range of policies to recover from or prevent such situations, but these policies are beyond the scope of this project.

어떤 Frame도 스왑 슬롯을 할당하지 않고 퇴출할 수 없고, 스왑이 가득 찬 경우, 커널을 패닉 상태로 만드십시오. 실제 운영체제는 이러한 상황에서 복구하거나 방지하기 위해 다양한 정책을 적용하지만, 이러한 정책은 이 프로젝트의 범위를 벗어납니다.

퇴출 과정은 대략 다음 단계로 구성됩니다

1. 페이지 교체 알고리즘을 사용하여 퇴출할 Frame을 선택합니다. 아래에 설명된 대로, 페이지 테이블의 "accessed" 비트와 "dirty" 비트가 유용할 것입니다.
2. 해당 Frame을 참조하는 모든 페이지 테이블에서 참조를 제거합니다. 공유를 구현하지 않은 경우, 어느 시점에서든 하나의 Page만이 Frame을 참조해야 합니다.
3. 필요한 경우, 페이지를 파일 시스템이나 스왑에 기록합니다. 퇴출된 Frame은 다른 Page를 저장하는 데 사용될 수 있습니다.

🗑️ Accessed and Dirty Bits

x86-64 hardware provides some assistance for implementing page replacement algorithms, through a pair of bits in the page table entry (PTE) for each page. On any read or write to a page, the CPU sets the accessed bit to 1 in the page's PTE, and on any write, the CPU sets the dirty bit to 1. The CPU never resets these bits to 0, but the OS may do so.

x86-64 하드웨어는 각 페이지 테이블 항목(PTE)에 있는 두 개의 비트를 통해 페이지 교체 알고리즘을 구현하는 데 도움을 줍니다. 페이지에 대한 읽기 또는 쓰기가 발생할 때마다 CPU는 페이지의 PTE에서 accessed 비트를 1로 설정하고, 쓰기가 발생할 때마다 CPU는 dirty bit를 1로 설정합니다. CPU는 이러한 비트를 0으로 재설정하지 않지만, 운영체제가 이를 할 수 있습니다.

You need to be aware of aliases, that is, two (or more) pages that refer to the same frame. When an aliased frame is accessed, the accessed and dirty bits are updated in only one page table entry (the one for the page used for access). The accessed and dirty bits for the other aliases are not updated.

Aliases라고 하는 것에 주의해야 합니다. 이것은 두 개 이상의 페이지가 동일한 프레임을 참조하는 경우를 말합니다. Aliased 프레임에 액세스할 때, 액세스된 페이지에 대해서만 페이지 테이블 항목(PTE)에서 accesseddirty 비트가 업데이트됩니다. 다른 별칭에 대한 accesseddirty 비트는 업데이트되지 않습니다.

In Pintos, every user virtual page is aliased to its kernel virtual page. You must manage these aliases somehow. For example, your code could check and update the accessed and dirty bits for both addresses. Alternatively, the kernel could avoid the problem by only accessing user data through the user virtual address.

Pintos 에서는 모든 사용자 가상 페이지가 해당하는 커널 가상 페이지에 별칭으로 지정됩니다. 이 별칭을 어떻게 관리할지 결정해야 합니다. 예를 들어, 코드에서는 각 주소의 accessdirty 비트를 확인하고 업데이트할 수 있습니다. 또는 커널은 사용자 데이터에 대해서만 사용자 가상 주소를 통해 액세스하여 이 문제를 회피할 수도 있습니다.

Other aliases should only arise if you implement sharing or if there is a bug in your code.
See Section Page Table Accessed and Dirty Bits for details of the functions to work with accessed and dirty bits.

🚥 Managing the Swap Table

The swap table tracks in-use and free swap slots. It should allow picking an unused swap slot for evicting a page from its frame to the swap partition. It should allow freeing a swap slot when its page is read back or the process whose page was swapped is terminated.

스왑 테이블은 사용 중인 스왑 슬롯과 빈 스왑 슬롯을 추적합니다. 이는 페이지를 해당 프레임에서 스왑 파티션으로 퇴출하기 위해 사용되지 않은 스왑 슬롯을 선택할 수 있어야 함을 의미합니다. 페이지가 다시 읽혔거나 페이지를 스왑한 프로세스가 종료될 때 스왑 슬롯을 free할 수 있어야 합니다.

From the vm/build directory, use the command pintos-mkdisk swap.dsk --swap-size=n to create a disk named swap.dsk that contains a n-MB swap partition. Afterward, swap.dsk will automatically be attached as an extra disk when you run pintos. Alternatively, you can tell pintos to use a temporary n-MB swap disk for a single run with --swap-size=n.

vm/build 디렉토리에서 pintos-mkdisk swap.dsk --swap-size=n 명령을 사용하여 n-MB 스왑 파티션을 포함하는 swap.dsk라는 디스크를 생성합니다. 이후에 swap.dsk는 pintos를 실행할 때 자동으로 추가 디스크로 연결됩니다. 또는 --swap-size=n을 사용하여 단일 실행에 대한 임시 n-MB 스왑 디스크를 사용하도록 pintos에 지시할 수 있습니다.

Swap slots should be allocated lazily, that is, only when they are actually required by eviction. Reading data pages from the executable and writing them to swap immediately at process startup is not lazy. Swap slots should not be reserved to store particular pages.
Free a swap slot when its contents are read back into a frame.

스왑 슬롯은 lazy 하게 할당되어야 합니다. 이 말은, eviction에 실제로 필요할 때만 할당되어야 한다는 말입니다. 프로세스가 시작될 때 실행파일에서 데이터 페이지들을 읽고 스왑에 곧바로 쓰는 행위는 lazy 하지 못한 행위입니다. 특정 페이지를 저장하기 위해 스왑 슬롯이 예약되어서는 안 됩니다.
스왑 슬롯의 내용물이 프레임으로 읽혀 돌아오면 그 때 스왑 슬롯을 free 해주면 됩니다.

📂 Managing Memory Mapped Files

The file system is most commonly accessed with read and write system calls. A secondary interface is to "map" the file into virtual pages, using the mmap system call. The program can then use memory instructions directly on the file data. Suppose file foo is 0x1000 bytes (4 kB, or one page) long. If foo is mapped into memory starting at address 0x5000, then any memory accesses to locations 0x5000...0x5fff will access the corresponding bytes of foo.

파일 시스템은 주로 readwrite 시스템 호출을 사용하여 액세스됩니다. 보조 인터페이스로는 파일을 가상 페이지로 "매핑"하는 것 입니다. 이는 mmap 시스템 호출을 사용합니다. 프로그램은 그런 다음 파일 데이터에 대해 직접 메모리 명령을 사용할 수 있습니다. 예를 들어, 파일 foo가 0x1000 바이트(4KB 또는 한 페이지) 길이인 경우입니다. 파일 foo가 주소 0x5000에서 메모리에 매핑되어 있다고 가정해보세요. 그럼 주소 0x5000부터 0x5fff까지의 모든 메모리 액세스는 foo의 해당 바이트에 액세스하게 됩니다.

#include <stdio.h>
#include <syscall.h>

int main (int argc UNUSED, char *argv[])
{
  void *data = (void *) 0x10000000;                 /* Address at which to map. */
  int fd = open (argv[1]);                          /* Open file. */
  void *map = mmap (data, filesize (fd), 0, fd, 0); /* Map file. */
  write (1, data, filesize (fd));                   /* Write file to console. */
  munmap (map);                                     /* Unmap file (optional). */
  return 0;
}

🔖 Sitation 📝

  1. 권영진(2022). "Virtual Memory.pptx"
  2. 원문 출처: https://casys-kaist.github.io/pintos-kaist/appendix/virtual_address.html

0개의 댓글