Post

Ch9. Main Memory

Ch9. Main Memory

Chapter9: Main Memory

목표

  • 메모리 하드웨어를 구성하는 다양한 방식에 대해 설명
  • 다양한 메모리 관리 기법들
  • 순수 세그먼테이션과 페이징을 포함한 세그먼테이션을 모두 지원하는 Inter Pentium의 구조를 설명

Protection

프로세스가 자신의 주소 공간 내의 주소에만 접근하도록 강제할 필요가 있다. -> 즉, 다른 프로세스나 운영체제의 영역을 침범하지 않도록 막하야한다.

보호 방법 -> base 레지스터와 limit 레지스터 쌍을 이용하여 제공함. -> 이 레지스터들은 프로세스의 논리적 주소 공간을 정의함.

Address Binding

disk에 저장된 프로그램은 메모리로 로드되어 실행을 기다리는 상태에서 input queue을 형성함.
-> 그러나 첫 번째 사용자 프로세스가 항상 주소 0000번 물리 주소에 있어야 하는 것은 비효율적임.

  • 소스 코드 상의 주소는 일반적으로 심볼릭 형태다.
  • 컴파일된 코드는 이러한 심볼릭 주소를 재배치 가능 주소로 바인딩한다.
  • 링커나 로더가 이 재배치 가능한 주소를 절대주소로 바인딩한다.
    -> 즉, 각 바인딩 과정은 한 주소 공간을 다른 주소 공간에 매칭하는 과정이다.

바인딩 과정

  1. 컴파일 시점
    • 만약 메모리 위치가 사전에 정해져 있다면, 절대 주소를 생성할 수 있다.
    • 단, 시작 위치가 바뀌면 코드를 다시 컴파일해야 한다.
  2. 로드 시점
    • 컴파일할 떄 메모리 위치를 모르면 -> 반드시 재배치 가능한 코드를 생성해야 한다.
    • 이 코드는 로딩 시점에 실제 메모리 주소로 바인딩된다.
  3. 실행 시점
    • 프로세스 실행 중에 메모리 위치가 바뀔 수 있다면, -> 바인딩은 실행 시점까지 지연된다.
    • 이 경우에는 하드웨어 지원이 필요함 -> 가상메모리 개념이 필요함.

Logical VS Phyical Address Space

논리 주소 공간과 물리 주소 공간을 분리하는 개념은 메모리 관리의 핵심 요소이다.

용어정리

  • 논리 주소 (Logical Address)
    • CPU가 생성하는 주소.
    • 가상 주소 (virtual address)라고도 불림.
  • 물리 주소 (Physical Address)
    • 실제 메모리 장치가 접근하는 주소

시점에 따른 차이

  • 컴파일 시점과 로드 시점에는. -> 논리 주소와 물리 주소가 같음
  • 실행시점 에는. -> 논리 주소와 물리 주소가 다름. -> 이유 : 이 시점에서 가상 메모리, 페이징 등을 통해 주소 변환이 일어.

Memory Management Unit (MMU)

MMU는 하드웨어 장치로, 실행 시점에 논리 주소를 물리 주소로 변환해주는 장

base-register 방식의 일반화된 형태인 간단한 메모리 변환 방식을 설명함.
base registerrelocation register라고도 불림.
사용자 프로그램이 생성한 논리 주소에 relocation register의 값을 더해서 물리 주소를 생성한다.

사용자 프로그램은 논리적인 주소를 사용할 뿐 실제 물리적인 주소를 전혀 보지 못한다.

Dynamic Loading

📌 핵심 개념

  • 프로그램 전체를 처음부터 메모리에 올릴 필요는 없다.
  • 루틴은 호출될 때까지 메모리에 로드됮 않는다.
  • 이 방식은 메모리 공간 활용 효울을 높여주며,
    -> 사용되지 않는 루틴은 아예 로드되지 않아 메모리를 절약할 수 있다.

💽 구현 방식

  • 모든 루틴은 재배치 가능한 형식(relocatable format) 으로 디스크에 저장되어 있다.
  • 잘 사용되지 않는 코드가 많고, 그 코드가 매우 클 경우 특히 유용하다.

