[UEFI] SEC 및 PEI 단계

2026. 1. 2. 21:42·CS/Graduation project

https://github.com/tianocore/tianocore.github.io/wiki/UEFI-EDKII-Learning-Dev

 

UEFI EDKII Learning Dev

Tianocore website. Contribute to tianocore/tianocore.github.io development by creating an account on GitHub.

github.com

1강의 내용을 정리한다.


SEC 단계

 

SEC(Security) 단계는 플랫폼 초기화의 최초 단계로, 플랫폼 리셋 또는 전원 켜기 후 펌웨어 무결성을 검증하기 위해 수행된다. SEC는 플랫폼 및 프로세서 아키텍처에 따라 달라진다.

 

SEC 단계는 최소한의 코드로 구성되며, 초기화되지 않은 메모리 환경 특성상 C 언어 스택을 사용할 수 없으므로 특정 프로세서 아키텍처에 맞는 어셈블리어로 작성된다. 또한 코드는 플래시 메모리에서 직접 실행되는 구조이므로 압축되지 않은 상태여야 한다. 모든 실행 흐름은 리셋 벡터에서 시작된다.

 

SEC의 주요 역할

  1. 플랫폼 재시작(Restart): SEC는 모든 플랫폼 재시작 이벤트를 처리한다.
  2. 임시 메모리 초기화: SEC는 메인 메모리(RAM)를 사용할 수 없는 단계에서 스택으로 활용할 임시 메모리 저장소를 준비한다.
  3. 신뢰점(Root of Trust) 역할: SEC는 시스템 제어권을 가장 먼저 획득하는 초기 코드로써 신뢰점 역할을 수행하며, 필요 시 PEI 파운데이션을 인증한다.
  4. 제어권 이양: SEC는 초기화 완료 후 제어권을 다음 단계인 PEI 파운데이션으로 넘긴다.

 


PEI FOUNDATION

 

 

PEI란?

PEI는 플랫폼 초기화의 두 번째 단계다. 이 단계의 목표는 메모리 및 기타 플랫폼 리소스를 초기화하여, 다음 단계인 드라이버 실행 환경(DXE)이 C 언어 환경에서 안정적으로 실행될 수 있도록 준비하는 것이다.

 

- 리셋 처리: PEI(및 SEC)는 리셋, INIT, 그리고 머신 체크 아키텍처(MCA) 신호를 처리한다. (과거 Itanium 프로세서 환경에서는 리셋 신호가 펌웨어를 호출하는 프로세서 추상화 계층(PAL)으로 전달되었다.) 부팅 진입점에는 프로세서 리셋을 수행하는 INIT 과정이 포함된다.

 

- 초기 구동: PEI 단계는 ROM에서 직접 실행(Execute In Place)되므로, 작고 효율적인 시작 코드로 구성된다. 빌드 도구를 통해 모듈형 드라이버들이 절대 주소에 배치되는데, 이 주소들은 빌드 시점에 이미 확정되므로 별도의 로딩 과정 없이 바로 실행된다.

 

- 아키텍처 지원: PEI는 최신 인텔 아키텍처 프로세서의 기능을 활용하여, 리셋 직후 더 빠른 시점에 C 언어 환경을 사용할 수 있게 해준다. C 언어는 스택을 필요로 하므로, 아직 초기화되지 않은 메인 메모리 대신 사용 가능한 임시 메모리 (예: Cache-as-RAM)를 마련한다.

 

- 모듈 관리: PEI 코어는 PEI 모듈(PEIM)을 찾아내고, 검증하며, 실행 순서를 관리하여 구동한다. PEIM은 PEI 단계에서 실행되는 칩셋이나 플랫폼 기능 지원용 펌웨어 코드의 모듈화된 단위다.

 

- 인터페이스 게시: PEI는 PEIM 간 인터페이스인 PPI(PEIM-to-PEIM Interface)를 통해 자체적인 프로토콜과 함수 호출 방식(Call-abstraction)을 외부에 공개하여 다른 모듈이 사용할 수 있게 한다.

 

- 최종 목표: PEI의 주요 목표는 부팅 모드를 감지하고, 메인 메모리 초기화 모듈을 실행하며, 이후 DXE 코어를 찾아 실행하고 플랫폼 정보를 DXE로 넘겨주는 것이다.

 

 

 

 

왜 PEI인가?

1. 개발 난이도와 호환성 문제 해결: 메모리가 가용하지 않은 상태에서 코드를 작성하는 것은 본질적으로 매우 어렵다. 특히 레거시 BIOS 환경에서는 코드가 서로 다른 레지스터 규칙에 따라 어셈블리어로 수작업 코딩되었다. 벤더마다 정보를 저장하기 위해 사용하는 IA32 레지스터가 제각각이었기 때문이다. 예를 들어, 어떤 벤더는 데이터 보관을 위해 EBP 레지스터를 쓰고, 다른 벤더는 EBX를 사용하는 식이다. 이러한 비표준화된 환경은 코드의 상호 운용성을 떨어뜨리고, 플랫폼 간 이식을 매우 어렵게 만들었다. PEI는 이러한 난립된 어셈블리 환경을 표준화된 구조로 대체하기 위해 도입되었다.

 

