Runtime Phaseとは何か

UEFIのRuntime Phaseを、OSが制御を受け取った後も残るfirmware機能として説明します。

更新 約 3 分
Đọc bằng 日本語 Tiếng Việt English
Firmware Flow cover

要点

Runtime Phase は、firmwareが制御の大部分をOSへ渡した後でも、一部のfirmware機能がUEFI Runtime ServicesとしてOSから呼ばれる期間です。

簡単に言うと、boot firmwareは主導権を失いますが、firmwareが完全に消えるわけではありません。

Runtime Phaseはいつ始まるか

Runtime Phaseは、通常ExitBootServices()が成功した後として説明されます。

その前までは、boot loaderはAllocatePool()LocateProtocol()LoadImage()などのBoot Servicesを使えます。その後はBoot Servicesが使えなくなり、memory管理、driver、scheduler、device stackはOS側の責任になります。

ただし、variable serviceやtime serviceなど、一部のRuntime ServicesはOSから呼ばれ続ける可能性があります。

残るRuntime Services

よく出てくるAPIは次のようなものです。

GetTime()
SetTime()
GetVariable()
SetVariable()
GetNextVariableName()
ResetSystem()
UpdateCapsule()
QueryCapsuleCapabilities()
SetVirtualAddressMap()

すべてのplatformが同じ使い方をするわけではありません。特にGetVariable()SetVariable()は、NVRAM、Secure Boot、boot option、capsule updateと強く関係します。

Boot Phaseとの違い

Boot Phaseでは、firmwareはBoot Services、protocol database、driver model、handle database、dispatcherを持っています。

Runtime PhaseではOSが主導権を持っています。firmware側に残るのは、memory mapとruntime attributeによってOSが保持したruntime entry pointだけです。

そのため、runtime driverはExitBootServices()後にBoot Servicesへ依存してはいけません。

Memory typeとの関係

Runtime codeとdataは、適切なmemory typeに置かれる必要があります。

EfiRuntimeServicesCode
EfiRuntimeServicesData

関連するdescriptorにはEFI_MEMORY_RUNTIMEが必要です。runtime contextを誤ってEfiBootServicesDataに置くと、OSがその領域をreclaimし、OS boot後にfirmware runtime pathがcrashする可能性があります。

Virtual addressへの移行

一部のOSはSetVirtualAddressMap()を呼び、Runtime Servicesをvirtual address modeへ移します。

VirtualAddressChange eventが発生したら、runtime driverは生き残る必要がある内部pointerに対してConvertPointer()を行います。

pointerを変換し忘れたり、nested pointerの変換が足りなかったりすると、OS boot後だけで問題が出ます。

よくあるdebug case

例えば、boot loader上ではfirmware variable serviceが正常に動くのに、OSに入った後のGetVariable()でpage faultするケースがあります。

原因としては、runtime private contextがBoot Services memoryに置かれていた、またはSetVirtualAddressMap()後にpointerをconvertしていなかった、などが考えられます。

Source-reading checklist

runtime pathを読む時は、次を確認します。

- MODULE_TYPEはDXE_RUNTIME_DRIVERか
- runtime code/dataのmemory typeは正しいか
- descriptorにEFI_MEMORY_RUNTIMEがあるか
- ExitBootServices()後にBoot Services APIを使っていないか
- VirtualAddressChange eventをregisterしているか
- ConvertPointer()はprivate context、global pointer、linked listをcoverしているか
- variable、flash、SMM pathはOS boot後のinputもvalidateしているか

まとめ

Runtime Phaseは、OSが制御を受け取った後も残るfirmwareの小さな部分です。Boot Phaseより範囲はかなり小さいですが、NVRAM、Secure Boot、capsule update、reset、firmware policyに関係するため重要です。runtime bugをdebugする時は、memory type、runtime descriptor、SetVirtualAddressMap()ConvertPointer()、Boot Servicesがもう使えないことを同時に確認する必要があります。

この記事が役に立ったら

ファームウェア、BIOS/UEFI、組み込みシステムを学んでいる人に共有したり、作者を応援したりできます。

ご意見

Nội dung liên quan

Một số bài viết, ghi chú hoặc project có liên quan đến nội dung bạn vừa đọc.

Biến note thành bài viết hoàn chỉnh

Notes là nơi ghi nhanh khái niệm.