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
2강의 내용을 정리한다.
UEFI DRIVER


UEFI 드라이버는 DXE 단계에서 실행되며, 플랫폼 초기화 과정 전반에 걸쳐 메모리에 상주하여 동작한다. Green H 아키텍처 다이어그램의 구성 요소로, 구조도상 우측 상단에 위치한다.
UEFI 드라이버 속성
UEFI 드라이버는 UEFI 로더에 의해 로드되는 시스템 이미지로, 프로토콜을 생성하거나 소비한다. 이를 통해 특정 하드웨어를 지원하거나 기존 드라이버를 대체 할 수 있다.
- Supportive: UEFI 드라이버는 복잡한 버스 계층 구조를 지원한다. 버스 인터페이스와 통신하여 장치를 버스에 연결하는 역할을 수행한다.
- 독립성: UEFI 드라이버는 플래시 메모리를 포함한 특정 플랫폼 스토리지에 종속되지 않으며, UEFI 시스템을 통해 유연하게 로드될 수 있다.
- 유연성: UEFI 드라이버의 핵심 속성은 UEFI 드라이버 바인딩 프로토콜을 구현한다는 점이다. 이는 UEFI 시스템 내에서 높은 유연성을 제공하기 위해 정의된 특수 프로토콜이다.
- 확장성 : UEFI 드라이버는 확장성을 가지며, 미래의 버스 및 장치 유형을 지원하도록 기능을 확장할 수 있다.
UEFI 드라이버의 기능


1. 펌웨어 기능 확장
2. 플랫폼 간 이식성
3. 신속한 개발 지원
UEFI 드라이버의 구성 요소
- Entry Point: 시스템 디스패처가 UEFI 드라이버를 실행하기 위해 최초로 호출하는 지점
- Published Functions: 해당 드라이버가 생성하여 시스템의 다른 구성 요소가 사용할 수 있도록 공개하는 기능을 의미
- Consumed Functions: 드라이버가 특정 작업을 수행하기 위해 외부에서 참조하는 기능이며, 예를 들어 PCI I/O 장치에 접근하는 방법을 파악해야 할 때 사용된다.
- Data Structures: UEFI 드라이버가 본연의 역할을 수행하는 데 필요한 각종 변수 및 데이터의 집합
UEFI DRIVER’S ENTRY POINT

UEFI 드라이버 진입점의 동작 과정을 보여주는 예시
- DXE 디스패처가 UEFI 드라이버를 메모리에 로드한다.
- DXE 디스패처가 해당 드라이버의 진입점을 호출한다.
- UEFI 드라이버의 진입점이 자체적인 프로토콜을 설치
- 위 예제에서 드라이버는 Supported(), Start(), Stop() 함수로 구성된 UEFI 드라이버 바인딩 프로토콜을 생성
- 설치 후 훅이라 불리는 드라이버 함수들에 대한 진입점만 남겨둔 채 드라이버 초기화 코드는 종료되어 제어권을 반환
- UEFI 드라이버는 시스템이 앞서 등록된 훅을 호출할 때까지 시스템 메모리에 상주
UEFI DRIVERS: SUPPORTED