2. 초기화 경로 최적화 및 특수 부팅 지원: PEI가 필요한 또 다른 이유는 메모리 및 필수 칩셋 초기화를 수행하는 가장 빠르고 효율적인 경로를 확보하기 위함이다. 또한, PEI는 일반 부팅뿐만 아니라 S3(Suspend-to-RAM) 절전 모드 복귀, 일반적인 대기 모드 해제(Resume from Sleep), 그리고 펌웨어 복구와 같은 특수 부팅 시나리오에서 핵심적인 초기화 역할을 수행한다

 

 

 

 

Intel® "Green H"의 의미

 

인텔 Green H 하단의 SEC(보안) 및 PEI 단계에서 시작해 상단의 운영 체제로 제어권이 이양되는 부팅 흐름을 구조적으로 시각화한 것이다.

 

Green H 구조의 하단부를 구성하는 SEC와 PEI 단계는 의도적으로 작고 간결하게 설계되었다. 이 영역은 하드웨어에 깊게 종속된 기계어(또는 어셈블리어)로 작성되어 타 플랫폼으로의 이식이 본질적으로 어렵기 때문이다. 즉, 이식성이 낮은 코드의 비중을 줄이는 것이 해당 단계의 규모를 최소화해야 하는 핵심 이유다

 

 

 

 

PEI 개요

- 기능 

  • 메인 메모리를 검색하고 초기화한다. (초기화 후, 임시 메모리의 데이터를 메인 메모리로 이전하는 작업 포함)
  • DXE 코어 및 아키텍처 프로토콜(AP)을 포함하고 있는 펌웨어 볼륨의 위치를 파악하고 기술한다.
  • PEI 단계에서만 식별 가능한 기타 플랫폼 고유의 리소스들을 기술한다.

 

- 구성 요소

  • 바이너리: PEI 코어 및 PEI 모듈로 구성된다. 이들은 제자리 실행(XIP) 코드/데이터, 재배치 정보, 인증 정보를 포함하는 표준 헤더 형식을 따른다.
  • 인터페이스: PEIM 간 통신을 위한 메커니즘으로, 핵심 서비스(PEI Services), PEIM 간 인터페이스(PPI), 그리고 알림으로 구성된다. (PEI 단계에는 별도의 타이머 서비스가 존재하지 않는다.)
  • 정의: PEIM은 PEI 단계에서 실행되며, 칩셋 또는 플랫폼 기능을 지원하는 모듈화된 펌웨어 코드 단위다.

 

- 환경 

  • 스택 등으로 활용하기 위해 소량의 임시 RAM을 사용한다.
  • 별도의 로딩 과정 없이 ROM에서 직접 실행된다.

 

 

 

 

PEI의 초기 메모리

PEI 코어가 작동하기 위한 최소 요구 사항은 소량의 임시 메모리를 확보하는 것이다. 필요한 메모리 양은 프로세서와 칩셋에 따라 다르나, IA32 샘플 구현의 경우 약 8KB가 요구된다. (8KB 는 최소 사양 예시, 현대 시스템 기준은 아님)

 

임시 RAM은 인텔 프로세서의 캐시 교체 금지 기술을 활용해 확보된다. 이는 캐시 내용을 메모리로 내보내지 않도록 설정하여, CPU 캐시를 마치 시스템 RAM처럼 활용하는 Cache-as-RAM(CAR) 환경을 구현하는 것이다.

 

IA32 인텔 프로세서의 주요 특징 중 하나가 바로 이 Cache-as-RAM(CAR) 기술이다. CAR 영역은 스택과 같은 데이터 저장 용도로만 사용되며, 실제 코드 실행은 여전히 플래시 메모리에서 직접 이루어진다. 임시 RAM 확보의 가장 큰 이점은, C 언어 기반 환경을 조기에 구축함으로써 IA32와 IPF(Itanium) 프로세서 기반 시스템 간에 상당 부분의 공통 코드를 공유할 수 있게 해준다는 점이다.

 

 

 

 

Memory Map

메모리 맵은 메모리 공간의 구성 요소와 그 배치를 정의한 레이아웃이다. 아래 그림은 인텔 IA-32 아키텍처의 메모리 맵 예시이다.

- BFV(s): 가장 먼저 실행되는 PEI 코드(SEC 및 PEI Core)가 저장된 영역이다

 

- FV(s): 펌웨어 데이터 및 코드를 파일 시스템 형태로 조직화한 논리적 저장소다. 각 펌웨어 볼륨은 UEFI PI 사양 제3권에 정의된 속성 및 형식을 따른다.

 

- T-RAM: 시스템 메모리(DRAM)가 초기화되기 이전 단계에서, 스택 및 초기 데이터 저장을 위해 사용되는 임시 메모리 공간이다. (앞서 언급한 Cache-as-RAM이 이 공간에 해당한다.)

 

