전공공부/운영체제 (Operating System)

[운영체제] Main Memory (3) - Page Protection, Page Table Structure

jooona 2021. 1. 4. 12:09
반응형

이번 글에서는 지난 글에서 공부한 페이징의 남은 부분들에 대해서 공부해보도록 하겠습니다.

 

1. 페이지 보호 (Page Protection)

페이지 테이블을 만들 때, 메모리 보호를 위해서 각 페이지들에 추가적인 비트들을 부여하여 사용할 수 있습니다. 

 

첫 번째로는 Read-write/Read-only를 나타내는 비트입니다. 당연히 Read-write 모드일 때만 데이터를 수정할 수 있으며 Read-only 모드에서는 읽을 수만 있습니다. 두 번째는 Valid-invalid bit입니다. 이 비트가 valid로 설정되어 있으면, 해당 페이지가 프로세스의 논리 주소 공간 안에 있는 합법적인 페이지라는 것을 나타냅니다. 운영체제는 이 비트를 통해서 해당 페이지에 접근을 허용할 것인지 말지를 결정합니다. 

 

예를 들면 14비트의 논리적 주소 공간을 갖는 시스템은 0~16383의 주소를 사용할 수 있습니다. 그리고 이 중에 프로그램이 0~10468까지의 주소만 사용할 수 있다고 가정하면, 2KB짜리 페이지를 0번부터 5번까지 6개 사용할 수 있습니다. 이렇게 되면 페이지 테이블에 0~5번의 페이지에는 valid, 그리고 이 외의 페이지들에는 invalid로 설정해 줄 수 있습니다. 

 

또한 몇몇 시스템에서는 페이지 테이블 길이 레지스터(PTLR, Page Table Length Register)를 사용해서 페이지 테이블의 크기를 저장해 둡니다. 말 그대로 페이지 테이블의 사이즈를 저장하는 레지스터로써, 프로세스가 제시한 주소가 유효한 범위 내에 있는 지를 확인하는 용도로 사용됩니다.

 

2. 공유 페이지 (shared Pages)

페이징의 큰 장점 중 하나가 바로 코드를 쉽게 공유할 수 있다는 것입니다. 프로세스들은 코드 페이지들이 만약 재진입 가능 코드(Reentrant code, or Pure code)라면 해당 코드 페이지들을 공유할 수 있습니다. 재진입 가능 코드란, 수행되늰 동안 절대 변하지 않는 코드로써, 다시 말하자면 프로그램 내의 어떤 명령어도 프로그램 내의 다른 명령어를 위한 변수들을 수정시키지 않는다는 뜻으로, 이는 프로그램들이 언제든 변수가 수정되지 않았다는 확신을 가지고 코드 내에 진입할 수 있도록 만들어 줍니다. 

 

이렇게 재진입 가능 코드의 경우에는 코드를 물리 메모리에 올려놓으면 여러 프로세스들이 이 코드를 공유하여 사용할 수 있습니다. 마치 라이브러리와 비슷한 느낌이라고 생각하시면 좋을 것 같습니다.

 

3. 페이지 테이블 구조 (Page Table Structure)

지금까지는 가장 단순한 형태의 페이지 테이블의 구조에 대해 공부하고 고려해왔습니다. 여기서는 유명한 페이지 테이블 구조 몇 가지를 알아보고자 합니다.

 

1. 계층적 페이징(Hierarchical Paging)

현재 사용되는 많은 컴퓨터들은 굉장히 큰 주소 공간을 가집니다. 주소 공간이 커진다는 말은 페이지 테이블도 함께 커질 수 밖에 없다는 것을 뜻합니다. 32비트 논리 주소 공간을 사용할 때, 페이지 사이즈가 4KB라면, 페이지 테이블은 100만 개의 항목을 담을 수 있어야 합니다. 이러한 문제점을 극복하기 위해 나온 방법이 바로 계층적 페이징입니다. 계층적 페이징을 쉽게 설명하자면, 페이지 테이블을 위한 페이지 테이블을 만든다고 생각하시면 될 것 같습니다. 

 

Hierarchical Paging

이러한 경우에 논리주소도 변환이 되어야 합니다. 그래서 페이지 번호가 들어가야 할 자리에 Outer Page Table에서 원하는 페이지를 찾기 위한 주소와, 두 번째 페이지 테이블에서 찾아야 할 주소를 모두 넣어줍니다. 참고로 Outer Page Table 그 자체의 주소는 CPU 내의 한 레지스터에 저장해둡니다.

 

이때 이 계층적 페이징이 위의 그림처럼 2단계일 필요는 없을 것입니다. 메모리의 용량에 따라서 더 많은 단계를 거칠 수 있는데, 너무 많은 계층을 거치게 되면 최종적인 페이지에 도착할 때 까지 참조해야 할 페이지 테이블이 너무 많아져서 시간이 오래 걸릴 수 있습니다. 

 

2. 해시 페이지 테이블(Hashed Page Table)

주소 공간이 32비트 보다 커지게 되면 해시 페이지 테이블을 많이 사용합니다. 논리적 주소에서 페이지 번호를 해시 함수를 거쳐 만든 해시 값으로 해시 테이블에 접근을 하여 프레임 번호를 찾는 것입니다. 해시 테이블에서 각각의 항목들은 연결 리스트를 가지고 있어서, 자신에게 해시되는 원소들을 쭉 연결시키게 됩니다. 

 

그래서 페이지 테이블을 찾고자하면 우선 페이지 번호를 해시 함수를 돌려서 해시 값을 얻어내고, 이 해시 값으로 해시 테이블에 접근을 하게 됩니다. 그럼 해당 해시 값에 연결 리스트로 구현된 여러 페이지 정보들이 존재하고, 그중에 자신의 페이지 번호와 맞는 정보를 찾아서 프레임 번호를 얻어낼 수 있습니다. 

 

아래의 그림을 보시면 조금 더 이해가 편하실 것 같습니다.

 

Hashed page table

 

3. 역 페이지 테이블(Inverted Page Table)

마지막으로 역 페이지 테이블에 대해서 공부해보겠습니다. 페이지 테이블은 모든 프로세스 마다 하나씩 존재하기 때문에, 너무 많은 프로세스가 존재한다면, 그리고 프로세스가 계속 늘어나게 되면, 굉장히 큰 공간의 공간이 페이지 테이블로 인해 사용되게 됩니다. 이를 막기 위해 물리 메모리와 같은 사이즈의 큰 하나의 페이지 테이블을 사용하여 모든 프로세스의 페이지 테이블 정보를 한 번에 구현하는 것입니다. 물리 메모리와 페이지 테이블의 크기가 같기 때문에 하나의 프레임 당 하나의 페이지 테이블 항목이 매핑됩니다.

 

그리고 모든 프로세스의 페이지 테이블이 하나에 모여있기 때문에 각각의 항목에 프로세스의 아이디를 추가로 표시해 주어야 합니다. 물론 이렇게 페이지 테이블이 너무 커지게 되면 원하는 페이지를 검색할 때 너무 느려지는 단점이 있습니다. 이 문제를 해결하기 위해 해싱 방법을 접목하여 사용할 수도 있습니다. 그리고 프로세스 아이디를 이용해 테이블을 만들기 때문에 공유 메모리를 사용하기는 어렵습니다. 

 

 

 

 

여기까지 메인 메모리에 대해서 공부해보았습니다. 이제 다음 글에서는 가상 메모리에 대한 공부로 넘어가보도록 하겠습니다. 읽어주셔서 감사합니다.

반응형