* 뇌피셜이 난무할 수 있습니다.
* 개인 공부 용도로 작성하였습니다.
참고자료
Project 2: User Programs
Introduction
- 핀토스를 통해 사용자 프로그램을 돌릴 수 있게 만드는 것이 이번 과제이다.
- 핀토스는 이미 사용자 프로그램을 로딩시키고 실행시킬 수 있다. 하지만 I/O 작업 등, 컴퓨터와의 상호 작용은 아직 가능하지 않다.
- 이번 과제에서는 이러한 상호 작용을, System call들을 통해 가능케 해야 한다.
- 프로젝트 1에서는 주로 thread 폴더에서 작업했던 것과는 달리, 이번 프로젝트에서는 주로 userprog 폴더에서 작업하게 된다.
- 코드에 TODO라는 주석이 없다고 해서 변경할 필요가 없다고 생각하면 안된다. 변경해야 될 수도 있다.
Background
- 핀토스 내에서 지금까지 내가 돌려보던 코드들은 모두 kernel의 일부분들이었다.(커널 내에서 동작하는 코드들이었다)
- 프로젝트 1의 테스트 케이스들은 모두 커널의 일부분으로 동작했고 시스템에서 privilege가 필요한 부분들에 대한 접근 권한을 가지고 있었다.
- 핀토스는 한 번에 둘 이상의 프로세스를 실행시킬 수 있다.(시분할을 통해서, 즉 동시성으로 실행시킬 수 있다는 뜻인가?)
- 각 프로세스는 하나의 쓰레드만 가지고 있다.(여러 개의 쓰레드를 가지고 있는 프로세스는 핀토스에서 지원해주지 않는다)
- 사용자 프로그램은 마치 자신이 모든 머신을 가지고 있다는 착각 속에서 실행되게 된다.
- 자신이 실행될 때는 모든 것들을 실행할 수 있기에 메모리 전체를 차지하고 있는 듯 하고,
- 실제로는 필요한 부분만 페이지 형태로 올라가 있지 않을까 싶다.
- CPU도 자신이 혼자 점유하는 듯이 느끼게 하며,
- I/O 파트도 마치 자기가 가지고 있는 듯한 착각에 빠지게 만든다.
- 실제로는 프로세스가 I/O 파트를 가지고 있는 것이 아니라, 시스템 콜을 통해 커널의 서비스를 받아서 I/O 작업을 할 수 있게 된다.
Source Files
process.c
- binary 형태의 ELF 파일을 로드하고 프로세스를 시작시킨다.
- ELF: Executable and Linkable Format
- 단순히 말해서 Linux/Unix에서의 실행 파일이다.(윈도우의 exe 파일이라고 생각하자)
- OS에서 프로세스로 실행되게 된다.
- 디스크 영역에 저장되어 있던 프로그램이, 메모리 영역에 올라가 컴퓨터의 자원을 사용해 서비스를 제공하게 된다.(프로그램이 프로세스로서 실행된다)
- ELF에서는 프로그램이 실행될 때, 메모리에 올라가야 할 각각의 부분들을 미리 정리하여 관리하고 있다가, 실행을 하게 되면 정리된 해당 부분들을 메모리에 올리게 된다.(그러면 CPU가 메모리에 접근하여 실행시킬 수 있다)
- 메모리에 올라온 프로그램 주소 공간의 text 섹션(코드 영역)의 인스트럭션을 한 line씩 실행하며 프로세스가 진행된다.
- 구조
- ELF Header : 파일의 메타 데이터를 가지고 있다.
- ELF 파일의 type, ELF header의 크기, 이 ELF 파일을 사용하기 위해 필요한 architecture 등이 담겨져 있다.
- .text section : 실제로 CPU에서 수행되는 이진 기계 코드가 저장된 영역
- .data section : 프로그램이 실행될 때, 이미 초기화되어 있는 ELF 파일의 Data가 저장되어 있는 영역
- 프로그램 헤더 테이블 : ELF 내의 세그먼트들에 대한 정보와, 이들을 어떻게 메모리에 로드애햐 하는지에 대한 정보를 담고 있다.
- 섹션 헤더 테이블 : 파일의 섹션들에 대해 알려준다.
- 링킹 : 각 섹션들을 공유 라이브러리 등에 각 세그먼트 내에 정렬해 주는 과정.
syscall.c
- 사용자 프로그램이 커널의 서비스를 받고 싶을 때 시스템 콜이 호출된다.
syscall-entry.S
- system call handler를 호출하는, 적은 양의 어셈블리 코드들로 이루어져 있다. 이 파일을 굳이 이해할 필요는 없다.(하지만 이해하면 컨텍스트 스위칭이 어떻게 이루어지는지 자세히 알 수 있을 것 같다)
exception.c
- 사용자 프로그램이 커널 서비스(시스템 콜)을 받아서 금지된, 혹은 특권이 필요한 작동을 하는 게 아니라, 자기 스스로 하려고 한다면 예외 처리가 발생된다.
- 오류 메세지를 띄우고 사용자 프로그램을 종료시킨다.
- 프로젝트 2에서 (아주 약간) 변경할 필요가 있다.
tss.c
- TSS(Task-State Segment)는 x86에서는 사용되었으나, x86-64에서는 더 이상 사용되지 않는다.
- 허나 링 스위칭을 위해서 여전히 사용되는 부분이 있다.
- 사용자 모드(Ring 3) -> 커널 모드(Ring 0)
- 커널 모드(Ring 0) -> 사용자 모드(Ring 3)
- 다시 말해서, 사용자 프로세스가 인터럽트 핸들러로 들어가고자 할 때, 하드웨어는 커널 스택 공간을 가르키는 커널 스택 포인터를 찾고자 TSS를 탐색한다.
Using the File System
-
사용자 프로그램이 파일 시스템으로 부터 로드되고, 많은 시스템 콜이 파일 시스템과 연관되어 있기에(파일에 데이터를 쓰는 write처럼) 이번 프로젝트에서는 file system 관련 인터페이스(함수)를 사용해야 한다.
-
현재 파일 시스템 인터페이스(함수)에는 별다른 동기화가 없다.(lock이나 sema 등) 따라서 동시에 접근하여 간섭하는 상황이 생길 수 있다.
- 따라서 한 번에 하나의 프로세스가 파일 시스템 함수를 실행하길 보장하려면 동기화를 해야 한다.(lock이나 sema 등등)
기타
- x86-64 아키텍처 : x86-64 혹은 x64는, x86 명령어 집합 아키텍처의 64비트 모임이다.
- 아키텍처, Architecture : CPU 디자인의 일부로서, 어셈블리어를 작성하기 위해 알아야 하는 것이다. 실행할 수 있는 명령어들의 집합이 어떠한지, 레지스터와 메모리의 조직은 어떠해야 하는지 등을 정의한다. 아키텍처는 명령어 체계를 정의한다는 측면에서 ISA(Instruction Set Architecture)라고도 부른다.
How User Programs Work
- 핀토스는, 메모리에 적합하고 우리가 구현한 시스템 콜만 호출하는, 보통의 C 프로그램을 실행시킬 수 있다.
- 이번 프로젝트에서의 시스템 콜은 메모리 할당을 허용하지 않기에 malloc은 구현할 수 없다.
Virtual Memory Layout
- 핀토스의 가상 메모리는 사용자 가상 메모리와 커널 가상 메모리 공간으로 나뉜다.
- 사용자 가상 메모리 공간은 0부터 KERN_BASE까지이다.
- 커널 가상 메모리 공간은 그 나머지를 차지하게 된다.
- 사용자 가상 메모리는 프로세스마다 존재한다.
- 커널이 한 프로세스에서 다른 프로세스로 스위칭시킬 때 사용자 가상 메모리 공간 또한, page directory base register를 바꾸면서 스위칭 된다.
- struct thread, 즉 TCB에 해당 쓰레드(프로세스)의 페이지 테이블을 가르키는 포인터(pml4, page map level 4)를 가지고 있다.
- 커널 가상 메모리는 전역이다. 사용자 프로세스가 running 중이든, 커널 쓰레드가 running 중이든 상관 없이 같은 방법으로 항상 맵핑된다.
- 핀토스에서 커널 가상 메모리는 물리적 메모리와 1대1로 맵핑되고, 이는 KERN_BASE로부터 시작된다.
- 즉, 가상 주소인 KERN_BASE(0x8004000000)는 물리적 주소 0에 접근한다.
- 만약 가상 주소가 KERN_BASE + 0x1234(0x8004001234)라면, 이는 물리적 주소 0x1234에 접근한다.
- 사용자 프로그램은 오직 자신의 사용자 가상 메모리 공간만 접근할 수 있다. 만약 직접 커널 가상 메모리 공간에 접근하려고 하면 page fault가 발생하여 해당 프로그램(프로세스)를 종료시키게 된다.
- 하지만 커널 쓰레드는 커널 가상 메모리 공간과 실행 중인 사용자 프로그램 가상 메모리 공간까지도 접근할 수 있다.
- 그러나 이러한 커널 모드에서도, 만약 접근하려는 메모리가 사용자 프로그램과 맵핑되어 있지 않다면 page fault가 발생한다.
Typical Memory Layout
- 핀토스의 code 세그먼트는 사용자 가상 주소 0x400000(약 128MB)에서 시작한다.
TSS
BSS
Protection Ring
make grade