🛠️ 운영체제 지원 여부

  • 운영체제의 특별한 지원이 없어도 구현 가능하다.
    → 즉, 프로그램 설계만으로 가능.
  • 다만, 운영체제가 동적 로딩을 돕는 라이브러리 등을 제공할 수도 있다.

동적 연결 vs 정적 연결

  • 정적 연결. -> 시스템 라이브러리와 프로그램 코드가 하나의 실행 파일로 미리 합쳐짐
  • 동적 연결. -> 실행 시점까지 라이브러리 연결을 지연 시킴 -> 따라서 프로그램 실행 시 실제 필요한 코드만 메모리에 올라감

Contiguous Allocation

📌 기본 개념

  • 주기억장치는 운영체제와 사용자 프로세스를 모두 지원해야 한다.
  • 메모리는 제한된 자원이므로 효율적으로 할당해야 한다.
  • 연속 할다다은 초창기 메모리 관리 방식 중 하나이다.

🧩 메모리 분할 방식

  • 주기억장치는 보통 두개의 파티션으로 나뉜다.
    1. 운영체제 영역 (보통 낮은 주소에 위치) -> 인터럽트 벡터와 함께 있음.
    2. 사용자 프로세스 영역 (보통 높은 주소에 위치) -> 각각의 사용자 프로세스는 메모리 내에서 하나의 연속된 블록에 저장돈다. -> 논리적으로는 연속적인 메모리 내에 있어야 하지만 물리적으로는 그렇지 않을 수 있다.

Variavle Partition

📌 기본 개념 Multiple-partition allocation 기법의 한 형태. -> 메모리 고정 크기가 아닌, 프로세스의 필요에 따라 가변적으로 분할함.

  • 가변 크기 분할 -> 프로세스의 크기에 맞춰 메모리 할당 -> 공간 효율 상승
  • Hole: 메모리 내의 빈 공간 블록
  • 프로세스가 도착하면, 그 프로세스를 수용할 수 있는 충분히 큰 hole에 할당됨.
  • 프로세스가 종료되면, 해당 파티션은 해제되고, 인접한 빈공간들과 병합되어 하나의 큰 hole로 만들어짐
  • 우영체제는 다음 두 가지 정보를 추적해야함:
    1. 할당된 파티션
    2. 남은 빈 공

Dynamic Storage-Allocation Problem

빈 공간 목록에서 크기 n을 요청하는 프로세스를 어떻게 효율적으로 할당할 것인가?

방법들

  1. First-fit : 처음으로 충분히 큰 hole을 찾으면 거기에 할당. -> 빠르며, 일반적으로 성능이 가장 좋음
  2. Best-fit: 가장 작은 (딱 맞는) hole을 찾아 할당. -> 공간 낭비 최소화, but 전체 리스트를 다 훑어야 할 수 있음. -> 결과적으로 남는 공간이 가장 작아짐
  3. Worst-fit: 가장 큰 hole에 할당. -> 큰 공간을 쪼개서 나중에 활용할 여지를 남김. -> 결과적으로 남는 공간이 가장큼, 역시 전체 리스틀 검색해야함.

Fragmentation

  1. External Fragmentation
    • 전체 메모리 용량은 충분하지만, 연속된 공간이 없어 요청을 만족하지 못하는 경우. -> 즉, 메모리는 존재하지만 연속적이지 않음 -> 할당 불가
  2. Internal Gragmentation
    • 할당된 메모리 크기 실제 요청보다 약간 더 큼. -> 이 차이는 파티션 내부에서 사요되지 않고 낭비되는 공간

      example). first-fit을 사용하면,
      N개의 블록이 할당되었을 때 약 0.5개의 블록이 단편화로 인해 사용 불가능
      전체 공간 대비 비율로 보면. 0.5N / (N + 0.5N) = 1/3 이 낭비됨. 이로 부터 유도 되넉이 바로 50%의 법칙이다.

Compaction (조각 모음)

