x86-64 프로세서 (인텔 64비트 호환 프로세서)에는 다섯 가지의 운영 모드가 존재한다.
컨트롤 레지스터와 인터럽트를 통해 각 모드로 전환할 수 있다.
다섯 가지 운영모드가 모두 구현되어야만 OS를 만들 수 있는 것은 아니다.
목적에 따라 몇개의 운영모드는 구현하지 않거나 필요하면 구현하는 방식으로 진행할 수 있기 때문에, 이 중에서도 필수모드와 선택 모드로 구분된다.
운영 모드
필수 운영 모드
리얼모드
- 프로세서가 전원이 켜지거나 리셋되면 프로세서는 리얼모드로 진입함 (이전에 어떤 상태인지는 상관 없음)
- 16비트 프로세스와 동일하게 동작
- BIOS(Basic Input Output System)의 여러 기능을 사용할 수 있음 => 디스크 읽기 및 쓰기, 그래픽 모드 전환 등 제공
- 디바이스 드라이버를 제작하지 않아도 됨
- OS 이미지를 디스크에서 메모리로 복사하여 보호 모드로 변경
보호모드
- IA-32e 모드로 전환하기 위한 것
- 32비트 윈도우 or 리눅스 os가 동작하는 기본 모드
- 최대 4G(\(2^{32}\)) 주소 공간을 제공하며, OS의 필수 기능으로 자리 잡은 보호, 멀티태스킹, 세그멘테이션, 페이징 등의 기능을 하드웨어 적으로 지원함
- 레지스터와 자료구조가 다양함
IA-32e 모드
- 32비트 호환 모드 : 보호모드와 같은 기능 수행
- 64비트 모드
- 16E(\(2^{64}\))의 주소 공간 제공
- 레지스터 수가 보호 모드보다 많음
- 프로세서가 32비트 호환 모드일 때는 보호모드에 있는 것 처럼 동작하기에 32비트 코드를 그대로 실행시킬 수 있다.
- 서브 모드만 변경함으로써 보호 모드 코드를 실행시킬 수 있다.
- 64비트 os에서 보호 모드 코드를 별다른 처리 없이 그대로 실행할 수 있는 이유이다.
운영 모드 전환
기존에 어떤 모드에 있었고. 어떤 모드로 변환하려는지에 따라서 다양하게 모드를 거쳐서 변환될 수도 있다.
ex) 리얼모드 -> 보호모드 -> IA-32e
- 처음 전원이 켜지거나 리셋되면 리얼모드로 진입
- 리얼모드 -> 보호모드
- 보호 모드 -> 가상 8086모드, IA-32e 모드, 리얼모드
- 시스템 관리 모드 : 모든 모드에서 진입할 수 있고 처리가 끝나 이전의 운영모드로 복귀하거나, 리셋을 통해 리얼모드 진입 가능
레지스터
운영 모드는 크게 16비트 모드, 32비트 모드, 64비트 모드 세 가지로 나눌 수 있다.
x86-64 프로세서에 존재하는 많은 레지스터들이다.
이 중 가장 많이 사용하는 것은 범용 레지스터, 세그먼트 레지스터, 컨트롤 레지스터이다.
범용 레지스터
범용 레지스터를 사용할 때, 우리는 비트를 구분할 수 있다.
따라서 보호모드나 리얼모드일 때 레지스터의 일부 영역만 사용이 가능하도록 하면서 범용 레지스터를 사용할 수 있도록 한다.
IA-32e 모드의 기본 오퍼랜드의 크기는 32비트이다.
IA-32e 모드의 서브모드인 64비트 모드 또한, 기본 오퍼랜드의 크기를 32비트로 지정한다.
이를 해결하기 위해 REX 접두사를 사용하면 64비트 오퍼랜드 크기를 사용할 수 있다 .
RIP : 현재 수행중인 명령의 주소를 가리키는 레지스터
RIP 레지스터 + 32비트 오퍼랜드 -> 64비트 주소 공간을 나타낼 수 있음
즉, 메모리의 절대 주소를 직접 지정하기 않고 RIP를 기준으로 주소를 계산한다. ex) MOV rax, [rip+0x200]
하지만, 기본 오퍼랜드의 크기가 32비트이기 때문에 상위와 하위 2G를 접근할 수 없다. (상위 32비트를 사용하는 부분)
이를 해결하기 위하여 분기 명령어(jmp)를 기본 64비트를 하여 전체 주소 범위에서 이동할 수 있도록 하였다.
세그먼트 레지스터
- 16비트 레지스터
- 주소 영역을 다양한 크기로 구분하는 역할을 함
- 리얼모드 : 단순히 고정된 크기의 주소 공간을 지정하는 역할
- 보호모드, IA-32모드 : 접근 권한, 세그먼트의 시작 주소 및 크기 지정에 사용
CS, DS, SS, ES, FS, GS 총 6개로 구성됨
메모리 관리 기법에 따라서 주소 공간을 구분하는 방법이 달라진다.
1. 세그멘테이션 기법
2. 페이징 기법
두 가지의 메모리 관리 기법이 존재하는데, 세그먼트 레지스터를 이용하는 것이 세그멘테이션 기법이다.
컨트롤 레지스터
- 운영모드를 변경
- 현재 운영 중인 모드의 특정 기능을 제어하는 레지스터
- CR0, CR1, CR2, CR3, CR4의 5개의 컨트롤 레지스터가 존재함
- x86-64에서는 CR8이 추가되어 총 6개가 존재함
- 리얼모드, 보호모드 : 32비트 크기
- IA-32e모드 : 64비트 크기 (일부 제약 사항 존재)
- CR0, CR4, CR8은 상위 32비트를 0으로 설정
- CR3는 비트 40부터 51까지 0으로 설정
메모리 관리 기법
Segmentation | 세그멘테이션
전체 영역을 원하는 크기로 나누어 관리하는 방식
- 세그먼트 레지스터에 세그먼트의 시작 주소 혹은 Descriptor라는 자료구조의 위치 설정
Paging | 페이징
일정한 단위로 잘라진 조각을 모아 원하는 크기로 관리하는 방식
- 컨트롤 레지스터 중 CR3 레지스터에 페이지 디렉터리라고 불리는 자료구조의 물리 주소를 설정해야 사용 가능
- page라는 일정한 크기로 나누고, 선형 주소와 물리 주소를 나눠놓은 페이지로 ㅇ녀결하는 방식
- 물리 메모리 크기보다 더 큰 영역의 선형 주소도 물리 페이지만 연결하면 사용 가능
- 물리 메모리를 4KB로 나누고, 선형 주소를 3단계로 구분한다.
- 물리 메모리를 4MB로 나누고 선형 주소를 2단계로 구분한다.
그 중, 3단계 페이징에 대해서 설명해보겠다.
선형 주소를 디렉터리, 테이블, 오프셋 세 부분으로 나누며, 물리 메모리를 4KB 페이지로 나누어 관리한다.
선형 주소의 디렉터리 부분과 테이블 부분은 각각 페이지 디렉터리와 페이지 테이블에 있는 엔트리의 위치를 나타낸다.
페이지 디렉터리와 테이블은 메모리 공간에 있는 자료구조이다. (4byte)
CR3의 컨트롤 레지스터는 페이지 디렉터리의 시작 주소를 가리키며, 페이지 디렉터리 엔트리의 위치 계산에 사용한다.
12 ~ 31 : 페이지 기준 주소 설정
11 ~ 0 : 속성 필드
U/S (User/Supervisor) 필드 : 해당 페이지에 접근할 수 있는 권한
=> 0 : 유저 애플리케이션(3)을 제외한 모든 레벨에서 접근 가능
디렉터리 10비트, 테이블 10비트, 페이지 12비트로 구분한다.
- CR3 레지스터에 설정된 어드레스로 페이지 디렉터리의 시작 주소를 찾음
- 페이지 디렉터리의 시작 주소에 선형 주소의 디렉터리 오프셋을 이용해서 해당 디렉터리 엔트리를 찾는다. (디렉터리 엔트리에 설정된 값이 페이지 테이블의 시작 주소)
- 페이지 테이블의 시작 주소에 선형 주소의 테이블 오프셋을 이용해서 해당 페이지 테이블 엔트리를 찾는다. (페이지 테이블 엔트리에 설정된 값이 4KB 페이지의 시작 주소)
- 페이지의 시작 주소에 선형 주소의 페이지 오프셋 값을 더해 실제 물리 주소로 변환한다.
세그멘테이션 보호 기능과 페이지의 보호 기능을 조합하면 커널 영역과 유저 영역의 구분이 가능하다.
리얼 모드
- 최대 1MB까지 주소 공간을 사용
- 세그멘테이션만 지원함
- 세그먼트의 크기는 64K로 고정
- 세그먼트의 시작 주소 = 세그먼트 레지스터에 직접 설정
- 세그먼트의 시작 주소 : 코드나 메모리에 접근할 때 기준 주소 (base address)로 사용됨
페이징 기법을 사용하지 않기 때문에 물리 주소로 변환하는 방식이 간단하다.
세그멘테이션을 거쳐서 나온 어드레스가 바로 물리주소가 된다.
리얼 모드의 세그멘테이션 : 세그먼트 레지스터 + 범용 레지스터
Q) 세그먼트 레지스터의 크기도 16비트, 범용 레지스터의 크기도 16비트인데 최대 1MB의 영역에 접근할 수 있는가?
A) 세그먼트 레지스터의 값을 그대로 범용 레지스터에 덩하는 것이 아니라, 세그먼트 레지스터의 값에 16 곱한 값을 세그먼트의 기준 주소로 사용한다. 따라서 1MB에 근접하는 값을 사용할 수 있게 된다.
세그먼트의 크기가 64KB인 이유 => 범용 레지스터의 크기
16비트 프로세서에는 32비트 레지스터가 없고, 범용 레지스터가 모두 16비트이다.
따라서 16비트로 접근할 수 있는 범위가 0xffff -> 세그먼트의 크기가 64KB가 되는 것이다.
보호 모드
- 세그멘테이션과 페이징 모두 지원
- 보호 모드의 세그멘테이션은 리얼 모드의 세그멘테이션보다 많은 기능을 제공
- 세그먼트 레지스터에 세그먼트의 기준 주소를 직접 설정하는 대신 디스크립터 자료구조의 위치 (Offset)을 설정함
- 세그먼트 레지스터가 아닌 세그먼트 셀렉터라고 함
Descriptor | 디스크립터
메모리 영역의 정보를 저장하는 자료 구조로 여러가지가 존재한다.
그 중, 세그먼트에 대한 정보를 나타내는 디스크립터를 세그먼트 디스크립터라고 부른다.
세그먼트 디스크립터에는
- 세그먼트의 시작 주소
- 크기
- 권한
- 타입
등의 정보가 들어있다.
DPL (Descriptor Privilege Level) : 해당 세그먼트에 접근하기 위한 최소한의 권한 (0~3) - 숫자가 작으면 권한 높음
CPL (Current Privellege Level) : 현재 수행중이 ㄴ특권 레벨
=> CPL ≥ DPL 이여야만 세그먼트에 접근 가능
보호모드에서 세그먼트 레지스터 -> 세그먼트 디스크립터의 위치
세그먼트 디스크립터는 메모리상에 위치하는 자료구조의 일종으로 GDT (Global Descriptor Table) 에 모여있다.
GDT : 연속된 디스크립터의 집합이며, 최대 8192개의 디스크립터를 포함할 수 있는 테이블 형태의 자료구조이다.
GDT도 메모리에 위치하는 자료구조이므로, 프로세서에 GDT의 위치를 직접 알려야한다.
GDTR(Global Descriptor Table Register) 레지스터가 16비트 GDT 크기 필드와 32비트 기준 주소 필드로 구성된 자료구조의 물리 주소를 넘겨받는다. 프로세서는 세그먼트 셀렉터를 통해 주소에 접근할 때마다 GDT의 위치를 찾는데에 참조한다.
주소 계산 방법 : 세그먼트 레지스터 + 범용 레지스터
선형 주소는 이후의 페이징의 입력 값이 된다.
IA-32e 모드
IA-32e 모드는 두 가지 서브모드로 호환모드와 64비트 모드가 존재한다.
호환모드는 보호모드와 동작이 같다.
64비트 모드는 사용가능한 최대 어드레스는 \(2^{64}\)로 16EB까지이다.
세그먼트 기준 주소와 크기에 관계 없이 모든 세그먼트가 기준 주소는 0, 크기는 64비트이다.
서브모드를 지원하기 때문에 세그먼트 디스크립터에 필드(21)가 추가된다.
IA-32e 모드의 페이징은 보호 모드와 달리 주소 공간이 64비트로 늘어나므로 PAE 기능이 활성화된다.
주소가 늘어난만큼 변환 단계도 늘어나기 때문에 4KB 페이지는 5단계로, 2MB 페이지는 4단계로 변경된다.
이로 인해 PML4(Page Map Level 4 Table), PDPT(Page Directory Pointer Table)이 추가된다.
변환 과정은 동일하다.
실제로 변환에 사용되는 부분은 48비트 까지이다.
출처
- 64비트 멀티코어 OS 원리와 구조
'CS > OS' 카테고리의 다른 글
부팅과 부트로더 (0) | 2025.01.23 |
---|---|
CPU Scheduling (1) | 2024.08.12 |
Limited Direct Execution (0) | 2024.04.28 |
Process (5) | 2024.04.28 |
Data Structures (Process Control Blocks) (0) | 2024.03.10 |