블로그 이미지
blueye

카테고리

내블로그 (52)
창작활동 (10)
저장활동 (16)
관심 (0)
Total
Today
Yesterday

'Pintos'에 해당되는 글 3건

  1. 2008.05.23 [Pintos] 괴물2?ㅋㅋ 4
  2. 2008.04.22 으으아~~
  3. 2008.03.09 [Pintos] 괴물을 만났다. 43

[Pintos] 괴물2?ㅋㅋ

창작활동 / 2008. 5. 23. 01:43
4. Project 3 : Virtual Memory

지금 여러분이 핀토스의 내부동작을 가진 어떤 유사한 것을 가지고 있을지 모르겠습니다.  여러분의 OS는 적당한 동기화를 하는 여러 스레드의 실행을 정확하게 다룰 수 있고, 한 번에 여러 사용자 프로그램들을 로드할 수 있습니다. 그러나 실행 할수 있는 프로그램의 갯수와 크기는 머신의 주기억메모리 크기에 한정되어 있습니다. 이러한 한정에 대해, 여러분은 그러한 제한을 사라지게 할것 입니다. 마지막 것 위에 이 임무를 작성하게 될 것입니다. Project2에서의 테스트 프로그램은 Project 3에도 또한 작동하게 될 것입니다.

여러분이 Project 3의 작업을 시작하기 전에 Project 2에서의 서브 미션에 의한 어떤 버그들을 고쳐야 하는것에 주의해야 할지 모릅니다.
왜냐하면 그 버그들은 project3에서의 몇가지 문제들의 원인이 되는 것들과 거의 유사할 것이기 때문입니다.
여러분은 이전에 할당해서 했던 것들과 같은 방법으로 핀토스 디스크들과 파일시스템들을 계속 다루게 될 것입니다.

4.1 Background

4.1.1 Source Files

여러분은 이 프로젝트를 vm 디렉토리 안에서 작업하게 될것입니다.vm디렉토리는 Makefile만 포함하고 있습니다.userprog에서 유일한 변화는 이 새로운 Makefile을 -DVM으로 새롭게 바꾸는 것입니다여러분이 작성한 모든 코드는 새로운 파일안에 있거나 더 먼저 번의 프로젝트들에 소게된 파일안에 있게 될 것입니다,

여러분은 아마도 초반에는 단지 적은 파일들만을 마주치게 될것입니다.물리 디스크로의 접근을 제공하고 조금은 두려운 IDE 인터페이스를 따로 추출합니다.여러분은 스왑 디스크 접근의 이 인터페이스를 사용하게 될것입니다.

4.1.2 Memory Terminology

신중한 정의들은 가상메모리에 대한논의가 혼란스럽게 되지 않게 하기 위해서 필요합니다.그래서 기억하고 저장하기 위해서 어떠한 용어를 표현하는 것에서 부터 시작합니다.이러한 조건의 몇 개인가는, 프로젝트 2로부터 유사하게 되게 해야할 지 모릅니다.4.1.2.1 Pages

페이지(때때로 가상페이지로 불리는)는, 길이로 4096바이트(페이지 크기)인 연속된 지역입니다.  페이지는 페이지를 일렬로 늘어놓아야 합니다.즉, 페이지 크기에 의해서 균일하게 나누어지는 가상주소로 시작해야 합니다. 이와 같이, 32비트의 가상 주소는 20-bit의 페이지 번호와 12bit의 페이지 offset으로 로 나누어질 수 있습니다.

31               12 11     0
+---------------+-------+
| Page Number | Offset |
+---------------+-------+

Virtual Address

각 프로세스는 독립된 사용자(가상)페이지들의 집합을 가지고 있으며, 그 페이지 들은 가상주소 PHYS_BASE(일반적으로 0xc0000000(3Gb)) 아래에 존재 합니다. 가상의 커널 페이지 집합은 다른 말로 전역입니다, 어떤 스레드나 프로세스가 실행중인지는 상관없이 남아있는 것입니다.
커널은 사용자와 커널페이지를 둘다 접근할수 있지만 사용자 프로세스는 오직 자신의 페이지만 접근할 수 있습니다.
자세한 내용은 3.1.3절의 Virtual Memory참조

핀토스는 가상메모리를 운용하기 위한 몇 개의 유용한 함수를 제공합니다.
섹션을 봐 주세요

4.1.2.2. Frame

31                12 11      0
+-----------------+-------+
| Frame Number | Offset |
+-----------------+-------+
Physical Address

프레임(때때로 물리 프레임 또는 페이지 프레임을 불림)은 물리적인 메모리에 연속적인 공간입니다.  페이지처럼 프레임은 페이지사이즈 이고 페이지처럼 정렬되어야 합니다
이와같이, 32-bit 물리주소는 20bit 프레임 번호와 12-bit 프레임 오프셋으로 나뉘어질수 있습니다.
80x86는, 물리 주소의 메모리직접접근방식으로 나뉘어지지 않습니다.
핀토스는, 커널 가상메모리의 맵핑을 통해 물리적인 메모리에 직접 접근할 수 있습니다.
커널 가상메모리의 첫번째 페이지는 물리적 메모리의 첫 번째 프레임으로 매핑되어 있으며, 두 번째 페이지엔 두번째 프레임, 등등
이와같이 프레임들은 커널가상메모리를 통해 접근될수 있습니다.
핀토스는 물리주소와 커널 가상주소사이에 변환을 해주는 함수를 제공합니다
자세한내용은 Section A.6(가상주소 75페이지 참조)