위 과정은 UEFI 시스템이 드라이버의 진입점인 훅을 호출하여 연결을 시도하는 절차를 보여준다. 구체적으로는 시스템이 해당 드라이버의 Supported 함수를 실행하는 단계다. 여기서 프로토콜 소비자란 드라이버의 제어가 필요한 디바이스를 의미한다.
UEFI 시스템은 로드된 모든 드라이버의 Supported 함수를 순차적으로 호출하여 적합성을 검사한다. 각 드라이버는 입력 매개변수를 통해 해당 디바이스를 제어할 수 있는지 판별한다.
위 예제의 경우 드라이버는 PCI I/O 프로토콜을 사용하여 타겟 디바이스의 디바이스 ID를 조회하고 이를 자신의 지원 목록과 대조한다. 확인이 끝나면 드라이버는 시스템에 EFI_SUCCESS(지원함) 또는 EFI_UNSUPPORTED(지원하지 않음) 상태 값을 반환하여 결과를 알린다.
Drivers vs Applications
시스템 메모리에 상주하는 드라이버와 달리 애플리케이션은 작업을 수행한 후 종료되며 메모리에서 제거된다
| Question | Driver | Application |
| 어떤 방식으로 로드되는가? | UEFI Loader | UEFI Loader |
| 사용 가능한 인터페이스는 무엇인가? | All | All |
| 프로토콜을 소비하는가? | Yes | Yes |
| 프로토콜을 생산하는가? | Yes | No |
| 주로 무엇에 의해 구동되는가? | The System | The User |
| 목적은 무엇인가? | 하드웨어 지원 | 특정 작업을 수행 |
UEFI PROTOCOLS
UEFI 프로토콜은 사양에 정의된 함수 포인터와 데이터 구조의 집합 혹은 API 덩어리를 의미한다.
- 드라이버와 프로토콜의 관계
- 프로토콜은 일종의 인터페이스다. UEFI 아키텍처의 핵심인 확장성은 바로 이 프로토콜을 기반으로 구현된다. 종종 UEFI 드라이버와 프로토콜을 혼동하는 경우가 있는데 이 둘은 엄연히 다르다.
- UEFI 드라이버는 특정 작업을 수행하기 위해 여러 핸들에 다양한 프로토콜을 설치하는 실행 가능한 바이너리 이미지다. 반면 UEFI 프로토콜은 사양에 따라 정의된 규약이며 반드시 고유 식별자인 GUID를 가져야 한다.
- 드라이버에 의한 생산
- UEFI 드라이버는 프로토콜을 생산하는 주체다. 프로토콜 인터페이스를 생산하는 드라이버는 내부적으로 프라이빗 데이터를 유지 관리할 수 있다.
- 프로토콜 인터페이스 구조체는 단순히 함수를 가리키는 포인터만 담고 있으며 실제 동작하는 함수 코드는 UEFI 드라이버 바이너리 내부에 존재한다. 드라이버는 그 복잡도에 따라 단일 프로토콜을 생산하거나 다수의 프로토콜을 동시에 생산할 수도 있다.
- 누구나 사용 가능
- UEFI 프로토콜은 누구나 사용할 수 있다. 제공자와 사용자가 반드시 1대1로 대응하지 않는다. 예를 들어 UEFI 플랫폼 드라이버가 제공한 플랫폼 전용 프로토콜을 다른 UEFI 드라이버가 자신의 초기화 함수 단계에서 호출하여 사용할 수 있다.
EXAMPLE A: PCI I/O PROTOCOL

EFI PCI I/O 프로토콜은 UEFI 부트 서비스 환경의 드라이버가 PCI 하드웨어를 제어할 때 사용하는 표준 인터페이스다. 이 프로토콜은 메모리, I/O, PCI 구성 공간 및 DMA 접근을 위한 필수 함수를 제공하여, 복잡한 하드웨어 제어 과정을 추상화하는 것을 핵심 목표로 한다.
구조적으로는 PCI 버스 내 각 컨트롤러마다 하나의 프로토콜 인스턴스가 1:1로 매핑된다. 따라서 드라이버가 특정 디바이스를 제어하려면 해당 인스턴스를 확보해야 하며, 이때 타겟 핸들은 최소한 EFI 디바이스 경로와 EFI PCI I/O 프로토콜을 필수적으로 포함하고 있어야 한다.
EXAMPLE B: DISK I/O PROTOCOL

EFI Disk I/O 프로토콜은 Block I/O 프로토콜의 고정된 블록 단위 접근 방식을 오프셋과 길이를 지정하는 범용적인 형태로 추상화한다. 시스템 펌웨어는 Block I/O 인터페이스가 존재하는 장치에 Disk I/O 프로토콜이 설치되어 있지 않다면 이를 감지하여 자동으로 추가할 책임이 있다. 주로 파일 시스템 드라이버나 기타 디스크 제어 루틴이 데이터에 접근할 때 이 Disk I/O 프로토콜을 사용한다.
EXAMPLE C: DEVICE PATH PROTOCOL