- System Memory: PEI 단계에서 메모리 초기화 모듈(MRC)을 통해 감지되고 초기화되는 메인 메모리 영역(DRAM)을 의미한다.

 

 

 

 

PEI CORE

특성 

  • PEI는 부트 펌웨어 볼륨(BFV)에 위치한다.
  • 주로 C 언어로 작성되지만, 성능 최적화를 위해 일부 어셈블리 언어가 사용된다.
  • PEI는 명확하게 명세화되어 있으며 검증되었다.

구성 요소

  • 코어 디스패처 (Core Dispatcher)
    • PEI 모듈(PEIM)을 탐색한다.
    • 예측 가능하고 유용한 순서로 모듈을 실행한다.
  • PEI 서비스: 모든 PEIM에서 유용하게 사용할 수 있는 PEI 공통 함수들을 제공한다.

 

 

PEI CORE CODE

PeiMain은 SEC 단계에서 PEI 단계로 전환될 때 실행되는 주요 코어 소스 코드 모듈이다. 이 모듈의 Entry Point는 PeiCore다.

 

오픈 소스 트리에서의 위치는 다음과 같다.

  • EDK I: \\Foundation\\Core\\Pei\\PeiMain
  • EDK II: \\MdeModulePkg\\Core\\Pei\\PeiMain

다음은 PEIMAIN 소스 코드의 예시다.

 

SecCoreData: 코어의 데이터 영역을 초기화하는 데 사용되는 이전 코어 데이터(Old Core Data)를 가리킨다. 이 값이 NULL이라면, 최초로 진입한 PeiCore임을 의미한다.

 

PpiList:

  • PEI 코어가 초기화 시점에 설치해야 할 하나 이상의 PPI 디스크립터 목록을 가리킨다. 빈 PPI 목록은 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST 종료 태그가 포함된 단일 디스크립터로 구성된다.
  • 초기화 과정에서, PEI 파운데이션은 이 SEC 단계에서 생성된 PPI들을 PPI 데이터베이스에 등록한다. 이를 통해 PEI 파운데이션과 모든 모듈이 해당 초기 PPI가 제공하는 서비스 및 코드를 활용할 수 있게 된다.

Data: 임시 RAM의 크기와 위치, 스택 위치, 그리고 BFV 위치 등 PEI 코어의 운영 환경 정보를 담고 있는 데이터 구조체를 가리킨다.

 

 

 

 

PEI PHASE FLOW

1단계: 리셋 및 SEC에서 PEI로의 전환

시스템 리셋 후 SEC 단계가 끝나면, PeiMain을 통해 PEI 단계의 시작점인 PeiCore가 실행된다. 이때 SEC는 초기화 작업을 넘기면서 다음 3가지 핵심 데이터를 PeiCore에 함께 전달한다.

  • SecCoreData (Old Core Data): 이전 코어 데이터를 말하며, 이 값이 NULL이면 시스템이 처음 켜진 상태라는 뜻이다.
  • Data (Hand-Off Information): 현재 사용 중인 임시 RAM(CAR)의 위치와 크기, 스택 위치, 그리고 부트 펌웨어 볼륨의 위치 정보가 담겨 있다.
  • PpiList: SEC 단계에서 미리 만들어둔 초기 PPI 목록이다. PEI 파운데이션은 이 목록을 데이터베이스에 등록해서, 이후에 실행될 모듈들이 바로 사용할 수 있게 한다.

 

2단계: PEI 코어 초기화 및 서비스 구축

PeiCore는 부트 펌웨어 볼륨 안에 있는 상태로 실행된다. 가장 먼저 하는 일은 모든 PEIM이 공통으로 쓸 수 있는 PEI 서비스를 만드는 것이다.

  • 주요 서비스
    • PPI 데이터베이스: 모듈끼리 통신할 수 있는 인터페이스를 관리한다.
    • 부트 모드: 지금이 정상 부팅인지, 복구 모드인지 등을 결정한다.
    • 메모리 서비스 및 HOB: 메모리 할당을 돕고, 다음 단계(DXE)로 넘겨줄 데이터 블록(HOB)을 관리한다.

 

3단계: 코어 디스패처와 PEIM 실행

이제 코어 디스패처가 작동해서 펌웨어 볼륨 안에 있는 PEI 모듈(PEIM)들을 찾아낸다. 디스패처는 모듈 간의 관계를 파악해 정해진 순서대로 하나씩 모듈을 실행한다. 각 모듈은 실행되면서 자신의 PPI를 등록하거나, 다른 모듈의 PPI를 가져와서 필요한 기능을 수행한다.

 

4단계: 메모리 초기화 및 스택 전환 (Switch Stacks)

처음에는 임시 RAM(캐시)을 스택으로 사용하지만, 메모리 초기화 모듈이 실제 시스템 메모리(DRAM)를 찾아내면 스택 전환 과정을 거친다. 이때 임시 RAM에 있던 데이터와 스택을 실제 시스템 메모리로 그대로 옮겨서, 더 넓고 안정적인 작업 공간을 확보한다.

 

5단계: DXE IPL을 통한 단계 종료