4.1.2.3 Page Tables

핀토스에서 페이지 테이블은 CPU가 사용하는 가상주소를 물리주소로 변환하는 것을 사용하는데 쓰이는 데이터 스트럭쳐 입니다. 그것은 또한 페이지에서 프레임으로 변환하는.
페이지테이블 포멧은 80x86 아키텍쳐에 의해 이야기 됩니다.
핀토스는 pagedir.c에 페이지테이블 관리관련 코드를 제공합니다.
아래와 같은 그림은 페이지와 프레임의 관계를 이야기합니다.

왼쪽에서 가상주소는 페이지번호와 오프셋으로 구성됩니다. 페이지테이블은 프레임넘버에 페이지넘버로 전환되고 오른쪽에서물리주소를 포함하는 오프셋은 수정 없이 합쳐집니다.

       +-----------+
.--------------->|Page Table|-----------.
       / +-----------+ |
0 | 12        11   0 0   V    12 11   0
+---------+----+ +---------+----+
| Page Nr | Ofs | |Frame Nr| Ofs |
+---------+----+ +---------+----+
  Virt Addr      |     Phys Addr ^
\_______________________________________/

4.1.2.4 Swap Slots

스왑슬롯은 연속적입니다, 스왑디시크 위의 디스크 공간의 페이지 사이즈 구역입니다.
슬롯의 배치를 이야기하고 있는 하드웨어 한계들은 페이지들에서 보다 느슨 합니다. 그리고 그렇게 할 아래쪽 장소가 없기때문에 스왑슬롯들은 페이지를 일렬로 늘어놓아야만 합니다.

4.1.3 Resource Management Overview

여러분은, 아래의 데이터 구조를 디자인해야할 필요가 있습니다.

 - supplemental page talbe : 페이지테이블에 추가하는 것에 의해서 페이지폴트를 다를수 있게 해야합니다. 섹션 4.1.4를 참조(추가적 페이지 테이블 관리/40페이지)

 - Frame table : 쫓아내는 정책의 효과적인 구현을 허락합니다. 섹션 4.1.5(프레임표 관리/40페이지)참조

 - Swap table : 스왑 슬롯의 트랙들의 사용, 섹션 4.1.6(스왑테이블 관리/41페이지참조)

 - Table of file mappings : 프로세스는 프로세스의 가상 메모리 공간에 파일들을 맵핑할지 모릅니다. 여러분은 어느페이지들에 파일이 맵핑되는지 추적하기 위해 테이블이 필요합니다.
여러분이, 반드시 4개의 완전히 다른 데이터 스트럭쳐를 구현할 필요가 있는것은 아닙니다.: 그것은 완 전히 또는 부분적으로 통합된 데이터 스트럭쳐안의 관련된 자원들을 합치는데에 유용할지 모릅니다.

각각의 데이터 스트럭처를 위해, 여러분은 각각의 요소가 어떤정보를 포함하는지 결정할 필요가있습니다.

여러분도 데이터 스트럭쳐의 범위에서 지역적(프로세스안에서) 또는 전역(전체시스템안에서 허용되는)을 결정할 필요가 있습니다, 또한 얼마나 많은 인스턴스들이 그 범위안에서 요구되는지.

여러분의 디자인을 심플하게 하기 위해서, 여러분은 페이지의 메모리공인 이외에 이 데이터 스트럭쳐들을 저장해야 할지 모릅니다.

즉, 여러분은 그것들 사이의 포인터들이 유효할 것인지 확신할 수 있습니다.
데이터 스트럭쳐들의 가능한 선택은 배열, 리스트, 비트맵, 그리고 해쉬테이블을 이야기 합니다.
배열은 종종 가장 간단한 접근이지만 드문드문 비어있는 배열은 메모리를 낭비합니다
리스트 또한 간단하지만 특정 위치를 찾아내기 위해 긴 리스트를 탐색하는것은 시간을 낭비합니다.
배열과 리스트는 크기가 변경될수 있으나 리스트는 중앙에서 보다 효과적으로 삽입/삭제를 지원합니다.
핀토스는 비트맵 데이터 스트럭쳐를 'lib/kernel/bitmap.c'와 'lib/kernel/bitmap.h'에 포합하고 있습니다,
비트맵은 디트들의 배열이며 각각은 true,또는 false가 될수 있습니다.
비트맵은 일반적으로 (한쌍의)자원들의 집합안에서 사용을 추적하는데 사용됩니다.
자원 n이 사용중이라면, 비트맵의 비트 n은 true입니다.
핀토스 비트맥들은 size로 고정되어있는데, 여러분은 리사이징을 지원하는 그것들의 구현을 확장할수 있었습니다.
핀토스도, 해쉬테이블의 자료구조를 포함합니다.(섹션 A.8(해쉬테이블) 81페이지참조)
핀토스 해쉬테이블은 테이블 사이즈의 광역에 걸쳐서 삽입 삭제를 효과적으로 지원합니다.
비록 더 복잡한 자료구조들이 성능이나 이득을 가져올지는 모르겠지만, 그것들은 또한 여러분의 구현도 불필요하게 어렵게 만들지 모릅니다.
이와같이, 우리는 여러분의 디자인의 부분으로서 조금 추천되는 자료구조의 구현을 추천하지 않습니다.

