ExitBootServices後のRuntimeとは何か

ExitBootServices後のfirmware状態を、Boot Services終了とRuntime Services継続から説明します。

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

要点

Runtime after ExitBootServices は、boot loaderがExitBootServices()を正常に呼び終えた後の状態です。この時点からUEFI Boot Servicesは使えなくなり、OSが自分の方式でsystemを管理し始めます。

これはUEFI boot flowの中でも非常に重要な境界です。

ExitBootServices後に何が変わるか

ExitBootServices()の前は、firmwareはBoot Services、protocol database、handle database、各種allocation APIを提供しています。

ExitBootServices()が成功した後は、次のようになります。

Boot Services: 無効
Protocol database: 以前と同じ使い方はできない
Firmware driver model: 主制御層ではなくなる
OS memory manager: 所有権を持つ
Runtime Services: preserveされた部分だけが残る

この境界の後にBoot Servicesを呼ぶcodeがあれば、かなり危険な兆候です。

EBS後のmemory map

EBS後、OSはBoot Services memoryをreclaimできます。

例:

EfiBootServicesCode
EfiBootServicesData

これらの領域は、もうfirmware専用ではありません。一方で、EfiRuntimeServicesCodeEfiRuntimeServicesDataのようなruntime領域は、runtime descriptorに従ってOSが保持する必要があります。

残るRuntime Services

EBS後も、platformがsupportしていればOSはRuntime Servicesを呼べます。

例:

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

ただし、これらはruntime条件で動く必要があります。Boot Servicesや完全なDXE handle databaseがまだある、という前提は置けません。

SetVirtualAddressMapとの関係

EBS後、OSはSetVirtualAddressMap()を呼び、runtime descriptorのvirtual mappingをfirmwareへ渡すことがあります。

その時、firmware runtime codeはVirtualAddressChange eventを処理し、生き残るpointerをConvertPointer()で変換します。

OSがvirtual runtime modeへ移った後もpointerがphysical addressのままだと、後のruntime callでcrashする可能性があります。

よくある失敗パターン

よくあるのは、private contextを普通のAllocatePool()で確保し、結果としてEfiBootServicesDataに置いてしまうケースです。EBS前は問題なく動きます。EBS後、OSがそのmemoryをreclaimします。

その後OSがGetVariable()などのRuntime Serviceを呼ぶと、firmwareが失われたcontextを読み、page faultを起こします。

Debug時の確認点

kernel起動後に問題が出る場合、次を確認します。

ExitBootServices()は成功したか
最後のmemory mapは正しいか
runtime descriptorにEFI_MEMORY_RUNTIMEがあるか
OSはSetVirtualAddressMap()を呼んだか
VirtualAddressChange handlerは動いたか
runtime pointerはConvertPointer()されたか
EBS後にBoot Services APIを呼んでいないか

これにより、boot loaderの問題、firmware runtimeの問題、OS mappingの問題を分けやすくなります。

Source-reading checklist

EBS後のruntime codeを読む時は、次を確認します。

- Boot Services dataへのpointerを保存していないか
- runtime allocationのmemory typeは何か
- runtime serviceがprotocolやhandle databaseに依存していないか
- convertが必要なglobal pointerやlinked listがないか
- SetVirtualAddressMap後のerror pathをlogできるか
- capsule、variable、reset pathはruntime contextで動くか

まとめ

ExitBootServices()後、firmwareは完全なboot environmentではなくなります。OSがsystemを所有し、Boot Servicesは終了し、runtimeとして保持された一部だけが残ります。boot後の問題をdebugする時は、memory type、runtime descriptor、SetVirtualAddressMap()ConvertPointer()、そしてEBS後に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.