본문 바로가기

잡다한 개발잡담

운영체제의 주소 바인딩 알아보기

운영체제 - 주소 바인딩

Goal

  • 프로그램이 물리적 메모리에 어떻게 올라가서 주소를 할당받는지 이해하기

메모리의 주소

집마다 고유의 주소가 있는 것처럼 메모리 역시 주소를 통해 접근할 수 있는 저장장치입니다.

주소 바인딩

프로그램이 실행을 위해 메모리에 적재된다면 그 프로세스를 위한 독자적인 주소 공간이 생성됩니다.

우리는 이 주소를 논리적인 주소(logical address) 또는 가상 주소(vritual addres)라고 칭합니다.

이와 같은 논리적 주소는 각 프로세스마다 독립적으로 할당되며 0번지부터 시작되고, CPU는 이와 같은 논리적 주소에 근거해 명령을 실행합니다.

그리고 물리적 주소(physical adderss)는 물리적 메모리에 실제로 올라가는 위치를 말합니다.

보통 물리적 메모리의 낮은 주소 영역에 운영체제가, 높은 주소 영역에는 사용자 프로세스들이 올라갑니다.

그리고 프로그램이 실행되기 위해서는 위의 두 가지 개념이 모두 사용되며 아래와 같은 조건을 충족해야 합니다.

  1. 해당 프로그램이 물리적 메모리에 올라가 있어야 합니다.
  2. CPU가 기계어 명령을 수행하기 위한 논리적 주소를 통해 메모리를 참조하기 위해 해당 논리적 주소가 물리적 메모리에 맵핑되어 있어야 합니다.

여기서 프로세스의 논리적 주소를 -> 물리적 메모리 주소로 연결시키는 작업을 주소 바인딩(address binding)이라고 합니다.

주소 바인딩의 방식

프로그램이 적재되는 물리적 메모리의 주소가 결정되는 시기에 따라 세 가지로 분류할 수 있습니다.

(1) 컴파일 타임 바인딩(Compile time binding)

물리적 메모리 주소가 프로그램을 컴파일 할 때 결정되는 주소 바인딩 방식

즉, 프로그램 내부에서 사용하는 주소와 물리적 메모리 주소가 동일.

-> 물리적 메모리 위치를 변경하려면 컴파일을 다시 해야 하며, 잘 사용하지 않는 기법

-> 만약 이미 다른 프로세스가 메모리를 차지하고 있는 경우도 존재할 수 있습니다.

-> 즉 하나의 프로세스만을 사용하는 것이 확실 할 때만 사용합니다.

(2) 로드 타임 바인딩(Load time binding)

프로그램의 실행이 시작될 때 물리적 메모리의 주소가 결정되는 주소 바인딩 방식

로더(loader)의 책임하에 물리적 메모리 주소가 부여되며, 프로그램이 종료될 때까지 물리적 메모리 상의 위치가 고정됩니다.

(로더란 사용자 프로그램을 메모리에 적재시키는 프로그램)

결과적으로 프로그램 내부에서 사용하는 주소와 물리적 메모리 주소는 다른 방식입니다.

물리적 메모리 주소와 논리적 메모리 주소를 분리하여 컴파일 타임 바인딩과는 다르게 multiprogramming이 가능합니다.

문제는 메모리를 참조하는 명령어를 다 변경해줘야 한다는 점으로 메모리 로딩 시간이 엄청 오래 걸리는 단점이 있습니다. 그래서 실제로 사용하는 방식은 아닙니다.

(3) 실행시간 바인딩(execution time binding or run time binding)

프로그램이 실행을 시작한 이후에도 프로그램이 위치한 물리적 메모리상의 주소가 변경될 수 있는 바인딩 방식

이 방식은 cpu가 주소를 참조할 때마다 해당 데이터의 물리적 메모리가 어디에 위치해야 하는지, 주소 매핑 테이블(address mapping table)을 이용해 바인딩을 점검합니다. 또한, 다른 방식들과 다르게 실행시간에 바인딩이 이루어지므로 기준 레지스터와 한계 레지스터를 포함한 MMU라는 하드웨어적인 지원이 뒷받침 되어야 합니다. (MMU는 논리적 주소를 물리적 주소로 매핑해주는 하드웨어 장치)