필요한 모듈이 모두 실행되면 마지막으로 DXE IPL 모듈이 호출된다. 이 모듈은 PEI 단계에서 만든 시스템 정보 덩어리인 HOB 리스트를 정리해서 DXE 코어에 넘겨주고, 시스템의 제어권을 DXE 단계로 완전히 넘기면서 PEI 단계를 마친다.

 

 

 

 

PEI CORE SERVICE

1. PPI (PEIM-to-PEIM Interface)

  • PEIM 간의 통신 인터페이스(PPI)를 관리하여, 모듈끼리 서로의 기능을 호출하고 사용할 수 있게 한다. 인터페이스 정보는 임시 RAM(T-RAM)에 위치한 데이터베이스에 등록되고 관리된다.

2. 부트 모드 (Boot Mode)

  • 현재 시스템의 부팅 경로를 관리하고 식별한다. 대표적인 모드로 S3(절전 모드 복귀), 복구(Recovery), 일반 부팅(Normal Boot), 진단(Diagnostics) 등이 있다. (S5는 일반적으로 전원 종료 상태를 의미하며, 부팅 시에는 콜드 부팅 경로로 처리된다.)

3. HOB (Hand-Off Blocks)

  • 핸드오프 블록(HOB)을 생성하고 관리하는 서비스를 제공한다. 이는 PI 아키텍처의 다음 단계인 DXE로 시스템 정보를 전달하는 표준 메커니즘으로 사용된다.

4. 펌웨어 볼륨 (Firmware Volume, FV)

  • 펌웨어 파일 시스템(FFS) 형식을 처리하여, 플래시 메모리 장치 안에 저장된 PEIM 파일이나 기타 펌웨어 데이터를 탐색하고 읽을 수 있도록 돕는다.

5. PEI 메모리 (PEI Memory)

  • 메인 메모리가 초기화되기 전(임시 RAM 단계)과 후(DRAM 단계), 어느 시점에서든 사용할 수 있는 일관된 메모리 할당 및 관리 서비스를 제공한다.

6. 상태 코드 (Status Code)

  • 시스템의 진행 상황 및 오류 코드를 보고하는 공통 기능을 제공한다. 예를 들어, 포트 80h(Port 80h) 하드웨어에 디버그 코드를 출력하거나, 시리얼 포트로 로그 메시지를 전송할 때 사용된다.

7. 리셋 (Reset): 시스템을 Warm Restart 또는 Cold Restart 하기 위한 표준화된 함수를 제공한다.

 

 

 

 

PEI Services Functions

  • 생성: PEI 파운데이션은 PEI 서비스 테이블을 생성한다.
  • 공개: 이 테이블은 시스템 내의 모든 PEI 모듈(PEIM)에 공개된다. 따라서 어떤 모듈이든 이 테이블을 통해 필요한 서비스를 이용할 수 있다.
  • 서비스의 범위: PEI 단계는 메모리 자원이 부족한 환경이기 때문에, 생성되는 서비스의 범위도 꼭 필요한 기능들로 제한된다.
  • 전달: 이 테이블을 가리키는 포인터는 각 PEI 모듈(PEIM)이 시작될 때(진입점), 그리고 모듈 간 인터페이스(PPI)가 호출될 때 함께 전달된다.
  • 내용 및 위치: PEI 서비스 테이블에는 InstallPpi나 GetBootMode 같은 함수 포인터 목록이 들어 있다. 이 테이블은 물리적으로 메모리(RAM)에 위치하며, 초기화 단계에 따라 ROM의 코드를 가리킨다

 

 

 

 

PEIM의 특징

  • PEIM은 독립적으로 실행 가능한 객체(단위)다.
  • 개별적으로 빌드된, 압축되지 않은 바이너리 이미지로 구성된다.
  • FV 내의 파일(FFS) 형태로 포함된다.
  • 탐색 메커니즘이 지원된다면, 단일 FV뿐만 아니라 여러 FV에 나누어 상주할 수 있다.
  • PEIM은 메모리로 복사되지 않고, 플래시 장치에 저장된 위치에서 바로 실행된다.
  • PEIM 간 인터페이스(PPI)를 정의하고 설치하여, 다른 PEIM이 사용할 수 있는 기능을 제공한다.
  • 자신이 실행되기 위해 필요한 PPI가 무엇인지 명시하여, 해당 요구 사항을 설명한다(의존성 표현).

 

 

PEIM Layout

PEIM의 레이아웃은 필수 구성 요소와 선택 가능한 구성 요소들로 이루어진다.

  • PE32는 PE/COFF 이미지이며, C 컴파일러로 컴파일하고 링커를 통해 링크될 때 생성된다
  • DEPEX는 종속성 표현이며, 해당 드라이버가 실행되기 전 충족되어야 할 조건을 기술한 데이터다.

 

 

PPI 인터페이스

시스템 내에서 생성되어 다른 PEIM들이 사용할 수 있는 PPI는 크게 두 가지 유형으로 나뉜다.

 