외부 단편화를 해결하는 방법. 메모리 내의 데이터를 정렬해서, 빈공간을 하나의 큰 블록으로 모음

⚠️ Compaction 조건 실행 중인 코드의 재배치가 가능할 떄만 수행 가능. -> 즉, 동적 재배치가 가능해야한다.
-> 실행 시점에 수행되어야한다.

🛠 I/O 문제

  • 만약 I/O 중에 메모리 이동(compaction)이 발생하면,
    I/O 버퍼의 위치가 바뀌어 문제가 발생할 수 있음

  • 해결책:

    1. I/O 작업 중인 job은 메모리에 고정(latch)
    2. 또는 I/O는 운영체제의 버퍼(OS buffer)에서만 수행

💽 저장장치(Backing Store)의 단편화

  • 디스크와 같은 저장 공간(backing store)도 단편화 문제를 동일하게 겪음

Paging

프로세스의 물리 주소공간은 연속될 필요 없음 -> 빈 물리 메모리 공간 어디는 할당 가능

장점

  • 외부 단편화를 방지
  • 다양한 크기의메모리 조각 문제를 제거

구조

  • 물리 메모리는 고정 크기 블록으로 나뉨 -> 이를 프레임 이라 부름
  • 논리 메모리도 같은 크기의 블록으로 나쉼 -> 이를 Page 라고 부름
  • 모든 프리 프레임들을 운영체제가 관리

실행 절차

  • 크기 N 페이지인 프로그램을 실행하려면, N개의 빈 프레임을 찾아 매칭해야함.
  • 페이지 테이블을 사용하여 논리주소 -> 물리 주소로 벼변환

보조 기억 장치도 페이지 단위로 분할됨 -> backing store 역시 페이지 다뉘로 나위어 저장

단점

  • 내부 단편화는 여전히 존재 -> 마지막 페이자 꽉 차지 않았을 경우, 남은 공간은 낭비

Address Translation Scheme

📌 주소는 두 부분으로 나뉜다

  1. 페이지 번호
    • 페이지 테이블의 인덱스로 사용됨
    • 페이지 테이블은 각 논리 페이지가 매핑되는 물리 프레임의 시작 주소를 저장함
  2. 페이지 오프셋
    • 해당 페이지 내에서 얼마나 떨어졌는지를 나타냄
    • 페이지의 시작 주소와 더해져서 최종 물리 주소를 구성

🧮 비트 구조

1
2
* 	전체 논리 주소 공간 크기: 2^m
* 	페이지 크기: 2^n

→ 논리 주소는 아래처럼 나뉨: | 비트 영역 | 의미 | 크기 | |:-:|:-:|:-:| | p | 페이지 번호 | m - n 비트 | | d | 페이지 오프셋 | n 비트 |

Calculating Internal Fragmentation

📌 예시 조건

  • 페이지 크기 = 2048 byte
  • 프로세스 크기 = 72766 byte
  • 필요한 페이지 수 = 72,766 ÷ 2,048 = 35 page + 1,086 byte -> 36번째 페이지는 일부만 사용되고 나머지는 낭비

내부 단편화 2048 - 1086 = 962 bytes

  • 최악의 경우 단편화 = 한 프레임 크기에서 1 byte만 사용될 수도 있음
  • 평균적으로는 단편화 ≈ 프레임 크기의 절반

💡 그럼 프레임 (페이지) 크기는 작을 수록 좋은가? 작으면 단편화는 준다. 하지만, -> 페이지 수가 많아지고 페이지 테이블 엔트리 수 증가 -> 테이블 관리 비용 증가 (메모리 차지 + 성능 부담)

최근에는 페이지 크기를 점점 키우는 경향이 있다 -> 페이지 수를 줄여서 테이블 부하를 줄이기 위함 -> 4KB, 8KB 두 가지 크기를 지원

Implementation of Page Table