4.1.4 Managing the Supplemental Page Table

supplemental page tatable은 각각의 페이지에대해 새로운 데이터로 페이지 테이블을 보충합니다.

그것은 페이지 테이블의 포멧에 의해 한계가 제한되기 때문에 필요합니다.

그러한 데이터 스트럭쳐는 종종 "page table"이라고 풀립니다.

우리는 혼란을 줄이기 위해 "supplemental"이란 말을 추가하였습니다.

supplemental page table은 적어도 두가지 목적을 위해 사용됩니다.

가장 중요한 것으로 페이지폴트에서 커널은 어떤 데이터가 있는지 확인하기 위해서 supplemental page table에서 폴트된 가상페이지를 찾습니다.

두번째로 프로세스가 끝날때 커널은 어떤자원을 해제해야 할지를 결정하기 위해서 supplemental page tabledp의뢰합니다.

여러분은 여러분의 바램에 의해서 supplemental page table을 조직할지 모릅니다.

그 조직에 관한 적어도 두가지의 기본적인 접근이있습니다. segment에 관해 또는 page들에 관해서 임의로 다신은 페이지테이블의 멤버들을 추적하는 인덱스로서 페이지테이블 자체를 사용할지 모릅니다.

여러분은 그렇게 하기 위해서 'pagedir.c안에 구현된 핀토스 페이지 테이블을 수정해야 할것입니다.

우리는 이 접근을 대학생에게 추천합니다.

자세한내용은 섹션 A.7.4.2(Entry Format 80페이지)참조

supplemental page table의 가장 중요한 사용자는 페이지폴트 핸들러입니다

프로젝트2에서 페이지 폴트는 언제나 커널또는 유저프로그램의 버그를 가리키고 있었습니다.

프로젝트3에서 이것은 더이상 true가 아니었습니다. 현재, 페이지 폴트는 페이지가 파일또는 스왑으로부터 반입되지 않으면 안되는것을 나타낼때만 가리키고 있을지 모릅니다. 여러분은 이러한 경우들을 위해 더욱 세련된 페이지 폴트 핸들러를 구현해야만 할것입니다.

'threads/exception.c'안의 page_fault()를 수정함으로써 구현될지도 모르는 여러분의 페이지 폴트 핸들러는 개략적으로 아래사항을 하기위해 필요합니다.

1. 추가 페이지 테이블의 fault된 페이지를 위치 시킵니다. 만약 메모리 참조가 valid 하면, 페이지의 데이터가 위치한 suppliemental page table entry를 사용하고 그것을 파일 시스템, 스왑공간 또는 제로 페이지에 단순히 위치시킬 것입니다. 만약 여러분이 공유를 구현한다면, 페이지의 데이터는 페이지 테이블이 아닌 이미 페이지 프레임에 있을 것입니다. 만약 페이지가 연관사상 되어있지 않다면, 그것은 그곳에 없는 데이터이거나 커널 가상메모리 상의 잘못된 페이지 또는 읽기 전용으로 시도되어 접근된 것입니다. 그때에는 접근은 정당하지 않습니다. 어떠한 정당하지 못한 접근들은 그 리소스의 모든 것들을 그것들의 주위로 놓으며 종료 시킵니다.

2. 우선 페이지가 저장된 프레임을 찾아냅니다. 4.15 Section [Managing the Frame Table] 의 40페이지를 자세하게 찾아보십시오.만약 여러분이 sharing을 구현하면, 여러분이 필요한 data는 이미 프레임에 있을 것이고 그 경우 여러분은 반드시 가능한한 그 프레임에 반드시 위치 시켜야 할 것입니다.

3. 프레임에 데이터를 Fetch하고 파일시스템이나 스왑 등으로 부터 읽어 들입니다.만약 여러분이 sharing을 구현하면 여러분이 구현한 페이지는 이미 프레이에 있을 것이고, 그경우 이단계에서 필요로한 아무액션도 취하지 않습니다.

4. 물리 페이지에서 faulting virutal address의 페이지 테이블 엔트리를 표시합니다. 여러분은 'userprog/pagedir.c'의 함수들을 사용할 수 있습니다.

4.1.5 Managing the Frame Table