1. 아키텍처 PPI (Architectural PPI)

  • 이 PPI의 전역 고유 식별자(GUID)는 PEI 파운데이션에 이미 알려져 있다.
  • ReportStatusCode()와 같이 플랫폼마다 구현 방식이 달라질 수 있는 기능에 대해, PEI 파운데이션이 사용할 수 있는 공통된 인터페이스를 제공한다.

2. 추가 PPI (Additional PPI)

  • 모듈 간의 상호 운용성에는 중요하지만, PEI 파운데이션이 실행되는 데 필수적으로 의존하지는 않는 PPI다.
  • 이러한 PPI를 등록하거나 사용하기 위해서는 InstallPpi(), ReinstallPpi(), LocatePpi(), NotifyPpi()와 같은 PEI 서비스가 필요하다.

PPI는 현재 사용 가능한 모든 PPI 목록을 담고 있는 PPI 데이터베이스를 통해 관리된다. 이 데이터베이스의 내용은 LocatePpi(), InstallPpi(), NotifyPpi(), ReinstallPpi() 인터페이스를 사용하여 조회하거나 변경 할 수 있다.

 

SOURCE CODE

이름으로 볼륨 내의 파일을 찾는 C 소스 코드 FwVol.C의 예시

 

 

 

 

PEI CORE DISPATCHER

PEI 디스패처는 PEIM을 검색하고 실행하는 역할을 담당하는 PEI 코어의 일부이다.

 

속성

  • 실행 조건이 갖춰지면 PEIM에게 제어권을 넘겨 실행한다.
  • 모든 펌웨어 볼륨을 탐색하여, 그 안에 포함된 각 PEIM 파일들을 찾아낸다.
  • 파일들의 실행 순서를 정하기 위해 의존성 표현식(Dependency Expression)을 검사한다.
  • DEPEX: 의존성 표현식을 의미하며, 해당 드라이버(PEIM)가 실행되기 위해 미리 충족되어야 할 조건(의존성)들을 기술해 놓은 데이터다.

 

 

 

 

DISPATCH MODEL

PEI 코어는 PEIM의 실행 순서(디스패치 스케줄링)를 결정하기 위해 두 가지 조건을 확인한다. 코어가 이 두 조건이 모두 충족되었다고 판단하면, 해당 PEIM의 엔트리 포인트를 실행한다.

 

1. 의존성 알고리즘이 참으로 평가되는가?

  • 이를 확인하기 위해, BNF 기반의 DEPEX 알고리즘을 사용한다.
  • 이때 DEPEX 규칙은 실행 순서에 있어 절대적인 순서가 아닌 약한 순서(Weak Ordering)를 생성한다는 점에 유의해야 한다

2. 파일 인증 상태가 참인가?

  • 파일의 인증 여부를 확인하기 위해, 원본 장비 제조업체(OEM)가 제공한 알고리즘이나 플랫폼 정책을 적용한다.

*. BNF

  • ::= 의미: "~로 정의됨"
  • | 의미: "또는"
  • < > 카테고리 이름을 둘러싸는 데 사용되는 꺾쇠 괄호

 

 

 

 

DISPATCHING PEIMS

PEI 코어는 다음 기준들을 지침으로 삼아 특정 PEIM을 실행할지 여부를 결정한다.

 

PEIM 실행 조건

  1. 동일한 패스에서 아직 실행된 적이 없어야 한다.
  2. DEPEX 내의 GUID가 PPI 데이터베이스에 존재해야 한다. (즉 필요한 의존성이 이미 실행되었거나, 해당 DEPEX 조건이 참이어야 함)
  3. 인증 섹션이 존재하는 경우, 인증이 완료되어야 한다.

다중 FV(Firmware Volume) 디스패칭의 경우 다음 내용이 추가.

  • PEIM은 다른 FV가 어디에 있는지 알려줘야 한다. 이때 코어는 아키텍처적으로 지정된 FindFv PPI를 사용한다.
  • 새로운 FV가 발견되면, 해당 FV는 코어 알고리즘의 검색 순서에 추가된다.

 

 

PEI 디스패처 코드 위치

바로 위는 PEI의 메인 디스패치 루프가 실행되는 영역이다. 알려진 FV들을 검색하여 PEIM을 찾아내고, 조건이 맞으면 실행을 시도한다.

 

디스패처는 해당 드라이버의 PEIM 엔트리 포인트를 호출한다. 빨간색으로 표시된 코드는 대략 807행으로, PEIM이 디스패치되는 지점이다. 또한 이 위치는 PEIM이 실행되는 정확한 시점이므로, 디버깅 목적으로 Break Point을 설정하기에 가장 적합한 장소다

 

 

 

 

PEI HOBs