EFI 디바이스 경로 프로토콜은 펌웨어가 부트 장치나 콘솔 등 핵심 하드웨어의 위치를 소프트웨어 토폴로지(Topology)에 맞춰 정의하고 전달하는 표준이다. 이 프로토콜의 주 목적은 OS 로더와 같은 애플리케이션이 추상화된 인터페이스와 연결된 실제 물리 장치가 무엇인지 명확히 식별할 수 있도록 돕는 것이다.
특히 모든 UEFI 애플리케이션은 ExitBootServices() 함수 호출로 부트 서비스가 종료되기 전까지, 하드웨어 직접 제어가 아닌 부트 서비스 디바이스 핸들을 통해서만 물리 장치에 접근해야 한다.
UEFI 프로토콜과 C++ 클래스 비교
유사점
- 프라이빗(Private) 멤버 변수를 가진다.
- 외부에 공개된 함수가 있다.
- 내부에서만 사용하는 비공개(Private) 함수가 있다.
- 객체 자신을 지칭하는 'This' 포인터를 사용한다.
차이점
- 코드 형태와 구현 방식이 다르다.
- 메모리 오버헤드가 더 낮다.
- 서로 다른 코드(드라이버)가 동일한 프로토콜을 생성 할 수 있다.
- 예: SCSI 드라이버와 IDE 드라이버가 동일한 추상화(인터페이스)를 제공할 수 있다.
- 하나의 코드(드라이버 이미지)가 복수 개의 프로토콜을 동시에 생산(제공)할 수 있다.
- 컴파일 타임이 아닌, 시스템 부팅 중 핸들 데이터베이스를 통해 런타임에 동적으로 연결된다.
DRIVER DESIGN PROCESS

드라이버 설계 프로세스는 총 6단계로 진행된다.
- 드라이버 유형을 결정한다.
- 드라이버가 사용할 I/O 프로토콜을 파악한다.
- 드라이버가 제공할 I/O 프로토콜을 파악한다.
- UEFI 드라이버 모델 프로토콜을 확인한다.
- 추가 드라이버 기능을 정의한다.
- 타겟 플랫폼을 선정한다.
UEFI DRIVER TYPES

드라이버를 개발할 때 가장 먼저 고려해야 할 점은 설계하려는 드라이버의 유형을 결정하는 것이다. 이를 위해서는 UEFI에서 생성 가능한 이미지의 종류를 이해해야 한다. UEFI 이미지는 크게 드라이버와 애플리케이션 두 가지 기본 클래스로 나뉜다.
애플리케이션 중에는 OS 로더라는 특수한 유형이 있다. 일반 애플리케이션과 OS 로더를 구분하는 유일한 요소는 ExitBootServices 서비스의 호출 여부다. ExitBootServices는 제어권을 OS 로더에서 OS 커널로 이양하는 역할을 한다. 이후 플랫폼의 제어권은 OS 커널이 갖게 된다. 따라서 OS 로더는 펌웨어로 복귀하지 않는 특수한 형태의 UEFI 애플리케이션이다.
UEFI 드라이버의 유형
서비스 드라이버 (Service Drivers)
- 하드웨어를 직접 관리하지 않는다.
- 다른 드라이버에게 서비스를 제공한다.
- 드라이버 바인딩 프로토콜을 지원하지 않는다.
- 주로 드라이버 진입점에서 프로토콜을 설치한다.
- 하나 이상의 서비스 핸들을 생성한다.
- 서비스별 프로토콜을 생산하여 서비스 핸들에 설치한다.
초기화 드라이버 (Initializing Drivers)
- 주로 하드웨어와 직접 통신한다.
- 일회성 초기화 작업을 수행한다.
- 핸들 및 프로토콜을 생성하지 않는다.
- 작업이 끝나면 메모리에서 언로드된다.
Root Bridge Drivers
- 주로 코어 칩셋의 일부를 관리한다.
- 하드웨어에 직접 접근한다.
- 하나 이상의 루트 브리지 핸들을 생성한다.
- 루트 브리지 I/O 프로토콜을 생산하여 새로운 루트 브리지 핸들에 설치한다.
버스 드라이버 (Bus Drivers)
- Start() 함수가 하나 이상의 자식 핸들을 생성한다.
- Start() 함수가 버스 특화 I/O 프로토콜을 생산하여 버스의 자식 핸들에 설치한다.
하이브리드 드라이버 (Hybrid Drivers)
- 버스 컨트롤러를 관리하고 열거)한다.
- Start() 함수가 하나 이상의 자식 핸들을 생성한다.
- Start() 함수가 버스 특화 I/O 프로토콜을 생산하여, 버스의 컨트롤러 핸들과 자식 핸들 모두에 설치한다.
디바이스 드라이버 (Device Drivers)
- 단일 컨트롤러나 주변 장치를 관리한다.
- Start() 함수가 자식 핸들을 생성하지 않는다.
- Start() 함수가 하나 이상의 I/O 프로토콜을 생산하여 디바이스의 컨트롤러 핸들에 설치한다.
CONSUME PROTOCOLS