📌 페이지 테이블 저장 위치

  • 페이지 테이블은 주기억장치 에 저장됨
  • 이를 점급하기 위한 두 레지스터 존재
    1. PTBR (Page-Table Base Register) -> 페이지 테이블이 어디에 있는지를 가리킴
    2. PTLR (Page-Table Length Register) -> 페이지 테이블의 크기 (에트리 수)를 나타냄

📉 기본 구조의 문제점

  • 이 방식에서는 모든 데이터 또는 명령어 접근 시, -> 메모리를 2번 접근해야 함:
    1. 페이지 테이블에서 물리 주소 조회
    2. 해당 물리 주소에서 실제 데이터/명령어 읽기

⚡ 해결책: TLB (Translation Look-aside Buffer)

  • TLB는 고속 하드웨어 캐시 -> 최근 사용한 페이지 번호와 물리 프레임 번호를 저장 -> 주소 변환 시 TLB 먼저 조회하여 메모리 접근 횟수 줄임

  • TLB는 연관 메모리 (associative memory), 즉 내용 기반 접근 (content-addressable memory) 사

Translation Look-Aside Buffer (TLB)

✅ ASID (Address-Space Identifier)

  • 일부 TLB는 각 엔트리에 ASID 값을 저장함 → 프로세스를 고유하게 식별할 수 있게 함 → 그래서 문맥 전환(context switch)TLB를 비우지 않아도 됨

🔵 그렇지 않으면 → 매 문맥 전환마다 TLB flush(초기화) 필요

TLB 크기

  • 보통 작음: 64 ~ 1024개 엔트리 정도
  • 그만큼 히트율 유지와 교체 정책이 중요

🔁 TLB miss 발생 시

  • 해당 매핑 정보는 페이지 테이블에서 가져옴 -> TLB에 새로 로드됨
  • 이때 교체 정책 (LRU, FIFO 등)을 고려해야함
  • 일부 중요한 엔트리는 wired down -> 즉, 항상 유지되며 제거되 않음 (예: 커널 코드용)

🧠 고급 아키텍처 지원 * 일부 CPU는 명령어용 TLB, 데이터용 TLB 따로 제공 * TLB 계층구조(hierarchical) 를 가지기도 함 (L1 TLB, L2 TLB…)

Hardware

✅ 연관 메모리(Associative Memory)의 특징

  • 병렬 탐색(parallel search) 을 지원함 -> 모든 항목을 동시에 비교하여 일치하는 페이지 번호를 즉시 찾아냄 (개빠름)

🔄 주소 변환 과정 (p, d)

  • cpu가 (page number, offset) 형태의 논리 주소를 생성할 때:
    1. TLB에서 탐색
    • page number p가 TLB에 있으면 -> 해당 frame number를 바로 꺼냄
      1. TLB에 없으면
    • 메모리상의 페이지 테이블에서 frame number 검색

Effective Access Time (EAT, 유효 접근 시간)

📌 개념

EAT = (hit ratio) x (hit time) + (miss ratio) x (miss time)

  • Hit ratio: TLB에서 지원하는 페이지 번호를 찾아내는 비율

Memory Protection

✅ 보호 비트 (Protection Bit)

  • 각 프레임마다 보호 비트를 설정하여 -> 해당 페이지가 읽기 전용 (read-only) -> read-write 가 가능한지를 명시 더 나아가 execute-only 비트도 추가하여 지정 가

✅ 유효/무효 비트 (Valid / Invalid Bit)

  • 패이지 테이블의 각 엔트리마다 설정되는 비트 | 비트 값 | 의미 | |:-:|:-:| | valid | 이 페이지는 현재 프로세스의 논리 주소 공간에 포함됨 → 사용 가능 | | invalid | 이 페이지는 해당 프로세스가 접근하면 안 됨 → 접근 시 오류 발생 |
  • 또는 전체 크기를 정의하는 PTLR (Page-Table Length Register)를 사용하여 접근 가능한 범위를 지정할 수도 있음.

⛔ 위반 시 동작

  • 잘못된 페이지 접근
  • 쓰기 금지된 페이지에 쓰기 시도 -> 커널로 trap 발생 -> OS가 처리 (segmentation fault)

Valid or Invalid Bit in A Page Table