프레임 테이블은 유저 페이지를 가지고 있는 개개의 프레임마다 하나의 엔트리를 가지고 있습니다. 각각의 엔트리는 그 페이지에 해당하는 포인터를 가지고 있으며, 데이터가 있다면 그것을 점유하거나 작성자가 지정한 다른 데이터를 점유할 수 있습니다. 핀토스는 프레임 테이블을 이용해서 효과적으로 축출법(eviction policy)을 실행할 수 있으며 이는 그 모든 프레임이 자유롭지 않을 때 페이지를 선택함으로서 축출을 하게 됩니다.

유저 페이지를 위해서 쓰이는 프레임들은 반드시 "유저 풀"에서 가져와야 하며 palloc_get_page(PAL_USER)를 이용해서 호출합니다. 작성자는 반드시 PAL_USER를 사용하여 "커널 풀"로부터 프레임을 배정받는 일을 피해야합니다. 그렇지 않을 경우 몇몇 시험 사례에서 예기치 않은 오류를 일으킬 수 있습니다. ([Why PAL USER?] 항목을 보십시오) 만약 작성자가 테이블 실행의 일환으로서 'palloc.c'를 수정 하면 반드시 그 두 개의 풀의 차이를 숙지하시기 바랍니다.

프레임 테이블에서 제일 중요한 실행은 미사용 프레임을 획득하는 것입니다. 하나 이상의 프레임이 자유로울 경우 이 과정은 쉽게 처리됩니다. 하지만 모든 프레임이 묶여있을 경우 원래 프레임의 몇몇 페이지를 축출함으로서 프레임을 획득해야합니다.

만약 교체 슬롯(Swap Slot)조차 없이 프레임이 하나도 축출되지 않을 경우, 혹은 모든 교체 슬롯이 포화 상태인 경우 커널이 경색될 가능성이 있습니다. 실용 운영 체제의 경우 매우 폭넓은 범위에 걸쳐서 이러한 경직 상태를 피하거나 혹은 빈 프레임을 얻는 수단을 강구하고 있습니다. 하지만 이러한 방법은 지금 다루는 프로젝트의 범위 밖입니다.

축출 과정은 개략적으로 다음 과정을 통해서 이루어집니다.

1. 축출할 프레임을 고릅니다.

이 과정에서 작성자가 정한 교체 알고리즘이 사용됩니다. 페이지 테이블 내의 "조회된 Accessed" 혹은 '난잡한 dirty" 비트들은-밑에서 설명하겠지만- 이 과정을 처리하는데 있어 유용합니다.

2. 위에서 언급된 요소를 대조하여 프레임 내의 페이지들을 참조합니다. 작성자가 실행 공유(Implemented Sharing)를 하고 있지 않는한, 한 순간에는 오직 하나의 페이지만의 한 프레임에 대해서만 참조합니다.

3. 필요하다면, 그 페이지를 파일 시스템에 옮기거나 교체(Swap)합니다. 축출된 프레임은 이제 다른 페이지를 저장하기 위해서 사용될 수 있습니다.

4.1.5.1 Managing the Frame Table

80x86 하드웨어는 몇 가지 페이지 교체 알고리즘의 구현을 도와주는 것을 제공합니다. 페이지에서 어떤 것을 읽거나 쓰면, CPU는 페이지의 PTE를 1로 설정시키고, 쓰기를 할때에 CPU는 dirty bit를 1로 설정합니다. CPU는 결코 이런 것들을 0으로 리셋하지 않고 OS가 그러한 것들을 합니다.

여러분은 여기서 같은 프레임에서 두 개 또는 그 이상의 페이지간에 aliases을 알아 챌 필요가 있습니다. 그 액세스 된 것과 다른 aliases의 dirty bits는 업데이트 되지 않습니다.

핀토스에서 모든 user virtual memory는 그것의 kernel virtual memory로 alias 됩니다. 여러분은 반드시 어떠한 식으로든 이러한 alias 들을 관리해야만 합니다.

예를 들어서, 여러분의 코드는 accessed와 dirty bit가 체크될 수 있고 업데이트 될 수 있습니다. 대신에 커널은 user virtual address를 통해서 user data가 accessing 될 때에만 그 문제를 피할 수 있습니다.

다른 aliases는 다만 만약 여러분이 기타 credit을 공유하는 것을 구현 했을 때에만 일어납니다.

A.7.3 섹션참조

4.1.6 Managing thw Swap Table

스왑 테이블에서는 빈 스왑 슬롯을 추적합니다. 그것은 스왑디스크의 프레임에서 사용되지 않은 스왑을 골라냅니다. 그것은 반드시 어떤 페이지가 종료되어서 스왑공간으로 읽고 되돌아 오면 빈스왑 슬롯으로 풀어줄 수 있도록 허용해야 합니다.

여러분은 devices/disk.h에 있는 디스크 인터페이스 원형을 사용하여 스왑디스크로 hd1:1 인터페이스의 디스크를 사용할 것입니다. 'vm/build' 디렉토리로 부터 핀토스-mkdisk swap.dsk n 명령을 사용하여 'swap.dsk'라는 이름의 n MB 스왑 디스크를 만든다. 그후 'swap.dsk' 핀토스를 실행시키면 'swap.dsk'는 자동적으로 hd1:1로써 부착됩니다. 대안으로는 핀토스에서 임시적인 n MB 스왑 디스크를 사용하기위해 '--swap-disk=n'을 명령할 수 있습니다.