PCI 어댑터는 PCI I/O 프로토콜을 주된 인터페이스로 사용하며, 경우에 따라 디바이스 경로 프로토콜도 함께 사용한다.
USB 주변 장치는 USB I/O 프로토콜과 디바이스 경로 프로토콜을 사용한다.
PRODUCED PROTOCOLS

"어떤 프로토콜을 생성 할 것인가?"는 전적으로 대상 주변 장치나 컨트롤러의 유형에 따라 결정된다.
만약 키보드 드라이버를 개발한다면 단순 입력 프로토콜을 생산해야 한다. 마우스, 포인터, 또는 트랙볼 드라이버라면 단순 포인터 프로토콜을 생산해야 한다. 또한 하드 드라이브, CD-ROM, USB, 플로피 드라이버를 작성하는 경우에는 Block I/O 프로토콜을 생산해야 한다.

SCSI 어댑터 드라이버를 개발할 때는 어댑터가 보유한 각 채널마다 SCSI Pass-thru 프로토콜을 생성 해야 한다. 예를 들어 단일 채널을 가진 SCSI 어댑터라면 하나의 SCSI 패스스루 프로토콜만 있으면 된다. 반면 다중 채널을 지원하는 SCSI RAID 어댑터의 경우, 각 채널별로 개별적인 SCSI 패스스루 프로토콜을 생산해야 한다.
또한 드라이버가 어댑터에 연결된 CD-ROM이나 하드 디스크 같은 저장 장치를 발견하게 되면, 식별된 각 장치에 대해 Block I/O 프로토콜을 추가로 생산해야 한다.

NIC 하드웨어는 칩셋 통합형, 독립 어댑터, 혹은 온보드 컨트롤러 등 다양한 형태로 존재한다. 하지만 드라이버 개발 시 어떤 레벨의 인터페이스를 구현할지는 전적으로 NIC 제조사의 정책에 따라 결정된다.
따라서 개발자는 하드웨어의 물리적 형태보다는 제조사가 정의한 사양을 확인하여 적절한 드라이버 레벨을 판단해야 한다. 예를 들어 모든 인텔 NIC는 표준적으로 UNDI 및 NII 드라이버 방식을 사용한다.
WRITING UEFI DRIVERS
UEFI 드라이버 개발 시 필요한 프로토콜은 드라이버의 완성도와 기능에 따라 필수 요소와 권장 요소로 나뉜다.
필수 요소
- 초기화 함수: 드라이버의 진입점 역할을 수행하는 함수다.
- 드라이버 바인딩 프로토콜: 드라이버의 핵심 수명 주기를 관리하며, 다음 3가지 함수를 정의한다.
- Supported(): 드라이버가 특정 컨트롤러를 지원하는지 확인
- Start(): 드라이버를 컨트롤러에 연결하고 구동
- Stop(): 드라이버 중지 및 연결 해제
권장 요소
- Component Name Protocol: 사람이 읽을 수 있는 드라이버 이름을 제공하며, 다국어 기능을 지원한다.
- HII 구성 프로토콜 : 사용자가 드라이버의 특성이나 설정을 변경할 수 있는 인터페이스를 제공한다.
- 드라이버 진단 프로토콜: 최종 사용자가 드라이버가 관리하는 장치의 상태를 테스트할 수 있게 해준다.
- 언로드 프로토콜: 드라이버 이미지를 메모리에서 완전히 제거하는 기능을 제공한다.
DRIVER INITIALIZATION

UEFI 드라이버는 PE/COFF 형식의 Relocatable한 이미지로, 메모리의 어느 위치에든 자유롭게 로드될 수 있다. 드라이버가 로드되면 진입점으로 ImageHandle이 전달되며 초기화가 시작된다.
가장 중요한 특징은 초기화 단계에서 하드웨어를 직접 건드리지 않는다는 점이다. 드라이버는 단지 자신이 생산할 프로토콜, 특히 Supported, Start, Stop 함수를 포함한 드라이버 바인딩 프로토콜을 시스템에 등록할 뿐이다.
이러한 구조는 빠른 부팅 속도를 보장한다. 수많은 옵션 ROM이 로드되더라도 초기화 시점에는 단순히 서비스 등록만 수행하고 하드웨어 제어는 하지 않기 때문이다. 실제 드라이버의 시작 여부는 플랫폼 BIOS 정책에 따라 결정된다. 심지어 동일한 하드웨어를 제어할 수 있는 드라이버가 여러 개 존재하더라도, 플랫폼 정책을 통해 특정 드라이버를 선택적으로 사용할 수 있다.
SUPPORTED()

