Upgrade to Pro — share decks privately, control downloads, hide ads and more …

UEFIをつくる

 UEFIをつくる

第11回 自作OSもくもく会でお話した内容です.

8dc3958dc2480bd681e4b5c197817047?s=128

Akira Moroo

March 24, 2018
Tweet

Transcript

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

  2. Recap: UEFI • Unified Extensible Firmware Interface • 標準化されたBIOSの規格とその実装 •

    そもそもの始まりはIA-64向けにIntelが開発したEFI • EFIをベースにUEFI Forumにより標準化⇒UEFI • TianoCore: オープンソースなリファレンス実装 1
  3. yabits • OSの起動にのみ特化したyet anotherなUEFI実装 • いろいろ動く • GRUB2 • Linux

    kernel • OpenBSD • TianoCoreと比較して • 起動時間: 1/2 • フットプリント: 1/10 • 概要はMitou Demo Day 2017の動画にて • https://youtu.be/OIdPUK9a7vI 2
  4. UEFI再考 • UEFIはOSではない.インターフェースである. • No multitask • No multithread •

    No Ring Protection • 従来のLegacy BIOS同様,bootloaderやOSに対して 機能を提供することが目的 • UEFIのゴールはOSを起動すること 3
  5. Boot Process 4 PEI DXE BDS TSL RT Hardware Init

    Driver Driver Driver Driver Services Boot Manager Boot Loader OS
  6. Handoff • Boot ManagerがESPを探索し,EFI Appを起動 • デフォルトでは\EFI\BOOT\BOOT<arch>.EFI • 起動時にスタックorレジスタに情報が渡される •

    EFI_SYSTEM_TABLE * • EFI_HANDLE • IA-32の場合 5
  7. 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;
  8. OSの起動に必要な機能 • BootServices • RuntimeServices • GPT+ESP対応 • デバイスドライバ •

    最低限以上の機能があればOSの起動は可能 7
  9. BootServices • ExitBootServices()されるまで提供するServices • 35個ほどあるが全て必要というわけでもない • メモリ関連 • {Allocate, Free}Pages(),

    {Allocate, Free}Pool() など • Image関連 • LoadImage(), StartImage() • 他にもEventやProtocol関係のServiceがある • Servicesには依存関係が存在 • 例: LoadImage()の内部でAllocatePages()を呼び出す 8
  10. ExitBootServices() • BootServices()のうちの1つ • 機能: BootServicesの提供を終了 • OSの条件: ExitBootServices()を呼ぶこと •

    EFI AppではExit()によりUEFIに処理を戻す • が,実際にはExitBootServices()後もBootServicesが 利用できる • Linuxでは少なくともそうなっている • arch/x86/kernel/setup.c:1149 参照 9
  11. RuntimeServices • OS起動後もUEFIが提供するServices • ExitBootServices()が呼ばれても存続 • NVRAM関連 • GetNextVariableName(), {Get,

    Set}Variable() • 時間関連 • {Get, Set}Time(), {Get, Set}WakeupTime() • UEFI対応したOSではこれらを利用しているはず 10
  12. SetVirtualAddressMap() • RuntimeServices()の1つ • UEFIのアドレッシングモードをPhysicalからVirtualへ • ExitBootServices()後に1度だけ呼び出される • UEFIはこれによりRuntimeServicesをリロケーション •

    デバッグの非常に難しいところ 11
  13. GUID Partition Table: GPT • MBR代替のPartition Tableの標準規格 • MBRを前提としたBIOSが読んでもPartition Tableが

    壊れないようにLBA 0にProtective MBRが存在 12
  14. EFI System Partition: ESP • 実質FATファイルシステム • 持っているGUIDが異なる • ライセンスとしてはMicrosoftがESPの利用に限って

    認めているような状況(だったはず) • Linuxの場合: /boot • GRUB2などのbootloaderもここに置かれる • Boot ManagerはESPを探索,bootloader/OSを起動 • デフォルトでは\EFI\BOOT\BOOT<arch>.EFI • NVRAMのVariableにも依存 13
  15. デバイスドライバ • 当然UEFIでも各種デバイスにアクセスする必要が あるのでデバイスドライバが必須 • 例: • PCIe, USB, IDE,

    AHCIなど • UEFIでは基本的にはポーリング • yabitsではLibpayloadやFILO,depthchargeのドライ バを活用 14
  16. 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
  17. まとめ • UEFIは標準化されたBIOSの規格とその実装 • UEFIはbootloaderやOSに対するインターフェース • UEFIはBootServices, RuntimeServicesなどの機能を 提供 •

    OS開発者から見た場合,UEFIは利用できる機能は Legacy BIOSと比較して増えたものの,その分煩雑 になったとも言える 16
  18. 参考文献 • 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