[OS] 주소 변환의 원리

장선규·2023년 7월 10일
0

[OS] OSTEP Study

목록 보기
10/28

주소 변환의 원리

제한적 직접 실행 (LDE)

  • 사용자 모드와 커널 모드로 구분하여 명령어 실행
  • 커널 모드에서만 특권 명령어(privilege command) 실행 가능
  • 프로세스가 시스템 콜을 호출하거나 타이머 인터럽트가 발생할 때 등의 특정 순간에는 운영체제가 개입하여 트랩(trap) 발생
  • 운영체제는 하드웨어의 지원을 받아 "효율적인" 가상화를 제공
  • 중요한 순간에 운영체제가 관여하여 하드웨어를 직접 "제어"

효율적이고 제어가능한 메모리 가상화 제공

  • 효율성을 높이려면 하드웨어 지원을 활용해야 함
    • 레지스터
    • TLB
    • 페이지 테이블 등 복잡한 하드웨어 사용
  • 제어는 프로그램이 자신 외의 다른 메모리에 접근이 불가능함을 보장하는 것
    • 프로그램을 다른 프로그램으로부터 보호
    • 운영체제를 프로그램으로부터 보호
    • 하드웨어의 도움이 필요
  • 유연성 측면에서 "프로그래머가 원하는 대로 주소공간을 사용하고, 프로그래밍하기 쉬운 시스템"을 만들기를 원함

핵심 질문: 어떻게 효율적이고 유연하게 메모리를 가상화하는가

  • 어떻게 효율적인 메모리 가상화를 구축?
  • 프로그램이 필요로 하는 유연성을 어떻게 제공?
  • 프로그램이 접근할 수 있는 메모리의 위치에 대한 제어를 어떻게 유지?
  • 메모리 접근을 어떻게 적절히 제한?
  • 어떻게 이 모든 것을 효율적으로?

주소 변환 (하드웨어 기반 주소 변환, hardware-based address translation)

  • 주소 변환을 통해 하드웨어는 명령어 반입, 탑재, 저장 등의 가상 주소를, 정보가 실제 존재하는 물리 주소로 변환
  • 프로그램의 모든 메모리 참조를 실제 메모리 위치로 재지정하기 위해 하드웨어가 주소를 변환함
  • DLE 방식에 부가적으로 사용되는 기능
  • 정확한 변환을 위해 운영체제가 관여하여 하드웨어 셋업
  • 운영체제는 메모리의 빈 공간과 사용 중인 공간을 항상 알고 있어야 하고, 메모리 사용을 제어하고 관리함

목표

프로그램이 자신의 전용 메모리를 소유하고, 그 안에 자신의 코드와 데이터가 있다는 환상을 만드는 것

1. 가정

가정1: 당분간 사용자 주소 공간은 물리 메모리에 연속적으로 배치되어야 한다고 가정
가정2: 주소공간은 물리 메모리의 크기보다 작다고 가정
가정3: 각 주소 공간의 크기는 같다고 가정

비현실적이지만, 논의를 진행하며 가정들을 완화할 것

2. 사례

다음과 같은 프로세스가 있다고 하자

이 프로세스에서 다음과 같은 코드가 탑재되어 있다고 가정

void func(){
	int x = 3000; 
    x = x+3 // 우리가 관심있는 코드
}

이 코드를 x86 어셈블리로 바꾸면 다음과 같다

128: movl 0x0(\%ebx), \%eax;	# 0+ebx를 eax에 저장 
132: addl \$0x03, \%eax;		# eax레지스터에 3을 더한다   
135: movl \%eax, 0x0(\%ebx);	# eax를 메모리에 다시 저장
  • x의 주소는 레지스터 ebx에 저장되어 있음
  • 이 주소에 저장되어 있는 값을 movl 명령어를 사용하여 범용 레지스터 eax에 넣는다.
  • eax에 3을 더한다.
  • eax의 값을 같은 위치의 메모리(x의 메모리 주소인ebx)에 저장

이 코드는 프로세스 주소공간에 그림과 같이 배치되어 있음

  • 세 개의 명령어 코드는 코드영역에 존재 (주소는 128)
  • 변수 x의 값은 스택영역에 존재 (초기값은 3000, 주소는 15KB)
  • 프로세스 관점에서의 메모리 접근 과정
    • 주소 128의 명령어를 반입
    • 이 명령어 실행 (주소 15KB에서 탑재)
    • 주소 132의 명령어를 반입
    • 이 명령어 실행 (메모리 참조 없음)
    • 주소 135의 명령어를 반입
    • 이 명령어 실행 (15KB에 저장)

이 프로세스의 관점에서 주소공간은 0~16KB이다. 프로그램이 생성하는 모든 메모리 참조는 이 범위 내에 있어야 한다.

그런데 운영체제는 이 프로세스를 물리 메모리 주소 0이 아닌 다른 곳에 위치시키고 싶다. (가상화 때문)

운영체제는 어떻게 해야 프로세스 모르게 메모리를 다른 위치에 재배치하는가?

3. 동적(하드웨어 기반) 재배치

