[PintOS] Project 2 - User Programs 1

Quro·2024년 5월 10일
1

OS

목록 보기
6/6
post-thumbnail

과제 목표

  1. Argument Passing (인자 전달)
  2. User Memory Access (유저 메모리 접근)
  3. System Calls (시스템 콜)
  4. Process Termination Message (프로세스 종료 메세지)
  5. Deny Write on Executables (실행 파일에 쓰기 거부)
  6. Extend File Descriptor (파일 식별자 확장하기 | Extra)

Intro

지난번까지의 과제에서 실행한 모든 코드는 커널의 일부로서 시스템에 중요한 부분에 접근 할 수 있는 특권을 가지고 실행되었다. 하지만 유저 프로그램을 실행하기 시작하면 더 이상 그런 특권은 갖지 못한다. 지금부터의 과제는 이런 상황을 다뤄야 한다.

pintOS에서의 프로세스는 하나의 스레드만을 가질 수 있다.(멀티스레드 프로세스 지원 X)
이러한 상황에서 우리는 한번에 하나 이상의 프로그램이 실행될 수 있도록 할 것이다. 이는 우리가 한번에 여러 프로세스들을 로드하고 실행할 때 메모리, 스케쥴링, 그 외 다른 상태들을 모두 관리해야 한다는 것을 의미한다.

Source Files

우리는 userprog 디렉토리에서 작업할 것이다.

process.c, process.h

  • ELF binaries를 불러와 프로세스를 시작할 것이다.

    ELF binaries : 리눅스에서 실행 가능(Executable)하고 링크 가능(Linkable)한 file의 Format을 ELF(Executable and Linkable Format)라고 한다. 즉, 실행 가능한 바이너리 또는 오브젝트 파일 등의 형식을 규정한 것 !

syscall.c, syscall.h

  • 여러 시스템 콜을 수행하는 코드로 이루어진 파일.

    유저 프로세스가 일부 커널 기능에 접근하려 할때마다 시스템 콜이 호출된다.
    현재 상태에서는 단지 메세지를 출력하고 유저 프로세스를 종료시키게 되어있다.

syscall-entry.S

  • 시스템 콜 핸들러를 부트스트랩하는 어셈블리 코드로 이루어져 있다.

    부트스트랩 프로그램 : 전원을 켜거나 재부팅을 할 때 적재되는 프로그램

exception.c, exception.h

  • 유저 프로그램이 특별한 접근 권한을 필요로 하거나 금지된 연산을 수행할 때, exception 혹은 fault로 커널에서 오류를 띄우는데, 이런 오류를 다루는 코드의 파일이다.

    응용프로그램이 시스템 콜을 호출하면 하드웨어는 '트랩 핸들러'를 실행하여 하드웨어 특권 수준을 커널모드로 격상시킨다.
    커널모드에서 운영체제는 시스템 하드웨어를 자유롭게 접근할 수 있다.

gdt.c, gdt.h

  • x86-64는 segmented architecture이다. Global Descriptor Table(GDT)는 사용중인 세그먼트들을 알려주는 표이고, 이 파일은 GDT를 셋업한다.

    segmentation 기법 : 프로그램을 논리적 의미 단위인 세그먼트의 집합으로 구성하는 방식

tss.c, tss.h

  • Task-State Segment(TSS)는 x86 아키텍쳐의 context switching에 사용된다.
    하지만 x86-64에서 context switching은 지원이 중단된 기능이다.
    그래도 TSS는 여전히 ring switching 동안 스택 포인터를 찾아내기 위해 사용되고 있다.

    유저 프로세스가 인터럽트 핸들러에 진입할 때, 하드웨어는 TSS에게 커널의 스택 포인터를 찾아 달라고 요청한다.

Virtual Memory Layout

pintOS에서 가상 메모리는 두 영역으로 나눌 수 있다

  • User Virtual Memory
    - 유저 가상 메모리는 가상 주소 0부터 KERN_BASE까지의 범위를 갖는다. (KERN_BASE : 0x8004000000)
  • Kernel Virtual Memory
    - 유저 가상 메모리를 제외한 나머지 주소 공간을 차지한다.

하나의 프로세스는 하나의 유저 가상 메모리는 갖는다. 프로세스 context switching이 일어날 때, 커널은 유저 가상 주소 공간 또한 바꿔준다. 스레드 구조체는 하나의 프로세스의 페이지 테이블을 가리키는 포인터를 가지고 있다.

pintOS에서 커널 가상 메모리는 물리 메모리와 일대일 대응으로 매핑되는데, 이는 KERN_BASE에서 시작한다. 즉, 가상 주소 KERN_BASE가 물리 메모리 0에 접근하고, 가상주소 KERN_BASE + 0x1234 가 물리주소 0x1234에 접근한다.

유저 프로그램은 자신의 유저 가상 메모리에만 접근할 수 있다. 만약 커널 가상 메모리에 접근하려 시도하면 page fault를 일으키고 프로세스는 종료된다.

반면, 커널 스레드는 커널 가상 메모리와 동작 중인 프로세스의 사용자 가상 메모리에도 접근 가능하다. 하지만 커널 안에서도 매핑되지 않은 주소에 접근하면 page fault를 일으킨다.

profile
개발합니다

0개의 댓글

관련 채용 정보