📌 상황 설정

  • 14비트 주소 공간 사용 (-> 최대 주소: 2^14 = 16,384)
  • 페이지 크기 = 2KB = 2 ^ 11 2^14 / 2^11 = 2^3 = 8 page 사용 가능

어떤 프로그램이 0 ~ 10468 주소까지만 사용함 -> 약 5페이지 분량 프로그램은 실제로 page 0 ~ page 4까지만 유효하게 사용 📌 문제점

  • 프로그램은 실제로 page 0 ~ page 4까지만 유효하게 사용 → 나머지 page 5 ~ 7은 논리 주소 공간에는 포함되지만, 실질적으로는 아무 데이터도 없음 (내부 단편화)

🛡️ 해결책: Valid / Invalid Bit 사용

  • page 0 ~ 4: valid
  • page 5 ~ 7: invalid 로 마킹 -> 누군가 page6 접근이 invalid 접근으로 trap 발생

대안: PTLR (Page Table Length Register)

  • PTLR = 5로 설정하면 -> page table lookup 자체가 0 ~ 4까지만 허용됨 -> 더 이상 valid/invalid 비트 없이도 보호 가능

Shared Code

  • 여러 프로세스가 동일한 읽기 전용 코드를 공유
  • 이 코드는 재진입 가능 해야함 -> 동시에 여러 프로세스가 실행해도 안전한 코드
  • example: 텍스트 편집기, 컴파일러, 공유 라이브러리 등
  • 특징:
    • 스레드가 같은 주소 공간을 공유 것과 유사
    • 읽기/쓰기 허용 페이지의 공유가 가능하다면 -> IPC 으로도 활용 가능
  • 어떤 OS는 shared page를 통해 shared memory IPC를 구현하기도 함

Private Code and Data

  • 각 프로세스마다 고유한 사본을 가짐 -> 즉, 독립적인 코드와 데이

Structure of the Page Table

page table이 너무 커짐 example)

  • 주소 공간 크기: 2^32 = 4GB
  • page 크기: 2^12 = 4KB
  • 필용한 페이지 수: 2^32 / 2^12 = 2^20

📌 페이지 테이블 크기 계산

  • 각 엔트리 = 4바이트일 때: 4bytes x 2^20 = 4MB -> 이렇게 큰 테이블을 물리 메모리에 연속적으로 배치하기 어려움

✅ 해결책: 페이지 테이블을 나누자!

📌 대표적인 구조들:

  1. Hierarchical Paging (다단계 페이지 테이블)
  2. Hashed Page Tables (해시 기반 테이블)
  3. Inverted Page Tables (역방향 페이지 테이블)

Hierarchical Paging Tables

  • 논리주소를 여러개의 페이지 테이블로 분리하여 사용한다.
  • 간단한 방법은 2단계 페이지 테이블을 사용하는 것이다.

Two-Level Paging Example

📌 예시 논리 주소 (32bit 체계 4kb page size)

  • page number = 20 bits
    • outer page table = 10bit
    • inner page table = 10bit
  • page offset = 12 bits

🧮 주소 변환 과정 예시

  1. 논리 주소: p₁ p₂ d 로 구성됨
  2. p₁: 외부 테이블에서 적절한 내부 페이지 테이블을 찾음
  3. p₂: 내부 테이블에서 실제 프레임 번호를 찾음
  4. d: 최종 물리 주소에서 프레임 안의 오프셋

    outer table → inner table → memory frame + offset

64-bit Logical Address Space

2계층 페이징은 64bit 체계에서 적합하지 않다. 왜냐하면, page size = 4kb 이면 2 ^ 52 엔트리가 페이지 테이블에 필요하기 때문이다. 이걸 2계층을 나누면 (inner page tables = 2^10) outer page = 2^ 42 가 된다. 이러면 존재하는 메모리의 크기를 넘어가게 된다.

64bit 아키텍처에서 계층적 페이지 테이블을 사용하는 것은 계층이 늘어나서 여려움이 따른다.
Intel x86-64의 경우 64bit 중 48bit만 논리 주소로 사용하고 4계층 페이지 테이블을 사용한다.

