중간 중간 뛰어 넘는 챕터가 존재하는데 어렵지 않다고 생각들거나 뛰어 넘어도 이해의 문제가 없기 때문에 뛰어 넘는다.
15.vm-mechanism
# 시작하며
프로그램은 자신의 전용 메모리를 소유하고 그 안에 자신의 코드와 데이터가 있다는 환상을 만들어 주자.
# 가정
지금까지 그러했듯 몇가지 가정을 둔다. 이러한 가정을 완화시키고 뒤에가서는 멀티레벨페이징 기법과 같은 것까지 접근 할 수 있다. 주소공간은 물리 메모리에 연속적으로 배치되어야 한다는 가정과 각 주소 공간의 크기는 같다는 가정을 한다. 조금 비현실적이다.
x = x + 3은 아래와같은 주소 접근이 일어나면서 실행된다. 시스템 소프트웨어때 공부했던 그대로다.
지금 실행되는 저 프로그램의 관점에서는 주소공간은 0KB ~ 16KB의 주소를 가지고 있다. 물론 실제 물리메모리에서는 다른 공간이겠지만 가상화를 통해 환상을 심어주었고, 아래와 같은 주소공간을 가지고 있다고 착각하게 된다.
실제 물리메모리에서의 배치는 아래와 같다. 프로세스를 실제 메모리의 다른 공간에 재배치(relocation)했다. 그렇다면 어떻게 32KB의 물리주소에서 시작되는 걸, 프로세스가 0KB라고 착각하게 할까? 또 데이터를 불러오려면 해당 주소공간에 접근해야하는데 그러한 과정을 어떻게 처리해주는 것일까라는 의문이 남는다.
# 동적(하드웨어 기반) 재배치(relocation)
1950년대 초창기 시분할 컴퓨터는 베이스-바운드기법(base - bound) 을 활용했다. 이 기술을 동적 재배치(dynamic relocation)이라고 한다. 각 CPU에는 두개의 추가적인 레지스터(하드웨어)가 필요하다. 하나는 베이스(base) 또 하나는 바운드(bound)라 부른다.
베이스와 바운드는 생각보다 간단하고, 우리가 재배치하기 위해서 어떻게 해야할까라고 생각해봤을때 떠오르는 첫번째 개념을 구현하기 위해 등장한다. 운영체제가 프로그램을 실행하면 프로세스로 올라오면서 물리메모리 어딘가에 재배치된다. 그림<18.2>에서 32KB가 그 시작점인데 이 시작주소의 정보를 베이스(base)레지스터에 저장시킨다. 프로세스는 메모리에 접근할때는 가상화 된 공간속임을 모른체 접근한다. 거기서는 0KB가 시작인 셈이다. 실제 물리주소로 접근이 필요할때는 베이스만큼의 값을 더해주는 것이다. 만약 가상메모리에서 1KB의 위치에 접근했다면 실제 물리메모리에서는 1KB + 베이스(base)를 더해 여기선 33KB의 위치로 이동하여 데이터를 얻어 오는 것이다.
그렇다면 바운드(bound)의 역할은 무엇일까? 보호(protection)을 위해 존재한다. 즉 다른 프로세스의 메모리 공간으로의 접근을 막는데 이용된다. 현재 가정에서는 메모리의 공간은 모두 같다는 가정을 두었기 때문에, 16KB로 고정된다. 만약 프로세스가 17KB의 주소로 접근을 요청한다면 차단하는 것이다.
이제 이러한 베이스-바운드 레지스터는 CPU칩 상에 존재하는 하드웨어 구조이다. MMU( memory management unit)라 부르기도 한다. 바운드 레지스터는 두가지 방법을 사용해서 메모리 보호를 구현할 수 있다. 가상주소를 베이스 레지스터에 더하기 전 바운드 레지스터와 비교하는 경우와 하드웨어는 먼저 베이스 레지스터를 더하고 그결과가 바운드 안에 위치하는 지를 검사한다. 결과는 똑같다.
## 예제
전자의 방식으로 바운드를 구현한다고 했을때 아래 4KB의 가상주소를 가지는 프로그램을 생각해보자.
바운드 범위 내에 있으면 베이스를 더하여 물리주소를 얻어내고, 그렇지 않다면 폴트(Falut)를 통해 에러를 발생시킨다. 뒤로 가서 배우지만 이러한 폴트의 종류는 매우 매우 많다!
# 하드웨어 도움이 필요
CPU의 커널모드 - 유저모드의 도움이 필요하다.
CPU에 존재하는 MMU에서 추가적인 레지스터 쌍(base - bound)를 가져야 한다. 또 위 예제의 연산같은 경우는 CPU내의 일부 회로를 사용하여 이루어진다.
하드웨어는 베이스-바운드 레지스터 값을 변경하는 명령어를 제공해야한다. 프로세스가 전환되면 베이스와 바운드의 값이 달라지게 되는데 MMU에 있는 레지스터에게 이 것을 알여야 하기 때문인다. 당연히 커널모드에서만 변경이 가능해야 한다.
CPU는 사용자 프로그램이 바운드를 벗어난 경우 불법적인 메모리 접근이라고 판단하고 예외를 발생 시킬 수 있어야 한다. CPU는 사용자 프로그램의 실행을 중지하고 운영체제의 예외 핸들러(Exception handler)가 실행되도록 조치한다.
# 운영체제의 역할
동적 재배치라는 새로운 기능으로 하드웨어에 추가적인 요구사항이 생겼듯 운영체제에도 새로운 요구사항이 생겨난다. 크게 몇 가지로 나눌 수 있다.
프로세스가 실행될때 운영체제는 프로세스의 가상주소공간을, 물리주소공간 어디에 저장을 해야한다. 이때 저장될 메모리 공간을 찾아야 한다. 빈 공간 리스트(free list)라고 불리는 자료 구조를 이용하여 검색한다. 뒤로가서는 더 복잡해져 빈 공간이 없을 경우 어떤 공간을 제거하고 새로운 공간을 올려야하는지 결정해야하기도 한다.
정상적으로 프로세스가 종료되거나 잘못된 행동을 하여 강제적으로 종료시킬때, 메모리를 회수해야한다. 즉 사용했던 공간을 빈공간 리스트(free list)에 넣어주고 연관된 자료구조를 정리한다.
운영체제는 프로세스사이의 문맥교환이 생길때 프로세스마다의 베이스-바운드쌍을 저장하고 복원해야한다. 이 것들은 프로세스 제어 블럭(process control block, PCB)라 불리는 곳에서 관리한다. 시스템소프트웨어를 수강할때 상당히 많이 사용했던 기억이 있다. 문맥 교환말고도 프로세스가 처음 실행 될때 또한 알맞은 베이스-바운드 값으로 설정해야 한다.
예외 핸들러에서의 조치를 정의해야 한다. 예를 들어 bound를 벗어나는 메모리 접근이 동작하면 예외 핸들러를 호출하고, 이 호출에 대한 동작을 정의해야 한다.
# 운영체제 - 하드웨어 - 프로세스의 타임라인
# 요약
동적 재배치 방법을 사용하여, 운영체제는 프로세스의 독립적인 공간을 만들어 투명성을 제공했다. 또 벗어나는 범위에 대해서 오류를 발생시켜 핸들링하기도한다. 그러나 동적 재배치는 비효율적인 모습을 보인다. 바로 내부 단편화(internal fragmentation)이다. 프로세스의 주소공간내에서 사용하지 않는 빈공간이 발생하는 것이다. 위 예에서는 스택과 힙사이의 공간이 사용되지 않아 매우 큰 공간낭비를 보이고 있지만, 이 위치 역시 그대로 물리메모리에 올라가게 된다. 다음장에서는 세그멘테이션(segmentation)기법을 사용하여 이 현상을 해결해 보도록 한다.
내부 단편화(internal fragmentation)와 마찬가지로 외부 단편화(external fragmentation)이라는 개념도 존재한다. 메모리 공간내에서 발생한 공간낭비가 내부 단편화라면 메모리 공간 밖, 즉 프로세스와 프로세스 사이에서의 공간낭비를 외부 단편화라고 하는데, 그 다음장에 차츰 등장하게 될 것이다.
'•Compter Science > Operating System' 카테고리의 다른 글
[OS/OSTEP] 17.vm-freespace : 메모리 빈 공간 관리하기 #11 (0) | 2022.04.18 |
---|---|
[OS/OSTEP] 16.vm-segmentation : 메모리 세그멘테이션 #10 (0) | 2022.04.18 |
[OS/OSTEP] 13.vm-intro : 주소공간(address space)와 메모리 가상화(virtual memory) 의 개념 #8 (0) | 2022.04.18 |
[OS/OSTEP] 09.CPU-sched-lottery-CFS : 비례, 배분을 이용한 스케줄링 #7 (0) | 2022.04.18 |
[OS/OSTEP] 09.CPU-sched-lottery : 비례, 배분을 이용한 스케줄링 #6 (0) | 2022.04.18 |