Hand-off Blocks(HOBs)는 메모리에 존재하는 데이터 구조들의 집합이다. 플랫폼의 특징, 구성 정보, 데이터 등을 기술하며 PEI 단계에서 생성되고 DXE 단계에서는 읽기 전용으로 사용된다.

  • PEI 단계와 DXE 단계 사이를 연결하는 역할을 한다. PEI는 시스템 자원 정보를 HOB 안에 수집한다.
  • HOB의 데이터 구조는 PI 사양에 정의되어 있으며, 각 HOB는 유형과 길이 등의 속성을 가진다.
  • PEI는 HOB를 생성하여 DXE가 사용할 수 있도록 시스템 메모리에 저장한다. 이때 HOB가 저장되는 메모리 공간은 일반적으로 연속적이다.
  • DXE는 시작될 때 HOB를 읽어 들인다. HOB 내부의 포인터들은 FV, 물리적 메모리 속성, 또는 PEIM이 할당한 특정 메모리와 같이 이동할 수 없는 물리적 자원들을 기술한다.

 

 

 

 

HOB LISTS

HOB 리스트는 메모리 내에 순차적으로 나열된 HOB들의 목록이다. PEIM은 DXE 코어를 호출할 때, 이 HOB 리스트를 DXE 코어에 전달한다.

 

Required HOBs

  • 리소스 디스크립터 (Resource Descriptor): DXE 코어가 사용할 물리적 시스템 메모리 정보를 기술한다.
  • PEI 핸드오프 정보 테이블 (PEI Hand-off Information Table): HOB 리스트의 시작점을 가리킨다.
  • BSP 스택: DXE 코어에게 현재 스택의 위치를 알려준다. DXE 코어는 이 정보를 바탕으로, 희망하는 메모리 맵 구성에 따라 필요하다면 스택을 다른 위치로 이동시킨다.

Optional HOBs

  • Firmware Volume: DXE 코어가 플랫폼 내의 다른 드라이버들을 로드하기 시작할 때 필요한 정보다.
  • GUIDed: 미리 정의된 표준 형식에 맞지 않는 기타 데이터들을 담는 저장소다. PEI에서 DXE 단계로 특정 정보를 전달할 때 사용한다.
  • CPU: 프로세서 실행 코드(Producer Phase)에 의해 생성된다. 주소 공간 및 I/O 공간 기능과 같은 프로세서 정보를 기술한다.

 

 

 

PEI 영구 메모리 이전 환경 (PEI PRE-PERMANENT MEMORY ENVIRONMENT)

PEI 영구 메모리 이전 환경에는 몇 가지 속성이 있다.

  • 목적: 이 환경의 주된 목적은 시스템 메모리를 초기화하는 것이다.
  • 모델: 시스템은 32비트 보호 모드(Protected Mode)의 플랫 물리 메모리 모델에서 실행된다.
  • 발견: 현재의 부팅 유형을 파악해야 한다. 예를 들어 절전 상태에서의 재개(S3 Resume), 복구(Recovery), 또는 정상 부팅 경로인지를 식별한다.
  • 입력: 진입 시점에 펌웨어 볼륨의 위치와 PEI 서비스 테이블에 대한 정보를 이미 알고 있다.
  • 환경
    • 이 시점에는 아직 실제 시스템 메모리가 없다.따라서 프로세서 캐시를 데이터 저장소 및 메모리 호출 스택으로 사용하여, C 스타일 호출 규약을 사용할 수 있게 한다.
    • 이는 인텔 프로세서 아키텍처의 특징인 Cache-as-RAM 기술이며, No-Eviction Mode 라고도 불린다.
    • 프로세서 아키텍처에 따른 환경적 제약 사항들을 고려해야 한다.

 

 

PEI 영구 메모리 이후 환경 (PEI POST-PERMANENT MEMORY ENVIRONMENT)

마찬가지로 PEI 영구 메모리 이후 환경에는 몇 가지 속성이 있다.

  • 목적: DXE 단계로 전환하고 HOB들을 준비하는 것이 목적이다.
  • 모델: 여전히 32비트 보호 모드(플랫 물리 메모리 모델)에서 실행된다
  • 자원: 이제 스택과 HOB 리스트를 저장할 수 있는 실제 메모리 공간을 확보한 상태다.
  • 입력: 첫 번째 HOB를 가리키는 포인터를 생성한다. 이는 PEI 핸드오프 정보 테이블(PHIT)이라고도 한다.
  • 환경:
    • 시스템 메모리가 확보된 상태에서 여전히 C 스타일 호출 규약을 사용한다.
    • 코드는 펌웨어 볼륨에서 제자리 실행(XIP) 방식으로 동작한다

 

 

COMPLETED PEI MEMORY MAP

전체 개요: PEI Post-Permanent Memory 환경

이 메모리 맵은 초기 CPU 캐시를 메모리처럼 쓰던 단계가 끝나고, 실제 시스템 메모리(DRAM)가 초기화된 직후의 상태를 보여준다.

  • 목적: 이 환경의 핵심 목적은 DXE단계로 넘어가기 위한 준비를 마치고, 시스템 정보를 담은 HOB 리스트를 완성하는 것이다.
  • 실행 상태: CPU는 32비트 보호 모드(Flat Model)에서 작동한다. 코드는 여전히 펌웨어 볼륨에서 제자리 실행되지만, 데이터는 이제 실제 메모리에 저장된다.

 

메모리 맵 상세

메모리 맵은 낮은 주소부터 높은 주소 순으로 다음과 같이 구성되어 있다.

 