스왑 슬롯은 늦게 할당되는데 이것은 사실상 방출에 의해 요청될 때에만 수행됩니다. 실행가능한 데이터 페이지를 읽는 것과 그것을 스왑에 기록하는 것은 프로세스가 시작될때엔 늦지 않는다. 스왑 슬롯은 특정 페이지 저장을 위해 할당되지(reserved) 말아야 합니다.

스왑슬롯은 그것의 내용이 프레임으로 되읽혀질때 비워진다.

4.1.7 Managing Memory Mapped Files

파일시스템은 가장 자주 read와 write 시스템콜에 접근합니다. 두번째 인터페이스는 mmap 시스템 콜을 사용하는 파일에서 가상 페이지로의 'map' 이다. 프로그램은 파일 데이터를 직접적으로 지시하는 메모리를 사용할 수 있습니다.'foo' 파일이 0x10000 바이트 길이라고 가정해봅시다. 만약 'foo'가 메모리의

시작주소 0x5000에 맵핑 되어있다면 0x5000 ... 0x5fff 위치의 메모리 접근은 'foo'에 대응하는 바이트에 접근하게 될 것입니다. 여기에 mmap을 사용하여 콘솔에 파일을 출력하는 프로그램이 있습니다. 명령줄에 쓰인 파일을 열고 가상 주소 0x10000000 에 그것을 맵핑하고 맵핑된 데이터를 콘솔에 출력한뒤 파일을 언맵핑합니다.

#include <stdio.h>
#include <syscall.h>
int main (int argc UNUSED, char *argv[])
{
    void *data = (void *) 0x10000000; /* Address at which to map. */
    int fd = open (argv[1]); /* Open file. */
    mapid_t map = mmap (fd, data); /* Map file. */
    write (1, data, filesize (fd)); /* Write file to console. */
    munmap (map); /* Unmap file (optional). */
    return 0;
}

모든 에러 핸들링을 하는 이와 유사한 프로그램이 'examples'디렉토리 안에 'mcat.c'가 포함되어 있고 mmap의 두번째 예제로 'mcp.c'가 포함되어 있습니다.

여러분의 submission은 메모리에 맵핑된 파일 파일에 의해 메모리의 추적을 할 수 있어야 합니다. 이것은 맵핑된 지역의 페이지 폴트를 적절히 처리하고 맵핑된 파일은 프로세스의 다른 세그먼트들에 중복되지 않아야 함을 책임지기 위해 필요하다.

4.2 Suggested Order of Implementation

우리는 다음과 같은 초기 구현순서를 제안합니다.

프레임 테이블(4.1.5 [프레임 테이블의 맵핑] 부분, 페이지 40을 참고). 여러분의 프레임 테이블 할당자를 사용하기 위해 'process.c'를 수정해야 합니다. 아직 스왑핑은 구연하지 말라. 만약 여러분이 프레임 밖에서 실행합니다면 할당에 실패 하거나 커널패닉에 걸리게 됩니다. 이 단계 후에 여러분의 커널은 프로젝트 2의 모든 테스트를 통과해야만 합니다.

페이지 테이블과 페이지 폴트 핸들러의 보충(4.1.4 [페이지 테이블의 보충] 부분, 페이지 40을 참고). 실행할수 있도록 로딩과 스텍에 셋업할 때 보충 페이지 테이블에 필요한 정보를 기록하기 위해 'process.c'를 수정합니다.

코드와 데이터 세그먼트의 로딩은 페이지 폴트 핸들러에 구현합니다. 지금은 타당한 접속에 관해서만 고려해봅시다. 이 단계 후에 여러분의 커널은 프로젝트 2의 모든 기능적 테스트 경우를 통과해야하지만 확고한 테스트 몇개에 대해 생각해봅시다.

여기에서 여러분은 스택의 증가, 맵핑된 파일들의 구현과 병행적인 프로세스 종료에서의 페이지 교정을 할 수 있습니다.

다음 단계는 추방(eviction)의 구현이다(4.1.5 [프레임 테이블 관리] 부분, 페이지 40을 참고). 초기에 여러분은 임의적으로 추방할 페이지를 선택했습니다

현 시점에서 여러분은 커널과 유저페이지의 들쭉날쭉한 접근과 dirty비트를 어떻게 관리할 것인지 고민해야할 필요가 있습니다. 추방 프로세스 중에 프로세스B의 프레임인 페이지에서 프로세스 A가 폴트가 났다면 이것을 어떻게 다룰 것인가 또한 동기화와 관련이있습니다. 마지막으로 클락 알고리즘과 같은 추방정책을 구현합니다.

4.3 Requirements 요구사항