Hashed Page Tables

  • 일반적으로 32bits 주소 공간에서 사용
  • 가상 페이지 번호를 해시 함수에 넣어 페이지 테이블의 위치를 찾음
    • 같은 위치로 해시된 요소들을 체인 형태로 저장

각 요소의 구성

  1. 가상 페이지 번호
  2. 매핑된 물리 프레임 번호
  3. 다음 요소를 가리키는 포인터

페이지 매칭 과정

  • 가상 페이지 번호를 해시하여 체인의 시작 지점을 찾고,
  • 그 체인에서 번호를 일일이 비교하여 일치하는 항목을 찾음
    • 일치하면 해야하는 물리 프레임 번호를 반환함

64비트 주소를 위한 변형: Clustered Page Tables (군집 페이지 테이블)

  • 해시 방식과 비슷하지만, 하나의 항목이 여러 페이지를 한 번에 다룸
  • 희소한 주소공간에서 특히 유용
    • 메모리 참조가 비연속적이고 흩어져 있는 경우에 적합함

      Inverted Page Table

      프로세스마다 페이지 테이블을 가지지 않고, 물리적 페이지를 기준으로 관리하는 방법

✅ 특징 및 작동 방식

  • 각 프로세스가 자신의 페이지 테이블을 가지는 대신 -> 모든 물리적 페이지에 대한 정보를 추적함 (track all physical pages)
  • 물리적 메모리의 실제 페이지마다 하나의 엔트리를 가짐 -> 즉, “실제 메모리 1페이지 <—> 가상주소 + 소유한 프로세스 정보”
  • 각 엔트리 구성
    1. 가상 주소 (그 물리 메모리 공간에 어떤 논리 주소가 매칭됐는지)
    2. 그 페이지를 사용하는 프로세스 정보 ✅ 장점과 단점
  • 장점:
    • 각 프로세스마다 별도 테이블을 만들지 않으므로 -> 전체적으로 메모리 사용량이 감소함
  • 단점:
    • 페이지 참조 시, 해당 가상 주소를 차지 위해 전체를 검색해야 하므로 느려짐
    • 따라서 검색 속도는 느려지고, 시간이 더 걸림
    • 또한, 하나의 물리적 주소에 하나의 가상 주소만 매칭되기 때문에, 공유 메모리 구현이 어려움 해결방안
    • 해시 테이블 사용 -> 해당 가상 주소가 있는지 빠르게 찾아서 검색 시간을 줄임 -> TLB를 활용해 접근 속도 향상 가능

      Swapping

      ✅ 개념

  • 프로세스가 메모리에서 Backing Store로 일시적으로 이동 되었다가, 다시 메모리로 불러와져서 실행되는 방식
  • 이를 통해 프로세스 전체 메모리 요구량 > 실제 물리 메모리 인 상황헤서도 실행 가

✅ 구성 요소 및 방식

  • Backing Store
    • 빠른 디스크
    • 모든 프로세스의 메모리 이미지를 저장할 수 있을 만큼 커야 함
    • 운영체제가 직접 접근할 수 있어야 함
  • Roll out, Roll in
    • 우선순위 스케줄링에서 사용
    • 우선순위 낮은 프로세스를 내보내고, 우선순위 높은 프로세스를 불러와서 실행함

✅ 성능 요소

  • 스와핑에서 가장 많은 시간을 차지하는 건 transfer time
    • 전송시간은 스와칭되는 메모리 크기에 비례
  • 운영체제는 디스크에 메모리 이미지가 있는 ready queue를 유지함 -> CPU가 쓸 수 있도록 메모리로 가져올 준비가 된 프로세스 목
용어 설명
Standard Swapping 프로세스 전체를 디스크로 내보내고 다시 불러오는 전통적 방식
Swapping 일반적으로 Standard Swapping을 의미
Paging 페이지 단위로 스와핑하는 방식 (→ 더 효율적, 세밀한 제어 가능)