A. 스택 영역

  • 이 영역은 PEI Pass 2 Processor Stack이라고 불린다. PEI 단계에서 C언어 기반 코드를 실행하기 위한 필수 작업 공간이다. Pass 2라는 명칭은 임시 메모리(Pass 1)에서 벗어나, 실제 메모리에 새롭게 구축된 스택임을 의미한다.
  • 메모리의 가장 아래쪽인 PHIT -> PeiMemoryBottom 영역에 위치한다.

B. HOB 리스트 (HOB List)

  • PEI 단계에서 수집한 하드웨어 정보들을 DXE 단계로 넘겨주기 위해 블록 형태로 쌓아둔 데이터 구조체들의 집합이다.
    • PHIT (PEI Hand-off Information Table): HOB 리스트의 가장 첫머리에 위치하며, 리스트의 헤더 역할을 한다. 현재 메모리의 사용량이나 여유 공간의 시작(PeiFreeMemoryBottom) 등을 관리하는 포인터 정보를 담고 있다.
    • Resource Descriptor HOB: 시스템에 존재하는 물리적 메모리 리소스 정보를 설명한다.
    • Memory Allocation HOBs: BSP Stack은 메인 프로세서의 스택 정보를, AP Stack은 멀티코어 환경에서 보조 프로세서들의 스택 정보를 담고 있다. 또한 전원 관리(ACPI)를 위해 예약된 메모리 영역도 이곳에 포함된다.
    • FV HOB & GUID Extension HOB: 펌웨어 파일들의 위치를 가리키거나, 벤더 고유의 추가 데이터를 전달할 때 사용된다.
  • 스택 바로 위에 쌓이는 초록색 영역이다.

C. 여유 공간 (Free Space)

  • 초기화와 테스트가 완료되었으나, 아직 사용되지 않은 빈 메모리 공간이다. PEI 단계가 진행되면서 새로운 HOB가 생성되면, 이 영역의 아래쪽부터 차곡차곡 채워진다.
  • PeiFreeMemoryBottom부터 PeiFreeMemoryTop 사이의 주황색 영역이다.

D. 고정 메모리 할당 (Fixed Memory Allocation)

  • 시스템의 가장 높은 주소 공간에 고정적으로 할당되어야 하는 데이터들이다. 보통 다음 단계의 코어인 DXE IPL을 로드하거나, 특정 하드웨어가 요구하는 예약된 메모리 공간으로 사용된다.
  • 메모리의 최상단인 PeiMemoryTop 아래의 회색 및 노란색 영역이다.

 

 

 

 

PEI 종료 조건

1. 디스패치 종료

PEI 코어 단계는 다음의 경우에 종료된 것으로 간주한다.

  • 더 이상 디스패치(실행)할 PEIM이 남아있지 않을 때.
  • PEI 코어가 의존성 목록을 확인하여, 실행 가능한 모든 PEIM들을 처리했을 때.

2. PEI 단계 완료

PEI 단계가 완전히 끝났다고 판단하는 조건은 다음과 같다.

  • PPI가 "메모리가 발견되었고, DXE 코어를 위해 초기화가 완료되었다"는 상태를 알릴 때.
  • 펌웨어 볼륨에서 발견된 모든 PEIM들의 디스패치 과정이 끝났을 때.

마지막 디스패치 작업이 완료되면, PEI 코어는 DXE IPL(Initial Program Load)을 호출한다. DXE IPL은 DXE 코드를 메모리로 옮기는 역할을 하며, 이를 통해 시스템은 DXE 단계로 진입하게 된다.

 

 

 

 

PEI Transitions to DXE

PEI가 DXE로 제어권을 넘기는 과정은 다음과 같다.

  1. PEI 단계가 시작될 시점에는, 어떠한 메모리도 초기화되어 있지 않은 상태다.
  2. PEI 코어는 PEIM들을 디스패치하여 초기화를 수행하고, 그 결과를 HOB 목록에 기록한다.
  3. DXE IPL PEIM이 실행될 시점이 되면, 시스템 정보를 담은 HOB 목록이 완성되어 있다.
  4. 이후 DXE IPL PEIM은 제어권을 DXE 코어로 넘긴다. 일단 DXE 단계로 넘어가면, 더 이상 PEI 단계의 서비스나 PPI에는 접근할 수 없다. DXE 단계로 전달되는 유일한 정보는 HOB 목록뿐이다.

 

 

 

 

DXE Inital Program Load

  • DXE IPL은 PEI와 DXE 사이에서 다음과 같은 핵심적인 목적을 수행한다.
    • 주소가 하드 코딩(고정)되는 것을 방지한다.
    • 가장 큰 물리 메모리 HOB를 찾아낸다. 이 공간은 이상적으로 메모리의 상단(Top) 근처에 위치해야 한다.
    • 확보된 메모리의 상단 영역에 DXE 스택을 할당한다.
    • HOB 목록에 있는 펌웨어 볼륨들을 검색하여 DXE 코어를 찾는다.
    • DXE 코어를 메모리에 로드하고, 이 DXE 코어에 대한 정보를 담은 HOB를 생성한다.
    • 최종적으로 스택을 전환하고, 실행 흐름을 DXE 코어로 넘긴다.

 

 

 

 