이 과제는 디자인에 제한이 없는 문제 이다. 우리는 어떻게 할 것인지에 대해 조금이라도 가능성이 있는것에 대해 말할 것입니다. 우리는 기능적인 면 보다는 여러분의 OS가 지원할 것을 요구하는데 초점을 둘 것입니다.. 여러분은 페이지 폴트를 어떻게 처리할 것인지, 어떻게 스왑 디스크를 구성할 것인지, 페이징을 어떻게 구현 할 것인지 등을 자유롭게 선택해야 합니다.

4.3.1 Design Document 디자인 문서

여러분의 프로젝트에 임하기 앞서 여러분은 프로젝트 3 디자인 문서 틀을 반드시 '핀토스/src/vm/DESIGNDOC'폴더 아래 복사해 두어야 합니다. 우리는 여러분이 프로젝트 작업을 시작하기 전에 디자인틀을 읽어둘 것을 추천합니다

가공 프로젝트 예제 디자인 문서인 부록 D [프로젝트 문서], 페이지 96을 읽기 바랍니다.

4.3.2 Paging 페이징

실행가능하도록 로드된 세그먼트를 위해 페이징을 구현합니다. 커널의 가로채기로 인한 페이지 폴트로 인해 이러한 페이지들은 대부분 늦게 로드됩니다.

추방(eviction)이 일어나면 페이지는 로드된 후에 (dirty bit로 인지하여) 스왑공간에 쓰여지도록 수정되야 합니다. 실행가능한 프로그램으로부터 항상 블럭을 읽을수 있도록 하기위해, 오직 읽기만한 페이지를 포함하여 수정되지 않은 페이지는 절대로 스왑공간에 쓰여져서는 안됀다.

LRU에 가까운 페이지 교체 알고리즘을 구현합니다. 여러분의 알고리즘은 적어도 'second chance' 또는 'clock' 알고리즘 만큼 수행할 수 있어야 합니다.

여러분의 디자인은 병행성을 보장해야 합니다. 만약 프로세스가 폴트가 없는 수행이 계속되거나 I/O수행이 없는 다른 페이지 폴트 동안에 페이지 폴트로 I/O를 요구 합니다면 수행이 완료 되어야 합니다. 이것은 동기화에 대한 노력을 요구합니다.

여러분은 'userprog/process.c' 안에있는 load_segment()의 루프문인 로더 프로그램의 핵심부를 수정한 필요가 있을 것입니다.. 루프문에서 page_read_bytes는 실행가능한 파일로부터 읽어들은 바이트수를 받고 page_zero_bytes는 뒤이어 읽은 바이트를 0으로 초기화한 바이트의 수를 받습니다. 이 두수의 합은 PGSIZE(4,096)을 항상 가진다. 페이지의 처리는 이런 변수들의 값을 요구하게 됩니다.

만약 page_read_bytes가 PGSIZE와 같다면 페이지는 디스크로의 그것의 처음 접속으로부터 페이지를 요구하게됩니다. 만약 page_zero_bytes가 PGSIZE와 같다면 0으로 채워져있기 때문에 페이지는 디스크로부터 읽어들일 필요가 없습니다.. 다르게 둘다 PGSIZE와 같지 않다면, 페이지의 처음부분은 디스크로부터 읽고 나머지는 0으로 채워야 합니다.

4.3.3 Stack Growth 스택의 성장

스택의 성장구현. 프로젝트 2에서 스택은 유져 가상 주소공간의 꼭대기에 단일페이지였고 프로그램들은 스택의 크기만큼 제한적이었다. 지금 과거보다 현재 크기만큼 스택이 성장합다면 필요에 따라서 페이지들을 추가로 할당해야합니다.

추가적인 페이지의 할당이 있을때에만 스택 접속에 표시되어야 합니다. 스택에 접근하려는 다른 접속 시도로부터 구별하는 방법을 고안해야 합니다.

유저 프로그램들이 스택포인터 아래에 썼다면 버그가 많다. 왜냐하면 전형적인 OS들은 스택에 데이터를 넣는 시그널을 보내서 어떤 상황이던간에 인터럽트 걸기 때문이다. 그러나 80x86 PUSH 명령은 그것을 스택포인터에 적용하기 전에 접근권한을 체크하도록 되어있기 때문에 아마도 스택포인터 아래로 4 바이트 페이지 폴트를 야기할 것입니다. 유사하게 PUSHA 명령은 한번에 32바이트를 push하기에 스택포인터 아래로 32바이트 폴트가 난다.

여러분은 유져 프로그램 스택 포인터의 현재 값을 얻을 필요가 있을것입니다.

유저 프로그램에 의해 생성된 시스템 콜 또는 페이지 폴트 범위 안에서 struct intr_frame의 맴버변수 esp로부터 syscall_handler() 또는 page_fault() 각각을 여러분은 정정할 수 있습니다. 스택에 접근하기 전의 유저 포인터를 검증할수 있다면(3.1.5 [유져 메모리 접근] 부분, 페이지 26 참고), 이것들은 처리할 필요가 있는 유일한 경우이다. 반면에 잘못된 메모리 접근을 감지한 페이지 폴트라면, 여러분은 커널에서 발생한 페이지 폴트의 다른 경우의 처리를 필요로 하게 될 것입니다. 프로세서는 유져에서 커널 모드로 전환할때 야기되는 예외상황에서 struct intr_frame 범위밖의 esp를 읽고 유져 스택 포인터가 아닌 엉뚱한 값을 산출해 낼때 스택포인터를 저장할 뿐이다. 여러분은 유져에서 커널 모드로 초기 변환시에 struct thread에 esp를 저장하는것 처럼 다른방법으로 정리할 필요가 있을 것입니다.