Supported() 함수는 드라이버가 특정 컨트롤러 하드웨어를 제어할 수 있는지 검사하는 역할을 한다. 드라이버 초기화 후 바인딩 프로토콜이 정의될 때 가장 먼저 호출된다.
1. 입력 파라미터
- This: 드라이버 바인딩 프로토콜 인스턴스 포인터.
- ControllerHandle: 검사 대상이 되는 컨트롤러의 핸들.
- RemainingDevicePath: (선택적) 자식 디바이스를 특정하기 위한 추가 디바이스 경로.
2. 핵심 설계 원칙 및 특징
- 지원 여부 판단: 해당 컨트롤러가 이 드라이버와 호환되는지 확인한다.
- 하드웨어 상태 변경 금지: 단순한 '확인' 과정이므로, 컨트롤러의 하드웨어 상태를 절대 변경해서는 안 된다. (Read-only)
- 실행 속도 최적화: 부팅 속도 저하를 막기 위해 복잡한 I/O 작업이나 초기화는 Start() 함수로 미루고, 최소한의 검사만 수행해야 한다.
- 중복 호출 대응: 이미 다른 드라이버(혹은 자기 자신)에 의해 관리되고 있는 컨트롤러에 대해서도 호출될 수 있음을 고려해야 한다.
3. 실행 흐름 (PCI 드라이버 예시)
PCI 디바이스 드라이버를 기준으로 Supported() 함수는 다음 4단계 절차를 수행한다.
- Open Protocol: 버스 상의 PCI 디바이스 정보를 읽기 위해 해당 컨트롤러 핸들에서 PCI I/O 프로토콜을 연다.
- Check: Vendor ID, Device ID 등을 읽어 드라이버가 지원하는 장치인지 확인한다.
- Close Protocol: 사용한 PCI I/O 프로토콜을 닫아 리소스를 정리한다.
- Return: 지원하면 EFI_SUCCESS, 아니면 EFI_UNSUPPORTED를 반환한다.
Start()

Start() 함수는 드라이버 수명 주기의 시작점으로, 하드웨어를 초기화하고 상위 계층에 서비스를 제공하거나 자식 핸들을 생성하는 핵심 역할을 수행한다
1. 입력 파라미터
Supported() 함수와 동일한 파라미터를 사용한다.
- This: 드라이버 바인딩 프로토콜 인스턴스.
- ControllerHandle: 제어할 컨트롤러의 핸들.
- RemainingDevicePath: (선택적) 특정 자식 디바이스를 지정하는 경로.
2. 주요 기능 및 동작 흐름
- 프로토콜 개방: 버스 제어를 위해 PCI I/O 프로토콜을 연다. 이때는 검사가 아닌 실제 사용이 목적이므로 드라이버 속성(BY_DRIVER)을 적용한다.
- 드라이버 구동: 하드웨어 초기화 루틴을 실행하고 리소스를 할당한다.
- 프로토콜 생산: (예시의 경우) EFI Block I/O 프로토콜과 같은 I/O 인터페이스를 생성하여 설치한다.
- 자식 핸들 생성: 버스 드라이버나 하드웨어 특성에 따라, 연결된 모든 디바이스에 대해 자식 핸들을 일괄 생성하거나 특정 디바이스에 대해 하나의 핸들만 생성할 수 있다.
Stop()

Stop() 함수는 드라이버 바인딩 프로토콜의 마지막 단계로, 드라이버가 컨트롤러 관리를 중단하거나 자식 핸들을 제거할 때 호출된다. Start()에서 생성한 자식 핸들과 프로토콜을 모두 제거하는 것이 주 목적이다.
1. 입력 파라미터
Start()와 유사하지만, 제거 대상을 특정하기 위한 파라미터가 포함된다.
- This: 드라이버 바인딩 프로토콜 인스턴스
- ControllerHandle: 관리를 중단할 컨트롤러의 핸들
- NumberOfChildren & ChildHandleBuffer: (Remaining Device Path 관련) 제거할 자식 핸들의 목록
2. 주요 기능 및 동작 흐름
- 프로토콜 닫기 (Close Protocol): Start()에서 열었던 PCI I/O 프로토콜 등을 닫아 리소스를 반환한다.
- 관리 중단: 드라이버가 더 이상 컨트롤러 하드웨어를 제어하지 않도록 상태를 변경한다.
- 자식 핸들 파괴: Start() 과정에서 생성되었던 모든 자식 핸들을 파괴하고, 설치된 프로토콜을 제거한다.
3. 버스 컨트롤러의 종료 메커니즘
자식 핸들이 구체적으로 명시되지 않은 경우, 컨트롤러 자체의 동작을 중단시킨다. 특히 버스 드라이버를 중단하는 과정은 구조적으로 두 단계의 호출이 필요할 수 있다.
- 첫 번째 호출: 버스에 연결된 자식 핸들들을 먼저 제거한다.
- 두 번째 호출: 자식들이 모두 제거된 상태에서, 비로소 버스 컨트롤러 자체를 정지시킨다.
RECOMMENDED DRIVER PROTOCOLS

