728x90

1. [Git book] User Memory

시스템 콜을 구현하기 위해서는 가상 주소 공간에 데이터를 읽고 쓰는 방법을 제공해야한다.

인수를 가져올 때는 이러한 기능이 필요하지 않다. 그러나 시스템 콜의 인수로 제공된 포인터에서 데이터를 읽을 때는 해당 기능을 통해 구현되어야한다.

 

  • 유효하지 않은 포인터
  • 커널 메모리에 대한 포인터
  • 부분적으로 해당 영역 중 하나에 블록 제공

 

 


2. [Git book] System Calls

  • 수정 파일 : userprog/syscall.c
  • 시스템 콜 번호, 시스템 콜 인수를 적절히 사용해서 작업을 수행해야 한다.

 


System Call Details

  • 프로젝트 1 : 외부 인터럽트를 이미 구현했다.
    • Timers, I/O devices

 

  • 프로젝트 2에서는 프로그램 코드에서 발생하는 소프트웨어적인 예외를 처리한다.
    (eg. Page fault, division by zero)
  • Exception의 의미 : user program에서 시스템 콜 요청 가능

 

  • 시스템 콜 번호 및 추가 인수는 일반적인 방식으로 레지스터에 설정되어야 한다.
    • %rax : 시스템 콜 번호
    • 4번째 인수 : %r10 (%rcx 가 아님을 유의!)
    • 💡 %rax : 가장 중요한 레지스터로 시스템 콜의 실질적 번호를 가리키는 번호, 함수 결과값이 담기는 레지스터
  • 64bit 정수 레지스터 표

 

syscall_handler() 가 제어권을 가져오면 시스템 콜 번호는 %rax 에 있고 인수는 %rdi, %rsi, %rdx, %r10, %r8, %r9 의 순서로 존재한다.

 

  • 호출자의 레지스터는 struct intr_frame 에 접근할 수 있다.
    struct intf_frame 은 커널 스택에 존재한다.

 

  • 함수의 리턴 값은 intr_framerax 멤버를 수정해서 값을 반환한다.

 


Implement the following system calls.

  • include/lib/user/syscall.h 에 해당 프로토타입이 명시되어있다
  • (include/lib/user 의 다른 모든 헤더들은 user program에서만 사용할 수 있다.)
  • include/lib/syscall-nr.h : 각 시스템 콜에 대한 시스템 콜 번호가 정의되어 있다.

 

  • userprog/syscall.c
    → 프로젝트 3과 프로젝트 4에서 다른 시스템 콜도 정의하게 된다.

 

  • 여러 사용자 프로세스가 한 번에 수행할 수 있도록 시스템 호출을 동기화 해야한다.
  • ./filesys 에 제공된 파일 시스템 코드를 다수의 스레드에서 한 번에 호출하는 건 안전하지 않다.
    ⚠️ 지금은 ./filesys 코드를 수정하지 않는 게 좋다.

 

  • lib/user/syscall.c 에 각 시스템 호출에 대한 사용자 수준 함수를 제공한다.
    → 사용자 프로세스가 C 프로그램에서 각 시스템 호출을 호출하는 방법을 제공한다.

 

  • 💬 프로젝트2 이후 user program 으로 인한 OS 충돌, 패닉, ASSERTION이 발생하지 않아야한다.
    🧨 테스트에서는 다양한 방법으로 시스템 콜을 중단하려고 시도한다.

 

  • 시스템 콜에 유효하지 않은 인수가 전달되면 옵션으로
  • 에러 값 리턴(리턴 값 존재 시)
  • 정의되지 않은 값 리턴
  • 프로세스 종료
    가 넘겨진다.

 

 


3. [Git book] Process Termination Message

  • 프로세스 종료 메시지를 출력하라.

 

  • exit 를 호출하거나 유저 프로세스가 종료될 때 마다 프로세스 이름과 종료 코드를 출력하라.
printf ("%s: exit(%d)\n", ...);

 

  • 출력되는 프로세스의 이름은 fork 에 전달되는 전체 이름이어야 한다.
  • 유저 프로세스가 아니라 커널 스레드가 종료하거나 halt 시스템 콜이 호출된 때에는 해당 메시지를 출력하지 마라.

 

  • 이외에도 핀토스가 아직 인쇄하지 않은 다른 메시지를 인쇄하지 마라.

 

 