여러분은 대부분은 OS들 처럼 스택 사이즈에 절대적 제한을 부과해야합니다.

Unix system 기반의 ulimit 명령으로 유져가 조정가능한 제한선을 가진 OS도 있습니다. 대부분의 GNU/Linux system 에서 일반적으로 8MB 제한선을 가진다

먼저 스텍 페이지는 스택 페이지는 늦게 할당되어서는 안됄 필요가 있습니다.
여러분은 오류 발생을 기다릴 필요가 없이 커멘드 라인의 인수들을 로드하는 시간에 초기화와 할당을 할수있습니다.
모든 스택 페이지는 추방(eviction)의 후보가 될 수 있습니다. 추방된 스택 페이지는 스왑공간에 쓰여져야만 합니다.

4.3.4 Memory Mapped Files 파일에 맵핑된 메모리

이어오는 시스템 콜을 포함하여 파일에 맵핑된 메모리의 구현.

mapid_t mmap (int fd, void *addr) // [system call]

fd로 열린 파일은 프로세스의 가상 주소 공간에 맵핑됩니다. 전체파일은 addr로부터 연속적인 가상 페이지에 맵핑됩니다.

여러분의 VM 시스템은 mmap 영역에 늦게 로드되고 mmap된 파일 자체로 맵핑을 저장하는데 사용합니다. mmap에 의해 맵핑된 페이지의 추방은 그것을 맵핑했던 파일에 쓰는것입니다.

만 약 파일의 길이가 PGSIZE의 복수개가 아니라면 최종적으로 맵핑된 페이지'stick out'을 넘어 파일끝에 몇바이트이다. 디스크로부터 오류가 발생한 페이지 일때 이런 바이트들을 0으로 셋팅하고 디스크로 써진 페이지일 경우에는 이를 무시합니다.

만약 성공적이라면 프로세스에서 맵핑된 유일한 식별자로 'mapping ID'를 반환하는 기능이다. 유효한 맵핑 아이디가 아니거나 프로세스의 맵핑이 수정되지 않은것과 같이 실패한경우 이것은 반드시 '-1'을 반환하게 됩니다.

mmap 은 만약 0바이트의 길이를 가진 파일을 fd로 열었을 경우 실패하게 됩니다. addr 이 페이지 정렬되어 있지 않거나, 실행가능한 프로그램 로드 시간에 맵핑된 페이지 또는 스택을 포함하는 현존하는 맵핑된 페이지에 덮어씌워지는 페이지의 영역이 있다면 이것은 반드시 실패합니다. 그리고 addr이 0

이라면 반드시 실패하도록 되어있습니다. 왜냐하면 핀토스 코드는 가상 페이지 0은 맵핑되지 않도록 되어있기 때문이다. 마지막으로 파일 디스크립터 0 과 1은 콘솔의 입력과 출력을 표현하므로 맵핑되지 않는다.

void munmap (mapid_t mapping) // [system call]

아직 unmapped되지 않은 프로세스에 의해 이전 mmap의 호출로 맵핑 아이디를 반환하는 맵핑을 Unmap합니다.

모 든 맵핑은 암묵적으로 프로세스가 종료될때 exit 과정 또는 다른 방법으로 unmapped 됩니다. 맵핑이 암묵적으로 또는 명시적으로 unmapped될 때 모든 페이지는 프로세스가 파일에 다시 쓰는것으로 인해 unmapped됩니다. 그리고 페이지는 페이지는 다시 쓰여지지 않는다. 페이지들은 가상 페이지의 프로세스 리스트들로부터 제거됩니다.

파 일의 제거 또는 닫음은 그것의 mapping으로부터 unmapped하지 않는다. 생성되었을때 맵핑은 munmap이 호출될때까지 또는 Unix정책에 따른 프로세가 종료될때 까지 유효하다. [열린 파일의 제거] 부분, 페이지 34를 참고하면 더 많은 정보를 볼 수 있습니다..




출처 : http://openmaya.tistory.com/entry/Pint-OS-메뉴얼-Project-4-Vitual-Memory-해석

_______________________________________________________________________________________________________

아직 과제로는 안나왔는데
우연히 돌아다니다가 주운 정보 ㅠ