Call to DXE IPL Code

DXE IPL은 스택을 전환하고 DxeMain을 호출할 준비를 수행한다. 이때 사용하는 프레임워크가 EDK I인지 EDK II인지에 따라 코드 베이스가 다르다.

 

 

 

 

Alternative Boot paths

PEI 단계가 끝난다고 해서 항상 DXE 단계로만 전환되는 것은 아니다. PEI는 부팅 모드에 따라 DXE가 아닌 대체 부팅 경로로 전환되기도 한다.

 

1. 부팅 모드의 결정

  • PEI 파운데이션 자체는 시스템이 현재 어떤 경로로 부팅해야 하는지 알지 못한다.
  • 대신 개별 PEIM들이 하드웨어 상태를 파악하여 부팅 모드를 결정한다. 이후 시스템은 결정된 모드에 따라 적절한 조치를 취한다.

2. 모드 설정

  • 대체 부팅 경로를 구현하기 위해, 각 PEIM은 SetBootMode()라는 PEI 서비스를 사용한다. PEIM은 이 서비스를 통해 시스템의 부팅 모드를 설정하거나 변경할 수 있다.

3. 디스패치 순서

  • 일반적으로 부팅 모드가 바뀐다고 해서 PEIM들이 디스패치되는 순서 자체가 변경되지는 않는다. 하지만 특정 부팅 모드나 상황에 따라서는 이 순서가 달라질 수도 있다.

1. 일반 부팅 경로 - 녹색

컴퓨터 전원을 처음 켰을 때(Cold Boot)의 과정이다. 이때는 추후 절전 모드에서 깨어날 상황을 대비해 중요한 정보들을 미리 저장해 둔다.

  • PEI 단계: 하드웨어를 초기화하면서 생성된 구성 정보를 비휘발성 저장소(NVS)에 저장한다.
  • DXE 단계: 부팅 과정에서 수행한 초기화 명령들을 부트 스크립트 테이블(Boot Script Table) 형태로 기록하여, ACPI NVS(메모리 영역)에 저장한다.

 

2. S3 복귀 경로 - 파란색

절전 모드(S3) 상태에서 시스템을 깨울 때의 과정이다. 전체 부팅 과정을 거치지 않고 단축된 경로를 사용한다.

  • SEC: 전원이 들어오고 CPU가 초기화된다.
  • PEI (설정 복구): S3를 인지한 PEIM(S3 aware PEIMs)들이 실행된다. 이들은 하드웨어를 다시 검사하는 대신, 앞서 NVS에 저장해 둔 설정값을 회수하여 PEI 단계의 구성을 즉시 복구한다.
  • PEI (스크립트 실행): 부트 스크립트 실행기가 작동한다. 이 모듈은 무거운 DXE 단계를 실행하는 대신, 메모리에 저장된 부트 스크립트를 단순히 실행한다. 이를 통해 DXE 단계의 하드웨어 설정을 빠르게 복원한다.
  • S3 웨이킹 벡터(S3 Waking Vector): 모든 복구가 완료되면, 운영체제가 잠들기 직전에 저장해 둔 복귀 지점으로 점프하여 시스템을 즉시 사용할 수 있게 한다.

'CS > Graduation project' 카테고리의 다른 글

CVE-2023-45230: UEFI DHCPv6 드라이버 힙 오버플로우  (0) 2026.01.19
[UEFI] UEFI DRIVERS  (1) 2026.01.12
[UEFI] Driver Execution Environment (DXE)  (0) 2026.01.04
[UEFI] UEFI 및 플랫폼 초기화(PI) 개요  (1) 2026.01.01
BIOS/UEFI의 역할  (0) 2026.01.01
'CS/Graduation project' 카테고리의 다른 글
  • [UEFI] UEFI DRIVERS
  • [UEFI] Driver Execution Environment (DXE)
  • [UEFI] UEFI 및 플랫폼 초기화(PI) 개요
  • BIOS/UEFI의 역할
tteokbokki-master
tteokbokki-master
공부하며 알아가는 걸 조금씩 정리하고 있어요
  • tteokbokki-master
    용로그
    tteokbokki-master
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • 컴파일러개론
        • Graduation project
      • 프로그래밍 언어
        • HTML & CSS
        • JavaScript
        • React 기초
        • 파이썬 기초
        • TanStack-Query
        • C언어 기초
        • git
        • 리눅스
        • 코딩테스트 공부
      • 개발 지식
      • 언어학
        • 의미론
      • 회고 및 기록
      • 프로젝트
        • TodoList 만들기
        • 학수고대 프로젝트
        • 2025 동계 모각코 (안조용희)
      • 기타
        • [JS-0기] 한입 FE 챌린지
        • 서평
  • 인기 글

  • 글쓰기 / 관리
  • hELLO· Designed By정상우.v4.10.3
tteokbokki-master
[UEFI] SEC 및 PEI 단계
상단으로

티스토리툴바