. [PintOS, Project 2] User Programs Introduction
본문 바로가기
Pintos Project/Project 2

[PintOS, Project 2] User Programs Introduction

by 불냥이_ 2021. 2. 5.

 - 만약 추과 과제의 테스트케이스를 도전하고 싶으면 userprog/Make.vars를 수정하라.

 - TODO가 없는 코드는 수정할 필요가 없다.

 

We allow more than one process to run at a time. Each process has one thread (multithreaded processes are not supported).

 - 다중 프로세스로 구성되어 있다.

 

 User programs are written under the illusion that they have the entire machine. 

 - UP는 전체 장치들이 있다는 가정하에 작성한다.

 

From now on, we will test your operating system by running user programs. 

 - 이번 프로젝트에서는 제출한 PintOS를 유저 프로그램을 작동시켜봄으로서 평가해본다.

 

 You must make sure that the user program interface meets the specifications described here, but given that constraint you are free to restructure or rewrite kernel code however you wish.

 - 커널 코드를 자유롭게 작성해보라.

 

 All of your codes should never located in block that enclosed by #ifdef VM

 - ifdef VM 안에 코드를 작성하지 마라 (여기는 프로젝트 3때 다루는 구역이다)

 

 

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

 - 시작하기 전에 synch와 가상 메모리를 읽어라.

 

 

 

Using FIle System

You will need to interface to the file system code for this project, because user programs are loaded from the file system and many of the system calls you must implement deal with the file system.

 - 작성한 시스템 콜들은 파일 시스템을 다루며, 파일 시스템은 UP(유저 프로그래밍)을 로드하기 때문에 파일 시스템에 대한 인터페이스가 필요하다.

 

Proper use of the file system routines now will make life much easier for project 4

 - 파일 시스템 루틴을 적절히 이용하면 project 4가 수월해진다.

 - 다음 제한 사항을 가진다.

 

  • No internal synchronization. Concurrent accesses will interfere with one another. You should use synchronization to ensure that only one process at a time is executing file system code.

    ㆍ내부 sync가 없음 : 동시 접속은 서로에게 영향을 줄 것이다. 한번에 한 파일 시스템 코드만 수행할 수 있도록 sync를 사용하라. 

 

  • File size is fixed at creation time. The root directory is represented as a file, so the number of files that may be created is also limited.

    ㆍ파일 크기는 만들 때 크기로 고정된다. 루트 디렉토리가 파일 형태이기 때문에 만들어질 파일들 또한 제한된다. (무엇이?)

 

  • File data is allocated as a single extent, that is, data in a single file must occupy a contiguous range of sectors on disk. External fragmentation can therefore become a serious problem as a file system is used over time.

    ㆍ파일들은 연속적인 디스크 섹터를 가진다. (분산되서 저장되지 않음) 그렇기 때문에 외부 단편화가 문제가 될 수 있다.

 

  • No subdirectories

    ㆍ서브디렉토리 없음

 

  • File names are limited to 14 characters.

    ㆍ파일명은 14음절로 제한된다.

 

  • A system crash mid-operation may corrupt the disk in a way that cannot be repaired automatically. There is no file system repair tool anyway.

    ㆍ작업 중의 시스템 충돌은 디스크를 오염시킬 수 있으며, 자동으로 복구되어지지 않는다.

 

 

One important feature is included:

중요한 사항이 있음

Unix-like semantics for filesys_remove() are implemented. That is, if a file is open when it is removed, its blocks are not deallocated and it may still be accessed by any threads that have it open, until the last one closes it. See Removing an Open File for more information.

- filesys_remove() 를 위한 Unix-like semantics 가 내장되어있다. 만약 실행되고 있는 파일이 삭제된다면, 이 블록은 반환되지 않으며, 이 파일을 열려는 스레드가 모두 닫히기 전에는 접속할 수 있게 되버린다. Removing an open files를 참고하라.

 

 

How User Programs Work

 메모리가 여유로우며 작성한 시스템 콜만 사용하는 한, PintOS는 일반 C 프로그램을 수행할 것이다. 이번 프로젝트에서는 메모리 할당이 필요하지 않기 때문에 malloc()은 수행되지 않는다. 커널이 스레드를 바꿀 때, 프로세서의 floating-point를 저장하거나 복구하지 않기 때문에, pintos는 floating point operation이 있는 프로그램을 수행하지 않는다.

 

 pintos는 userprog/proces.c 안에 로더와 함께 ELF excutable을 로드할 수 있다. ELF는 Linux나 solaris 등 에서 사용되는 파일 포맷이다.

 

 사용 가능한 상태를 넘어서 

 

 

 