4. [Git book] Deny Write on Executables

  • 실행 파일에 쓰기를 거부하라.

 

  • 실행중인 파일에 쓰기를 거부하는 코드를 추가하라.
  • 만약 어느 프로세스가 디스크에서 수정되고 있는 코드를 실행하려고 한다면 예기치못한 결과를 불러 일으킬 수 있다.
    → 많은 OS에서 ‘실행중인 파일에 쓰기를 거부’를 수행한다.

 

  • 열려있는 파일에 대한 쓰기를 막기 위해 file_deny_write() 를 사용할 수 있다.
  • file_allow_write() 를 해당 파일 안에서 호출하면 다시 쓰기를 가능케할 수 있다.

 

 


5. 구현 관련 내용 정리

  • 시스템 콜 번호를 통해 시스템 콜을 호출한다.

 

  • Original : System Call Handler table ❌

 

  • Process related: halt, exit, exec, wait, fork
  • File related: create, remove, open, filesize, read, write, seek, tell, close

 

System call

  • 서비스를 위한 프로그래밍 인터페이스는 OS에서 제공된다.
  • user mode 프로그램이 커널 기능을 사용할 수 있게 해준다.
  • 시스템 콜은 커널 모드에서 돌아간 뒤, 유저 모드로 돌아간다.
  • 시스템 콜의 키 포인트는 하드웨어 인터럽트가 시스템 콜 호출을 위해 발생 될 때, 실행 모드의 우선 순위를 끌어올리는 것이다.

 

System call handler

  • 시스템 콜 번호를 이용해서 시스템 콜 핸들러에서 해당 시스템 콜을 호출한다.

 

System Call Interface

  • 시스템 콜 번호를 이용해서 해당 시스템 콜의 서비스 루틴을 호출 하도록 구현
  • rsp 주소와 시스템 콜 인자가 가리키는 주소(포인터)가 유효 영역(유저 영역)인지 확인한다.
    기존 핀토스의 경우 유저 영역을 벗어난 주소를 참조할 경우, 페이지 폴트가 발생한다.
  • 유저 스택에 존재하는 스택 프레임의 인자들을 커널에 복사하도록 구현한다.

 

 


6. 테스트 관련 유의 사항

  • Project 1의 코드가 Project 2의 테스트 코드에도 포함되므로, 만약 Project 1에서 제대로 안짰다면 Project 1의 코드도 수정해야할 수도 있다.🥲

 

  • include/threads/thread.h
    #define USERPROG 를 통해 메인코드에서 USERPROG 관련 에러 뜨는 걸 막을 수 있다.
    → 빌드할 때는 자동으로 #define USERPROG 으로 들어가므로, 테스트 시에는 주석 처리해야한다.

 

  • 시스템 콜 테스트 코드가 출력을 통해 비교하므로 시스템 콜 테스트 결과를 보려면 최소 write까지 구현이 되어야한다.
    → 이걸 몰라서 엄청 오래 삽질함..🤣

 

  • printf 가 있는 부분은 모두 지우고 테스트를 돌려야한다.
    → Argument Passing에서 구현한 hexdump 포함!

 

  • 전체 테스트
>> cd ./userprog
>> make check

 

  • 개별 테스트
pintos -v -k -T 60 -m 20   --fs-disk=10 -p tests/userprog/fork-read:fork-read -p ../../tests/userprog/sample.txt:sample.txt -- -q   -f run fork-read
pintos -v -k -T 60 -m 20   --fs-disk=10 -p tests/userprog/exec-missing:exec-missing -- -q   -f run exec-missing
pintos -v -k -T 60 -m 20   --fs-disk=10 -p tests/userprog/exec-read:exec-read -p ../../tests/userprog/sample.txt:sample.txt -p tests/userprog/child-read:child-read -- -q   -f run exec-read
pintos -v -k -T 60 -m 20   --fs-disk=10 -p tests/userprog/wait-killed:wait-killed -p tests/userprog/child-bad:child-bad -- -q   -f run wait-killed

 

 

⭐ Gitbook에 모든 내용이 다 있다! ⭐

⭐ Gitbook 꼼꼼히, 자주 읽고 내용 복기하기! ⭐

 

728x90