개발할 때 참고할 사항
DRIVER GUIDELINES
하나의 드라이버로 다중 시스템을 지원하도록 설계할 때는 아래의 지침을 준수해야한다.
- 드라이버 진입점(Entry Point)에서는 프로토콜 설치만 수행하며, 절대 하드웨어를 직접 건드리지 않는다.
- 자원 할당과 해제 구조가 정확히 대응되도록 설계한다.
- Start() ↔ Stop()
- Driver Entry ↔ Unload
- 시간이 오래 걸리거나 복잡한 I/O 작업은 Driver Entry나 Supported가 아닌, 실제 구동 단계인 Start()와 Stop() 함수 내에서 처리한다.
DRIVER DESIGN CHECKLIST

구현, 테스트 및 디버그
권장 사항
- UEFI 쉘 명령어를 사용하여 함수를 테스트한다.
- UEFI 쉘 명령어를 사용하여 누수를 확인한다.
- UEFI 호환 운영체제를 설치한다.
- UEFI 호환 운영체제를 부팅한다.
- 디버그 매크로를 통해 치명적인 오류를 식별한다.
- 모든 프로세서 유형 (x86, x64, Itanium 프로세서 제품군, EBC)에 동일한 기법을 사용한다.
PCI DEVICE DRIVERS: START()

PCI 디바이스의 속성을 설정하는 Start 함수 코드의 예시이다. 이 예시는 원본 값을 지역 변수에 따로 저장해두고, 실제 속성을 설정 및 활성화한다.
PCI DEVICE DRIVERS: STOP()

Stop 함수 예시에서는, 원본 값으로 저장해두었던 지역 변수를 사용하여 디바이스를 다시 원래 상태로 재설정하고 있다.
USING UEFI DRIVER LIBRARY FUNCTION

코드의 크기를 줄이는 데 도움이 되는 라이브러리 호출 사용 예시이다. 적절한 코드 예시에서는 두 번의 호출이 이루어지는 반면, 최적의 코드 예시에서는 단 한 번의 호출만 이루어지므로, 결과적으로 바이너리 크기를 절약한다.
기타 유용한 제안 사항
옵션 ROM 크기 줄이기
- UEFI 압축 (UEFI Compression) 사용
- EFI 바이트 코드(EBC) 컴파일러로 컴파일
- x86, x64 및 Itanium을 아우르는 단일 바이너리
- Itanium 바이너리보다 크기가 작음
- x86 바이너리와 비슷한 수준
- 압축 효율이 좋음 (약 50%)
이식성 향상
- 자식의 최대 개수를 미리 가정하지 말 것
- 고정 메모리 주소나 어셈블리 코드를 사용하지 말 것
- 부동 소수점 연산을 사용하지 말 것
- 몇 가지 사소한 EBC 포팅 고려 사항들 확인
- 버스 드라이버는 가능하다면 한 번에 하나의 자식을 생성하는 것을 지원해야 함 (이렇게 하면 부팅 성능이 향상됨)
'CS > Graduation project' 카테고리의 다른 글
| SMM 권한 상승과 Secure Boot 우회 (CVE-2025-7026, 3052) (0) | 2026.01.26 |
|---|---|
| CVE-2023-45230: UEFI DHCPv6 드라이버 힙 오버플로우 (0) | 2026.01.19 |
| [UEFI] Driver Execution Environment (DXE) (0) | 2026.01.04 |
| [UEFI] SEC 및 PEI 단계 (0) | 2026.01.02 |
| [UEFI] UEFI 및 플랫폼 초기화(PI) 개요 (1) | 2026.01.01 |
