일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 분할 정복(Divide and Conquer)
- 백준 17608번
- DFS(Depth First Search)
- 그리디 알고리즘(Greedy Algorithm)
- 백준 10000번
- DFS
- BFS(Breadth First Search)
- 백준 2504번
- 백준 18352번
- 이분 탐색(Binary Search)
- 백준 1707번
- 백준 9012번
- 스택(Stack)
- BFS
- 큐(Queue)
- 백준 21606번
- 위상 정렬(Topology Sort)
- 백준 1948번
- 이분 그래프(Bipartite Graph)
- 알고리즘 개념
- 그래프(Graph)
- 플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)
- 백준 2261번
- 트리(Tree)
- 위상 정렬(Topological Sort)
- 다익스트라 알고리즘(Dijkstra Algorithm)
- 동적 프로그래밍(Dynamic Programming)
- 백준 2493번
- DFS & BFS
- 백준 2812번
- Today
- Total
Always Be Wise
Project_2 : User Programs - Introduction 본문
Pintos 두 번째 프로젝트는 사용자 프로그램과 관련한 것이다.
첫 번째 프로젝트에서 실행했던 모든 코드는 운영체제 커널의 일부였다. 따라서 시스템 권한이 필요한 영역까지 완전한 접근이 가능했다.
하지만 사용자 프로그램은 그렇지 않다.
Pintos에서는 기본적으로 한 프로세스 이상을 동시에 실행 가능하도록 한다. 그리고 각 프로세스에는 하나의 스레드가 있다.
사용자 프로그램은 컴퓨터 전체를 사용한다는 가정 아래 실행된다.
다시 말해, 여러 프로세스를 한 번에 로드하고 실행할 때, 메모리와 스케줄링을 포함한 여러 가지들을 신경 써야 한다.
이전 프로젝트에서 테스트 진행 시, 코드를 커널에 직접 컴파일하였다. 이제는 사용자 프로그램을 실행하여 운영체제를 테스트한다.
이는 훨씬 많은 자유도를 주겠지만, 사용자 프로그램 인터페이스가 특정한 사양을 충족할 수 있도록 해야 한다.
모든 코드는 #ifdef VM으로 둘러싸인 블록안에 위치해서는 안된다.
해당 블록은 세 번째 프로젝트에서 구현할 가상 메모리 하위 시스템을 활성화한 후에 포함된다.
프로젝트를 진행하면서 작업할 각 부분은 대략적으로 아래와 같다.
process.c, process.h
ELF 바이너리를 로드하고, 프로세스를 시작한다.
ELF는 오브젝트 파일, 공유 라이브러리, 실행 파일을 위해 사용되는 파일 형식이다.
syscall.c, syscall.h
사용자 프로그램이 일부 커널 기능에 접근하기를 원할 때마다 시스템 콜을 호출한다.
시스템 콜 핸드러에 대한 스켈레톤 코드를 확인할 수 있고,
현재는 메시지를 출력하고 사용자 프로세스를 종료하는 것이 전부이다.
시스템 콜에 필요한 코드를 여기에 추가해야 한다.
exception.c, exception.h
사용자 프로그램이 권한이 필요하거나 금지된 작업을 수행하면 커널에 예외 또는 오류로 트랩 된다.
이는 예외 처리를 해주어야 한다.
현재 모든 예외 처리는 메시지를 출력하고 사용자 프로세스를 종료하기만 한다.
이 파일의 page_fault( )를 수정해야 한다.
사용자 프로그램이 파일 시스템에서 로드되고 많은 시스템 콜들이 파일 시스템을 다루기 때문에 파일 시스템 코드 인터페이스가 필요하다.
filesys 디렉터리를 살펴보면 단순하지만 완전한 파일 시스템을 제공하고 있다.
filesys.h와 file.h 인터페이스를 확인하여 파일 시스템 사용 방법과 제한 사항을 파악해야 한다.
두 번째 프로젝트에서는 파일 시스템 코드를 수정할 필요가 없다.
아래의 제한 사항들이 있다.
1. 한 번에 하나의 프로세스만 파일 시스템 코드를 실행하도록 동기화를 사용해야 한다.
2. 파일 크기는 생성 시 고정된다. 루트 디렉터리는 파일로 표시고 생성할 수 있는 파일 수도 제한된다.
3. 단일 파일의 데이터가 디스크 섹터 범위를 차지한다.
4. 하위 디렉토리는 없다.
5. 파일 이름은 14자로 제한된다.
6. 작업 도중 시스템 충돌로 인해 자동으로 복구되지 않는 방식으로 손상될 수 있다.
추가적으로 파일이 열려 있는 경우, 해당 블록은 할당 해제되지 않는다. 파일이 닫힐 때까지 액세스 할 수 있다.
Pintos에서 가상 머신에 파일을 넣으려면, 시스템 파티션을 가진 시뮬레이션 디스크를 생성해야 한다.
pintos-mkdisk 프로그램이 해당 기능을 제공한다.
userpfog/build 디렉터리에서 pintos-mkdisk filesys.dsk 10를 실행하면, filesys.dsk라는 10MB 크기의 디스크가 생성된다.
그리고 --fs-disk 명령어를 통해 디스크를 특정해줘야 한다.
디스크를 특정한 이후에는 파일을 시스템으로 복사해야 하는데, -p 파일 주소:새로운 파일명 명령어를 사용한다.
-- -q 명령어는 핀토스 종료 명령어이며, -f 명령어는 파일 시스템 실행을 위한 포맷이다.
아래는 상기 과정에 대한 예시이다.
우선 첫 번째 줄은 10MB 크기의 디스크를 만드는 과정이다.
다음 줄은 파일 시스템을 포맷하고, 프로젝트의 두 번째 테스트 사례인 args-single 프로그램을 디스크에 복사한 후
'one arg'라는 인자를 전달하여 프로그램을 실행하는 명령어이다.
pintos-mkdisk filesys.dsk 10
pintos --fs-disk filesys.dsk -p tests/userprog/args-single:args-single -- -q -f run 'args-single onearg'
pintos --fs-disk=10 -p tests/userprog/args-single:args-single -- -q -f run 'args-single onearg'
Pintos의 가상 메모리는 사용자 가상 메모리와 커널 가상 메모리 두 가지 영역으로 구분된다.
사용자 가상 메모리 범위는 가상 주소 0부터 KERN_BASE까지이며, 기본값은 0x800400000입니다.
커널 가상 메모리는 가상 주소 공간의 나머지를 차지한다.
사용자 가상 메모리는 프로세스 별로 할당되며,
한 프로세스에서 다른 프로세스로 전환할 때 프로세서의 페이지 디렉토리 레지스터를 변경하여 사용자 가상 메모리 주소를 전환한다.
커널 가상 메모리는 전역적이며, 실행 중인 사용자 프로세스나 커널 스레드와 상관없이 항상 동일한 방식으로 매핑된다.
커널 가상 메모리는 KERN_BASE부터 시작하여 물리적 메모리에 일대일로 매핑된다.
즉, 가상 주소 KERN_BASE는 물리적 주소 0에 액세스하고,
가상 주소 KERN_BASE + 0x1234는 물리적 주소 0x1234에 액세스하는 방식으로 시스템의 물리적 메모리 크기까지 액세스한다.
사용자 프로그램은 자신의 가상 메모리에만 액세스 할 수 있다.
만약, 커널 가상 메모리에 액세스하려고 하면 userprog/exception.c의 page_falut( )가 실행되어 프로세스가 종료된다.
커널 스레드는 커널 가상 메모리와 실행 중인 프로세스의 사용자 가상 메모리 모두 액세스 가능하다.
그러나 커널에서도 매핑되지 않은 사용자 가상 주소의 메모리에 액세스하려고 하면 page fault가 발생한다.
이 프로젝트에서는 사용자 스택의 크기가 고정되어 있지만, 세 번째 프로젝트에서는 사용자 스택을 확장할 수 있다.
사용자 가상 주소는 주소 공간의 바닥에서 대략 128MB인 0x400000에서 시작한다.
우분투에서 제공하는 전형저긴 값이며 특별한 의미는 없다.
시스템 콜의 일부로서 커널은 사용자 프로그램에 의해 제공되는 포인터를 통해 메모리에 접근해야 한다.
사용자가 가상 메모리에 매핑되지 않았거나 커널 가상 주소 공간(KERN_BASE 위의 공간)에 대한 포인터, NULL 포인터를 전달할 수 있다.
이러한 유효하지 않은 포인터들를 전달한 프로세스의 경우 page fault를 야기한다.
userprog/exception.c에 있는 코드를 수정하여 프로세스를 종료시킨 후 자원을 해제하는 등의 처리가 이루어져야 한다.
'카이스트 정글 - 프로젝트 > Pintos' 카테고리의 다른 글
Project_2 : User Programs - System Calls(1) (0) | 2022.01.04 |
---|---|
Project_2 : User Programs - Argument Passing (0) | 2021.12.30 |
Project_1 : Threads - Weekly I Learned (0) | 2021.12.30 |
Project_1 : Threads - Priority Scheduling(4) (0) | 2021.12.29 |
Project_1 : Threads - Priority Scheduling(3) (0) | 2021.12.28 |