🔷 스와핑된 프로세스는 반드시 같은 물리 주소로 돌아가야 하나? -> 항상 그런것은 아님!

  • 주소 바인딩 방식에 따라 달라짐
  • 또한 I/O 작업 중인 버퍼 같은 경우에는 물리 주소가 고정되야 할 수 있음 -> I/O 동작과 연관된 주소는 변경되면 안

🔷 스와핑의 활용 (Linux, Windows 등)

  • 대부분의 시스템에서 swapping은 기본적으로 꺼져 있음
  • 시스템의 메모리 사용량이 임계치를 초과혐ㄴ 시작됨
  • 메모리 수요가 다시 감소하면 Swapping은 다시 비활성화 됨.

Context Switch Time including Swapping

🔷 문맥 교환 시 스와핑이 필요한 경우

  • 다음에 CPU에 올라갈 프로세스가 메모리에 없다면, -> 현재 프로세스를 swap out하고 -> 대상 프로세스를 swap in해야 함
  • 이런 경우, context switch 시간이 매우 커질 수 있음.

스와핑에 필요한 실제 메모리 용량을 OS에 알려주면 불필요한 스와핑을 줄일 수 있다.

🔷 스와핑 시 추가 제약 조건 (Constraints) Pending I/O

  • I/O 작업이 아직 끝나지 않았다면, 스와핑할 수 없음
    • 왜냐하면 I/O가 잘못된 프로세스 메모리에 접근할 위험이 있기 때문
    • 해결 방법: Double Buffering (이중 버퍼링)
      • 항상 I/O를 커널 공간으로 복사한 후, 디바이스로 전송
        • 경로: user buffer <—> system buffer <—> I/O device
      • 장점 : 데이터 안정성 확보
      • 단점 : 오버헤드 증가 🔷 현대 운영체제의 스와핑 방식
  • 표준 스와칭은 현대 OS에서 거의 사용되지 않음
    • 전체 프로세스를 스와핑하는 방식은 비효율적이기 때문
  • 대신, 수정된 방식이 사용됨
    • 남은 메모리가 극도로 적을 때만 스와핑 수

Intel IA-32 Architecture

세그멘테이션과 페이징과 결합된 세그멘테이션 모두 지원

🔷 주요 특징

  • 각 세그먼트는 최대 4GB
  • 하나의 프로세스 당 최대 16K (16384) 세그먼트 사용 가능
  • 이 세그먼트들은 두 파티션으로 나뉘어 있음

🔷 세그먼트 분할 방식

  1. Local Descriptor Table (LDT):
    • 각 프로세스만의 세그먼트 (8K)
    • private 세그먼트들로, 다른 프로세스와 공유되지 않음
  2. Global Descriptor Table (GDT):
    • 모든 프로세스가 공유 하는 세그먼 (또한 최대 8K)
    • OS 커널 코드나 공유 라이브러리 등이 여기에 위치 가

      LTD, GTD의 각 엔트리는 8 바이트 segment descriptor로 구성,
      여기에는 segment의 base location과 limit 정보가 포함됨

주소 변환 흐름

  1. 논리 주소 (Logical Address) 생성
    • CPU가 생성하는 논리 주소는
      • selector (16bit) : 어떤 세그먼트를 참조할지 결정
      • offset (32bit) : 해당 세그먼트 내부의 위치
  2. 세그멘테이션 유닛으로 selector 전달
    • selector는 세그멘테이션 유닛에 전달되어, 세그먼트의 base address를 가져옴 -> 이를 offset과 더해 linear address 생
    • selector 구조 | s (13비트: 세그먼트 번호) | g (1비트: LDT/GDT 선택) | p (2비트: protection level) |
  3. 페이징 유닛으로 선형주소 전달
    • 생성된 선형 주소는 페이지 유닛에 전달됨
    • 페이징 유닛은 해당 주소를 물리 주소로 변환

      💡 페이징 유닛은 MMU(Memory Management Unit) 역할을 수행함

    • 페이지 크기 : 4kb or 4mb
This post is licensed under CC BY 4.0 by the author.