핀토스 설치에 대한 포스팅이 본의아니게 너무 과열되어서 ㅎㅎ
이어지는 P2 P3는 선뜻 올리지 못하고 그냥 흐지부지 넘어갔는데
(그냥 넘어간 듯 말하지만, 사실 아는게 별로 없다)
P4는 다시한번 조심스럽게 포스팅에 도전해보려 한다.
변역된 글을 살짝 읽어봤는데. 음 과연.
이번 과제는 설치만큼 간단한 과제는 아닌듯 싶다.
사실 성공할지 조차도 의심스럽다..ㅠ
번역해놔도 뭔말인지 이해가 안간다. 이 미친 괴물.
이래놓고 실패하면 뭔망신이겠냐만은 ㅋ
일단 저질러놓고 수습하면 된다.

맨날 지겹다 힘들다 지친다 떠들어놓고도
이러고 있는걸 보면
축하해. 드디어 미친게 분명하다 ㅋㅋ

어차피 하게 될 거라면
피하기 보다는 정면 승부.

일단 당분간은 플젝마감이 없으니.
간만에 편안한 주말.ㅋㅋㅋ
Posted by blueye
, |

으으아~~

카테고리 없음 / 2008. 4. 22. 05:52
미친 핀토스.

요거 재수강뜨면 진짜 미쳐버릴지도.

한 번 듣는거도 쓰러지겠는데.

F 아니라 Z마이너스 할아버지가 뜨더라도

절대 재수강 안한다. 주저없이 버릴거다.

이런걸 아무 도움없이 pdf파일 한개로 어떻게 해결하라고 하는건지.

우리 허본좌님이야 관악산 골짜기에 계실테고,

조교님은 당최 어디 나가서 자고 계시기에 연락이 안되는지.

(밖에서 자면 입돌아간다. 썅.)


내피부는누가책임질건데;;;;;ㅁ너ㅏㅇㅎ럊ㅁ볃롭쟈매ㅕ돓ㅁ내여로망렁ㅎㅁ랴ㅕㄶㄻ

피부도 피부지만, 성격도 같이 썩어간다.

이번건 별로 포스팅하기도 싫다. 질렸어. 얼룩말색히.
Posted by blueye
, |

태어나서 처음으로 Pintos라는 것에 대해 들어보았다.
사실 들어본것도 아니다. A4용지 한쪽 귀퉁이에 쓰여진 "Pintos 프로젝트를 수행하라"는 짤막한 한마디.
이너넷을 대충 뒤져보니, Stanford 대학에서 개발한 학습용 OS인 것 같았다.

나중에 프로젝트에 대한 추가 설명이 있겠지만,
주말이고 할 일도 없고 해서 그냥 설치만 미리 해보기로 했다.
근데 이렇게 어려울 줄이야.. 주말이 그냥 지나갔다;;

우분투 7.10 커널 2.6.22.14 기준에서 작성.
정확한 순서는 아니다. 내가 작업하면서 시행착오를 겪은 순서대로 썼다.
아마 거의 대부분의 오류는 여기 다 있을듯.
내용이 길기 때문에, 필요한 부분만 찾아서 보는게 좋겠지요.





1. bochs 설치

Pintos를 구동하려면 이게 필요하단다. (Box와 같은 발음으로 읽는다. 박스.)
이너넷을 통해 구할 수 있는 공개 프로그램(
http://bochs.sourceforge.net/)이며
"오픈소스 ia32 에뮬레이션 프로젝트"라는 것을 보니, 뭔가 가상머신의 일종으로 짐작된다.


(1) 설치과정


(2) 첫번째 오류 - error: C compiler cannot create executables


(3) 두번째 오류 - X windows libraries were not found






2. Pintos 설치

http://www.stanford.edu/class/cs140/projects/pintos/pintos.tar.gz
문제의 그놈이 숙주하고 있는 곳이다.
역시 공개 프로그램. 전 세계로 바이러스마냥 퍼져나갔겠지.
cs140이라는 수업에서 교육자료로 이용하고 있는듯. 그것도 OS수업일까.


(1) 설치과정


(2) 첫 번째 오류 - __stack_chk_fail


(3) 두 번째 오류 - System BIOS must end at 0xfffff

_____________________


최종보스를 물리친 결과이다. 알람메시지가 출력된 모습.

사용자 삽입 이미지

여기까지가 설치 끝.
이제부터가 시작이구나;;;
지겨워지겨워.
리눅스를 쓰면 쓸수록 드는 생각은
"윈도우는 위대하다~?"
이런 시행착오를 겪으면서 점점 강해지는 것이 아닐까.
강한 최종보스를 물리쳤으니, 경험치 급상승? ㅋㅋㅋㅋ



......................................................................................................................................................

간단하게 정리될 줄 알았던 글이 시행착오를 겪으면서 꽤 큰 포스팅이 되어버렸다.

직접 겪어보지 않은 사람은 뭔 소린가 하겠지만

나와 같은 문제를 겪은 사람이 이 글을 보고 있을 것이고, 도움이 되리라 믿는다..

(우리 학교 컴과 학생일지도.ㅋ)

도움을 주려는 목적도 있었지만, 그것보단 내가 까먹을까봐 정리한건데....ㅋ

그래도 혹시 도움되셨다면,

댓글과 함께 애드센스 광고 한 번 꾹~^^;;






Posted by blueye
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함