Virtual Memory Layout

 가상 메모리는 두 영역으로 나눠진다 : 유저 가상 메모리와 커너 가상 메모리이다. 유저 가상 메모리의 영역은 가상 주소 0부터 KERN_BASE 까지이며 (incldue/threads/vaddr.h 안에 정의되어있다. 기본값은 0x800400000) 커널 가상 메모리는 나머지를 차지하고 있다.

 

 유저 가상 메모리는 per-process이다. 커널이 프로세스를 바꿀 때, processor page directory base register를 바꿈으로서 유저 가상 주소 공간도 바꾼다. 스레드는 프로세스 page table 포인터를 가지고 있다.

 

 커널 가상 메모리는 전역으로 사용된다. 유저 프로세스나 커널 스레드에 구애받지 않고 맵핑 가능하다. 핀토스에서는, 가상메모리는 물리적 메모리에 1:1 대응하고있다. 가상 주소 KERN_BASE는 물리 주소 0에 대응하고, 가상 주소 KERN_BASE + 0x1234는 물리주소 0x1234애 대응한다.

 

 유저프로그램은 유저 가상 메모리에 접속가능한다. 커널 가상 메모리에 접속하려하면, userprog/exception.c 안의 page_fault()에 의해 page fault가 발생하고, 프로세스는 제거될 것이다. 배정받지 않은 유저 가상 메모리에 접속하려고 하면 page fault가 일어난다.

 

 

Typical Memory Layout

 이번 프로젝트에서 유저 스택은 고정된 크기를 가지고 있다.

 

 pintos에서 코드 영역은 유저 가상 주소 0x400000에서 시작하며 대략 128MB정도로, 주소 공간 아랫쪽에 위치한다.

 

 linker는 말 그대로 메모리의 유저 프로그램의 layout을 만든다. info ld로 접속가능한 linker manul에서 script를 읽으면 linker script에 대해서 알 수 있다.

 

 

Accessing User Memory

 시스템 콜의 한 부분으로서, 커널은 유저 프로그램이 제공한 포인터로 메모리에 접속해야한다. 이 때, 유저가 null pointer나 가상 메모리에 맵핑되어있지 않은 포인터를 넘겨주거나, 커널 가상 주소로의 포인터를 넘겨줄 수도 있다. 이러한 포인터들은 offending process를 제거하고, process의 자원을 폐기함으로서 포인터를 제거한다. 

 

 이 작업을 수행할 수 있는 두 가지 방법이 있다. 첫번째 방법은 유저가 넘긴 포인터를 검사한 뒤에 역참조 하는 것이다. 이 방법을 쓸 것이면 userprog/pagedir의 함수와 include/threads/vaddr.h를 봐라.

 

 두번째 방법은 유저가 넘긴 포인터가 KERN_BASE 이전을 가리키는지만 확인하는 것이다. 잘못된 유저 포인터였다면 page fault를 일으킬 것이고, 이는 page_fault()로 수정할 수 있다. 이 방법은 MMU방식과 같기 때문에 빨리 수행할 수 있기 때문에 Linux같은 실제 커널에서 사용된다. 

 

 자원이 새지(leak)않도록 하라. 예를 들어, 시스템 콜이 malloc()으로 메모리를 할당받았거나 어떤 lock을 가졌다고 해보자. 이 다음에 잘못된 유저 포인터를 사용한다면, 반드시 lock이나 메모리를 반환해야한다. 만약 역참조하기 전에 유저 포인터를 검사했다면 잘못될 일이 없을 거이다. 만약 잘못된 유저 포인터가 page fault를 일으킨다면 에러 코드나 반환값을 받을 길이 없기 때문에 더욱 다루는 게 어려워진다. 그러므로 두번째 방법을 쓰고 싶은 사람은 아래 코드를 사용해봐라.

/* Reads a byte at user virtual address UADDR.
 * UADDR must be below KERN_BASE.
 * Returns the byte value if successful, -1 if a segfault
 * occurred. */
static int
get_user (const uint8_t *uaddr) {
    int result;
    asm ("movl $1f, %0; movzbl %1, %0; 1:"
         : "=&a" (result) : "m" (*uaddr));
    return result;
}

/* Writes BYTE to user address UDST.
 * UDST must be below KERN_BASE.
 * Returns true if successful, false if a segfault occurred. */
static bool
put_user (uint8_t *udst, uint8_t byte) {
    int error_code;
    asm ("movl $1f, %0; movb %b2, %1; 1:"
    : "=&a" (error_code), "=m" (*udst) : "q" (byte));
    return error_code != -1;
}

 이 함수들은 KERN_BASE아래에 유저 주소가 있다고 가정한다. 또한, 커널에서 page_fault가 일어났을 때, rax to -1 에서 일어나도록 하고, 이전 값을 %rip에 복사하도록 page_fault()를 수정했다고 가정한다. 

 

 

'Pintos Project > Project 2' 카테고리의 다른 글

[PintOS, Project2] System Call  (0) 2021.02.17
[PintOS, Project2] 명령어 실행 기능 구현  (0) 2021.02.17

댓글