(4) 로드 타임 바인딩과 실행 시간 바인딩의 차이점

로드 타임은 메모리에 로딩할 때 주소 변환 작업을 미리 다 해놓지만 반면에 실행 시간 바인딩은 실행 할때 하게 됩니다.

즉, 로드타임은 한 번만 바꿔 놓게 되면 똑같은 해당 주소로 접근하면 됩니다. 그러나 실행 시간 바인딩의 경우 변환 작업을 수행하고 메모리에 접근하게 됩니다.

위와 같은 차이점만 보게 되면 로드 타임이 더욱 좋아 보이지만, 하드웨어 성능이 높아져서 하드웨어 상의 로직 수행으로 실행 시간 바인딩을 수행해도 성능 상 문제가 없다고 합니다.

그러나 로드의 경우 메모리 로딩시의 오버헤드가 큰 관계로 사용하지 않습니다.

MMU기법 알아보기

CPU가 특정 프로세스의 논리적 주소를 참조하고 싶을 때, MMU 기법은 그 주소 값에 기준 레지스터의 값을 더해 물리적 주소 값을 얻어낸다.

이때, 기준 레지스터는 재배치 레지스터(relocation register)라고도 부르고 프로세스의 물리적 메모리 시작 주소를 가지고 있다.

MMU 기법은 프로그램의 주소 공간이 물리적 메모리의 한 장소에 연속적으로 적재되는 것을 가정합니다.

그러므로 적재되는 물리적 메모리 상의 시작 주소만 알면 쉽게 주소변환이 가능합니다.

CPU가 논리적 주소 123번지에 있는 메모리를 요청하게 되면 기준 레지스터(재배치 레지스터)에 저장된 23000을 더해 23123 물리적 메모리 주소 내용을 참조하게 됩니다. 즉 그러므로 논리적 주소 123번지는 기준 레지스터의 값으로부터 얼마나 떨어져 있는지를 나타내는 개념으로도 생각할 수 있습니다.

프로세스는 자신마다 고유한 주소 값을 가지고 있고, 각 프로세스마다 서로 다른 내용을 담게 됩니다. 그래서 cpu가 논리적 주소 100번지를 참조할 때, 이 CPU에서 수행하는 프로세스가 다를 경우 가리키는 내용은 상이해야 합니다.

MMU기법에서는 문맥 교환으로 cpu에서 수행 중인 프로세스가 변경될 때, 재배치 레지스터의 값을 그 프로세스에 해당되는 값으로 재설정하면서 위와 같은 방법을 지원합니다. 이와 같은 방식은 하나의 주소 체계를 가지는 물리적 메모리 내에 여러 프로세스가 올라올 경우 프로세스 별 논리적 주소를 어떻게 물리적 주소로 매핑할 수 있는지 보여줍니다.

MMU - 다중 프로그래밍 환경에서의 고려할 점

그러나 한 가지 더 고려해야 할 것이 있습니다. 다중 프로그래밍 환경에서는 물리적 메모리 안에 여러 개의 프로세스가 동시에 올라가 있는 경우가 대부분입니다.

위의 MMU 방식을 사용하여 주소 변환을 했을 경우 CPU가 요청한 논리적 주소 값 + 재배치 레지스터의 값이 다른 프로세스의 주소 공간을 가리키는 경우가 생길 수 있습니다.

이와 같은 상황을 방지하기 위해 한계 레지스터라는 또 하나의 레지스터를 사용하게 됩니다. 한계 레지스터라는 이름처럼 프로세스가 자신의 주소 공간을 넘는 메모리를 참조하는지 체크할 때 사용합니다. 그래서 CPU에서 현재 수행 중인 프로세스의 논리적 주소의 최대 값인 프로세스의 크기를 담고 있습니다.

CPU가 요청한 논리적 주소 값이 한계 레지스터의 값 이내라면, 재배치 레지스터의 값을 더해 물리적 메모리 위치에 접근하게 됩니다.

만약 한계 레지스터보다 크다면 트랩이 발생합니다.

출처 : 운영체제와 정보기술의 원리,

https://jhnyang.tistory.com/247?category=815411