동적 재배치(dynamic relocation)

  • 베이스와 바운드(base and bound)라고도 함
  • 각 CPU마다 2개의 하드웨어 레지스터인 베이스 레지스터와 바운드 레지스터 필요
  • 베이스 레지스터: 프로그램이 탑재될 물리 메모리 위치
  • 바운드 레지스터: 보호용 레지스터. 메모리 참조가 해당 바운더리 안에 있지 않으면 예외 발생
    (프로세스 주소공간의 크기를 저장 or 프로세스 주소공간의 마지막 물리주소를 저장)
    • 프로세스가 32KB 주소에 재할당 된 것
    • 베이스 레지스터가 32KB로 설정됨
      • 프로세스에 의해 생성되는 모든 주소는
        물리주소 = 가상주소 + base로 변환
      • 프로세스가 주소 128을 사용하면, 실제로 사용하는 주소는 32KB + 128 = 32768
    • 바운드 레지스터는 (이 예에서) 항상 16KB임
      • 바운드 레지스터는 프로세스가 생성한 모든 주소가 합법적이고 프로세스의 "범위"에 있다는 것을 확인
      • 물론 두번째 방법으로 48KB가 들어갈 수도 있음, 이런 경우 그냥 48 넘어가냐 아니냐로 판단

4. 하드웨어 지원: 요약

다음은 동적 재배치를 위해 필요한 하드웨어 자원들이다.

1) 프로세서 상태 워드(processor status word):

  • 레지스터의 한 비트가 CPU의 현재 실행 모드를 나타냄
    (시스템 콜 호출 또는 예외 발생 시 CPU 모드 전환)
  • 두가지 CPU 모드
    • 특권 모드 (커널 모드): 컴퓨터 전체에 대한 권한 가짐
    • 사용자 모드: 응용 프로그램은 사용자 모드에서 실행되고, 명령어 사용에 제한이 있음

2) 베이스와 바운드 레지스터

  • 하드웨어는 베이스와 바운드 레지스터를 자체적으로 제공
  • 메모리 관리 장치(MMU)의 일부임
  • 레지스터 값을 변경할 수 있도록 하드웨어는 명령어를 제공해야함

3) 예외 발생

  • 바운드를 벗어난 주소로 불법적인 메모리 접근을 시도하려는 상황에서 예외를 발생시킬 수 있어야 함
  • "Out of bounds" exception handler가 실행되도록 해야함
  • 운영체제 핸들러는 예외 발생 시 어떻게 대처할지 결정함 (대부분 프로세스 종료시킴)

업로드중..

5. 운영체제 이슈

동적 재배치 지원을 위해 하드웨어가 새로운 기능을 제공하는 것과 마찬가지로, 운영체제에도 새로운 이슈가 등장한다.

하드웨어 + 운영체제 -> 가상 메모리 간단히 구현

베이스와 바운드 방식의 가상 메모리 구현을 위해서 운영체제가 반드시 개입되어야 하는 중요한 네 개의 시점이 존재한다.

1) 프로세스 생성 시 운영체제는 주소공간이 저장될 메모리 공간을 찾아야 함

  • 위의 가정 2,3번에 의해 각 주소 공간은 물리 메모리의 크기보다 작고, 크기가 일정함
  • 운영체제는 물리 메모리를 슬롯의 배열로 보고 각 슬롯의 사용 여부 관리
  • 새 프로세스 생성되면 빈 공간 리스트(free list)에서 빈 공간 찾고, 이젠 사용 하므로 사용중이라고 표시

2) 프로세스 종료 시, 프로세스가 사용하던 메모리를 회수함

  • 정상 종료든, 강제 종료든, 운영체제는 종료한 프로세스의 메모리를 다시 빈 공간 리스트에 넣음
  • 빈 공간 리스트에 넣은 후 연관된 자료 구조를 모두 정리

3) 운영체제는 문맥 교환이 일어날 때 조치 취함

  • 베이스, 바운드 레지스터는 CPU당 하나씩 있음
  • 근데 각 프로그램은 서로 다른 물리 주소에 탑재되어야 하기 때문에, 실행중인 프로그램마다 다른 베이스,바운드 값을 가짐
  • 따라서 운영체제는 문맥교환 시 메모리에 존재하는 자료구조 안에 베이스와 바운드 레지스터 값을 저장해야 함
  • 이 자료구조를 프로세스 구조체(process structure) 또는 프로세스 제어 블럭(PCB)라고 함
  • 운영체제는 프로세스를 다시 시작할 때 또는 처음 실행시킬 때, 이 프로세스에 맞는 값으로 CPU의 베이스와 바운드 값을 설정해야 함
  • 프로세스의 주소공간을 옮기는 방법
    • 프로세스 실행 중지
    • 운영체제는 새 위치로 주소 공간을 복사함
    • 운영체제는 프로세스 구조체에 저장된 베이스 레지스터를 갱신하여 새 위치를 가리키도록 함

4) 예외 처리

  • 운영체제는 예외 핸들러 또는 호출될 함수를 제공해야 함
  • 운영체제는 부팅할 때 특권 명령어를 사용하여 예외 핸들러를 설치함
  • 프로세스가 불법적인 행위를 하면, 운영체제는 그 프로세스를 종료시킴

업로드중..

6. 요약

  • 주소변환을 사용하면 운영체제는 프로세스의 모든 메모리 접근을 제어할 수 있음 (커널모드)
  • 주소변환을 사용하면 접근이 항상 주소 공간의 범위 내에서 이루어지도록 보장할 수 있음 (베이스,바운드)
  • 하드웨어 지원 덕분에 효율성 확보 (빠른 물리<=>가상 주소 변환)
  • 베이스와 바운드 방식은 효율적이고, 보호의 기능도 제공
  • 근데 사실 동적 재배치는 비효율적임
    • 32KB~48KB 사용중이지만, 힙과 스택이 작아 사용되지 않는 영역이 낭비되고 있음 (내부 단편화)

내부 단편화 개선하는 방법?
-> 베이스와 바운드 정교화 (세그멘테이션)

다음 장에서 배울 것!

profile
코딩연습

0개의 댓글