Slide 1

Slide 1 text

UEFIをつくる 2018/03/24 第11回 自作OSもくもく会 @retrage

Slide 2

Slide 2 text

Recap: UEFI • Unified Extensible Firmware Interface • 標準化されたBIOSの規格とその実装 • そもそもの始まりはIA-64向けにIntelが開発したEFI • EFIをベースにUEFI Forumにより標準化⇒UEFI • TianoCore: オープンソースなリファレンス実装 1

Slide 3

Slide 3 text

yabits • OSの起動にのみ特化したyet anotherなUEFI実装 • いろいろ動く • GRUB2 • Linux kernel • OpenBSD • TianoCoreと比較して • 起動時間: 1/2 • フットプリント: 1/10 • 概要はMitou Demo Day 2017の動画にて • https://youtu.be/OIdPUK9a7vI 2

Slide 4

Slide 4 text

UEFI再考 • UEFIはOSではない.インターフェースである. • No multitask • No multithread • No Ring Protection • 従来のLegacy BIOS同様,bootloaderやOSに対して 機能を提供することが目的 • UEFIのゴールはOSを起動すること 3

Slide 5

Slide 5 text

Boot Process 4 PEI DXE BDS TSL RT Hardware Init Driver Driver Driver Driver Services Boot Manager Boot Loader OS

Slide 6

Slide 6 text

Handoff • Boot ManagerがESPを探索し,EFI Appを起動 • デフォルトでは\EFI\BOOT\BOOT.EFI • 起動時にスタックorレジスタに情報が渡される • EFI_SYSTEM_TABLE * • EFI_HANDLE • IA-32の場合 5

Slide 7

Slide 7 text

EFI_SYSTEM_TABLE • UEFIの提供するServicesをまとめたstruct 6 typedef struct { EFI_TABLE_HEADER Hdr; CHAR16 *FirmwareVendor; UINT32 FirmwareRevision; EFI_HANDLE ConsoleInHandle; EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; EFI_HANDLE ConsoleOutHandle; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; EFI_HANDLE StandardErrorHandle; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr; EFI_RUNTIME_SERVICES *RuntimeServices; EFI_BOOT_SERVICES *BootServices; UINTN NumberOfTableEntries; EFI_CONFIGURATION_TABLE *ConfigurationTable; } EFI_SYSTEM_TABLE;

Slide 8

Slide 8 text

OSの起動に必要な機能 • BootServices • RuntimeServices • GPT+ESP対応 • デバイスドライバ • 最低限以上の機能があればOSの起動は可能 7

Slide 9

Slide 9 text

BootServices • ExitBootServices()されるまで提供するServices • 35個ほどあるが全て必要というわけでもない • メモリ関連 • {Allocate, Free}Pages(), {Allocate, Free}Pool() など • Image関連 • LoadImage(), StartImage() • 他にもEventやProtocol関係のServiceがある • Servicesには依存関係が存在 • 例: LoadImage()の内部でAllocatePages()を呼び出す 8

Slide 10

Slide 10 text

ExitBootServices() • BootServices()のうちの1つ • 機能: BootServicesの提供を終了 • OSの条件: ExitBootServices()を呼ぶこと • EFI AppではExit()によりUEFIに処理を戻す • が,実際にはExitBootServices()後もBootServicesが 利用できる • Linuxでは少なくともそうなっている • arch/x86/kernel/setup.c:1149 参照 9

Slide 11

Slide 11 text

RuntimeServices • OS起動後もUEFIが提供するServices • ExitBootServices()が呼ばれても存続 • NVRAM関連 • GetNextVariableName(), {Get, Set}Variable() • 時間関連 • {Get, Set}Time(), {Get, Set}WakeupTime() • UEFI対応したOSではこれらを利用しているはず 10

Slide 12

Slide 12 text

SetVirtualAddressMap() • RuntimeServices()の1つ • UEFIのアドレッシングモードをPhysicalからVirtualへ • ExitBootServices()後に1度だけ呼び出される • UEFIはこれによりRuntimeServicesをリロケーション • デバッグの非常に難しいところ 11

Slide 13

Slide 13 text

GUID Partition Table: GPT • MBR代替のPartition Tableの標準規格 • MBRを前提としたBIOSが読んでもPartition Tableが 壊れないようにLBA 0にProtective MBRが存在 12

Slide 14

Slide 14 text

EFI System Partition: ESP • 実質FATファイルシステム • 持っているGUIDが異なる • ライセンスとしてはMicrosoftがESPの利用に限って 認めているような状況(だったはず) • Linuxの場合: /boot • GRUB2などのbootloaderもここに置かれる • Boot ManagerはESPを探索,bootloader/OSを起動 • デフォルトでは\EFI\BOOT\BOOT.EFI • NVRAMのVariableにも依存 13

Slide 15

Slide 15 text

デバイスドライバ • 当然UEFIでも各種デバイスにアクセスする必要が あるのでデバイスドライバが必須 • 例: • PCIe, USB, IDE, AHCIなど • UEFIでは基本的にはポーリング • yabitsではLibpayloadやFILO,depthchargeのドライ バを活用 14

Slide 16

Slide 16 text

OS開発者から見たUEFI • UNIX系をベースとしている場合非常に面倒 • Calling Conventionの違いなど • Linuxでの対応方法 • GRUB2による起動 • EFI Appなヘッダを作成してOSをEFI Appとして起動 • OpenBSDやBitVisorでの対応方法 • EFI対応の1st loader+共通の2nd loader • UEFI対応についてLinuxと同じ方針をとったnon GPL なtoy OSがあると幸せかもしれない 15

Slide 17

Slide 17 text

まとめ • UEFIは標準化されたBIOSの規格とその実装 • UEFIはbootloaderやOSに対するインターフェース • UEFIはBootServices, RuntimeServicesなどの機能を 提供 • OS開発者から見た場合,UEFIは利用できる機能は Legacy BIOSと比較して増えたものの,その分煩雑 になったとも言える 16

Slide 18

Slide 18 text

参考文献 • http://www.uefi.org/sites/default/files/resources/ UEFI%20Spec%202_7_A%20Sept%206.pdf • http://wiki.phoenix.com/wiki/index.php/EFI_BOOT _SERVICES • http://wiki.phoenix.com/wiki/index.php/EFI_RUNTI ME_SERVICES • https://github.com/yabits/uefi 17