SlideShare a Scribd company logo
UEFI時代のブート 
ローダ 
@syuu1228
自己紹介 
• Software Engineer at Cloudius Systems 
(OSv) 
• FreeBSD developer (bhyve, network stack..)
UEFIのおさらい
BIOSブート 
←ディスクに1個 
• MBRからブートセクタをロード 
• プログラム領域が足りないのでMBRの次のセク 
タなどを利用して更に大きなブートローダをロー 
ド(多段ブート) 
• /bootファイルシステムをパースしてLinuxカー 
ネルを見つけてロード&実行
UEFIブート 
• ブートセクタなどなかった 
• EFIパーティーション(FATファイルシステム)にブートロー 
ダ(UEFIイメージ)を配置 
• NVRAMに設定がある 
→設定されたパスからブートローダをロード&実行 
• NVRAMに設定がない 
→デフォルトパスからブートローダをロード&実行 
• プロテクテッドモード、UEFI API 
←ディスクにn個(いくらでも)
BIOSのブートイメージ 
• ブートセクタなどのとても狭い領域に固定的に配 
置 
• リアルモード 
• アドレッシング出来るメモリに大きな制約 
• アセンブリ 
• 古くさいBIOSコールによる限られたAPI
UEFIイメージ 
• PEバイナリ 
(Windowsアプリと似たようなヘッダ) 
• 32/64bitプロテクテッドモード 
(※但し両対応ファームはない) 
• サイズ制限、メモリ容量制限なし 
• 全てC言語で記述可能 
• 豊富なAPI
参考:Runtime Services 
• ExitBootServices()後もUEFIがOSに対して提供するサービ 
ス 
• 最低限の機能のみ 
• Time (GetTime, SetTime...) 
• Virtual Memory (SetirtualAddressMap...) 
• Variable Services (GetVariable...) 
• Miscellaneous Services(ResetSystem...)
参考:Boot Services 
• ExitBootServices()までUEFI Applicationに提供するサービス 
• Task Priority Services (RaiseTPL...) 
• Memory Services (AllocatePages...) 
• Event & Timer Services (CreateEvent, SetTimer...) 
• Protocol Handler Services (HandleProtocol...) 
• Image Services (LoadImage, StartImage...) 
• Miscellaneous Services (Stall, CopyMem...) 
• Open and Close Protocol Services (OpenProtocol...) 
• Library Services (LocateProtocol...) 
• 32bit CRC Services (CalculateCrc32...)
参考:Procotols 
• ネットワークプロトコルスタックのことではな 
い 
• UEFI上で提供される様々なサービスの事 
• UEFI Driverを実装しUEFIへロードする事によ 
り、自作のProtocolを提供する事も可能
参考:定義されている 
Protocol 
• EFI Loaded Image 
• Device Path Protocol 
• UEFI Driver Model 
• Console Support 
• Media Access 
• PCI Bus Support 
• SCSI Driver Models and Bus 
Support 
• iSCSI Boot 
• USB Support 
• Debugger Support 
• Compression Algorithm 
• ACPI Protocols 
• TCP/IP, IPSec, FTP 
• ARP & DHCP 
• UDP & MTFTP 
• etc...
UEFIからのブート手順 
(デフォルト) 
BootManagerの設定がデフォルト値の場合 
1. UEFIがHDDを検出、GPTをロード 
2. EFI System Partitionを検索 
3. EFIBOOTBOOTX64.EFIをロード 
(32bit UEFIならBOOTX86.EFI)
UEFIからのブート手順 
(カスタム) 
以下の様な値をUEFI NVRAM variableに設定(efibootmgrなど) 
• Boot####:ロードするUEFI applicationのPATH・ 
又はディスクのデバイスPATH 
• BootOrder:Boot####の試行順序(配列で指定) 
• BootNext:次回起動時にロードするBoot#### 
(BootOrderより優先、一度起動すると削除) 
• Timeout:設定秒数だけBoot Menuを表示(自動起動を遅 
延)
設定例 
• efibootmgrで編集 
• /sys/firmware/efi/vars, /sys/firmware/efi/efivars 
経由でUEFI NVRAM Variableへアクセス
/sys/firmware/efi/efivars 
syuu@ubuntu:~$ ls /sys/firmware/efi/efivars 
Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c 
Boot0001-8be4df61-93ca-11d2-aa0d-00e098032b8c 
Boot0002-8be4df61-93ca-11d2-aa0d-00e098032b8c 
Boot0003-8be4df61-93ca-11d2-aa0d-00e098032b8c 
Boot0004-8be4df61-93ca-11d2-aa0d-00e098032b8c 
BootCurrent-8be4df61-93ca-11d2-aa0d-00e098032b8c 
... 
$ sudo cat /sys/firmware/efi/efivars/ 
Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c 
@EFI VMware Virtual SCSI Hard Drive (0.0) 
?
Boot Manager 
ブート項目の選択画面。 
OSは自分のブートローダをここに登録する
UEFI Shell 
• 運が良ければROMに乗ってる 
無ければUSBからロード
さまざまな 
UEFIブート手順
UEFIでのLinuxブート方法(1) 
• shim→grub2→Linux bzImage 
• shim→grub2→Linux EFI Stub 
• grub2→Linux bzImage 
• grub2→Linux EFI Stub 
• gummiboot→Linux EFI Stub 
• Linux EFI Stub 
←SecureBoot
UEFIでのLinuxブート方法(2) 
• LinuxカーネルにEFI Stubを用意すれば直接Boot 
Managerからロード出来る 
• UEFIイメージから更に別のUEFIイメージをロー 
ド&実行できる 
• UEFI APIがサポートしていないバイナリフォー 
マットよりもサポートが容易 
サポートすることによるデメリットも少ない
なるほど~?
非対応フォーマットの 
ロード&実行 
• ヘッダのパース 
• メモリへの展開 
• CPUレジスタの初期化、辻褄合わせ 
• エントリポイントへのジャンプ 
_人人人人人人_ 
> 結構面倒 < 
‾Y^Y^Y^Y^Y‾
UEFIイメージのロード& 
実行 
• UEFIイメージファイルをロードするAPI 
にファイル名渡して終わりでは? 
_人人人人人人_ 
> 簡単そう < 
‾Y^Y^Y^Y^Y‾
ところで 
• mrubyはUEFIで動く(mruby on EFI shell)
ということは 
• mrubyにローダAPIを足せばmrubyスクリ 
プトでブートローダを簡単に実装出来 
るのでは?
UEFI APIサポートon mruby 
class BlockIoProtocol < UEFI::Protocol 
GUID = UEFI::Guid.new("964e5b21-6459-11d2-8e39-00a0c969723b") 
define_variable(:revision, :u64) 
define_variable(:media, :p) 
define_function(:reset, :e, [:p, :b]) 
define_function(:read_blocks, :e, [:p, :u32, :u64, :u64, :p]) 
end 
class Media < UEFI::Protocol 
define_variable(:media_id, :uint32) 
end 
handles = 
UEFI::BootService.locate_handle_buffer(BlockIoProtocol::GUID) 
handle = handles.first 
puts "handle: #{handle}" 
ptr = UEFI::BootService.handle_protocol(handle, 
BlockIoProtocol::GUID) 
bp = BlockIoProtocol.new(ptr) 
media = Media.new(bp.media) 
puts "media_id: #{media.media_id}"
これを使ってmrubyでロー 
ダを書けばいいんじゃね?
Cで書く→mrubyに起こす 
• Cで書いてみた 
https://gist.github.com/syuu1228/ 
d7ce6b949cbeec887ea0
どのAPIをmrubyでどう置き 
換えれば良いのか分からない 
…(゜Д゜)
方針転換 
• 足りない機能は皆C拡張にしてしまえ 
• さっきのコードをコピペしてmrubyのクラス化 
→実行 
• 何故かエラー… 
• (゜Д゜)
む?
良くみたらsystem(3) 
あったわ 
• EDK2にはlibc + BSD socketのテスト実装が載ってる 
(非公式あつかい) 
• どうせmrubyは初めからこれをリンクしている 
• system(3)もある 
• 文字列組み立てて渡せば一行のCコードでバイナリ実行 
できんじゃん… 
• 何を苦労していたんだろう
が… 
• mruby on EFI shellはmrubyの標準ビルドシス 
テムを迂回してEDKのビルドシステムでビルド 
されてる 
• mrubyのビルドシステムを使わないとmrbgems 
を追加出来ない 
• 殆どAPIが無い&簡単に足せない…
応急処置的に足す 
• さっきのsystem(3)を呼び出すShell.exec() 
• キーボード入力を受け付けるShell.gets() 
• Dirクラス
完成! 
• https://github.com/syuu1228/ 
mruby_on_efi_shell/blob/ 
862b7d95e399dc23744c589220e59d6e6f 
0adff3/example/bootloader.rb
デモ
TODO 
• mrbgems問題をどうにかするべき 
• HTTPクライアントをポーティングしてカーネルもスク 
リプトも外から落としてきて実行させたい 
• ファイルシステムドライバをインストールしてext[2-4] 
の/bootからカーネルをロードしたい 
• ブートしたらツイートしたい 
• もうちょっと整備すると結構便利になると思う
URL 
• https://github.com/syuu1228/ 
mruby_on_efi_shell/tree/devel

More Related Content

PDF
10分で分かるLinuxブロックレイヤ
PDF
JIT のコードを読んでみた
PDF
あなたの知らないPostgreSQL監視の世界
PPTX
UEFIによるELFバイナリの起動
PDF
QEMUでARM64bitベアメタルプログラミング
PDF
Linuxカーネルを読んで改めて知るプロセスとスレッドの違い
PDF
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
PDF
12 分くらいで知るLuaVM
10分で分かるLinuxブロックレイヤ
JIT のコードを読んでみた
あなたの知らないPostgreSQL監視の世界
UEFIによるELFバイナリの起動
QEMUでARM64bitベアメタルプログラミング
Linuxカーネルを読んで改めて知るプロセスとスレッドの違い
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
12 分くらいで知るLuaVM

What's hot (20)

PDF
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
PPTX
Ceph アーキテクチャ概説
PDF
Docker Compose 徹底解説
PDF
ゼロからはじめるKVM超入門
PDF
katagaitai CTF勉強会 #5 Crypto
PDF
x86とコンテキストスイッチ
PDF
“見てわかる” ファイバーチャネルSAN基礎講座(第4弾)~続・間違わない!FC SAN導入のヒントとコツ~
PDF
IL2CPPに関する軽い話
PDF
5分で分かるgitのrefspec
PDF
コンテナ未経験新人が学ぶコンテナ技術入門
PDF
Scapyで作る・解析するパケット
PPTX
Docker Tokyo
PDF
今だからこそ知りたい Docker Compose/Swarm 入門
PPTX
冬のLock free祭り safe
PDF
1075: .NETからCUDAを使うひとつの方法
PDF
大規模サービスを支えるネットワークインフラの全貌
PDF
Wireshark だけに頼らない! パケット解析ツールの紹介
PDF
OSC2011 Tokyo/Fall 濃いバナ(virtio)
PDF
コンテナの作り方「Dockerは裏方で何をしているのか?」
PPTX
本当は恐ろしい分散システムの話
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Ceph アーキテクチャ概説
Docker Compose 徹底解説
ゼロからはじめるKVM超入門
katagaitai CTF勉強会 #5 Crypto
x86とコンテキストスイッチ
“見てわかる” ファイバーチャネルSAN基礎講座(第4弾)~続・間違わない!FC SAN導入のヒントとコツ~
IL2CPPに関する軽い話
5分で分かるgitのrefspec
コンテナ未経験新人が学ぶコンテナ技術入門
Scapyで作る・解析するパケット
Docker Tokyo
今だからこそ知りたい Docker Compose/Swarm 入門
冬のLock free祭り safe
1075: .NETからCUDAを使うひとつの方法
大規模サービスを支えるネットワークインフラの全貌
Wireshark だけに頼らない! パケット解析ツールの紹介
OSC2011 Tokyo/Fall 濃いバナ(virtio)
コンテナの作り方「Dockerは裏方で何をしているのか?」
本当は恐ろしい分散システムの話
Ad

Similar to UEFI時代のブートローダ (10)

PDF
Play with UEFI
PDF
UEFIで始めるLinux From Scratch
PPTX
BIOSからUEFI
PPTX
2015年度の自宅NAS環境
PDF
UEFIのブート方式について
PDF
UEFI向け自作OSの紹介
PDF
NetBSD/evbarm (APC9750) への道
PDF
initramfsについて
PDF
Raspberry pi で始める v sphere 7 超入門
PDF
Infinite Debian - Platform for mass-producing system every second
Play with UEFI
UEFIで始めるLinux From Scratch
BIOSからUEFI
2015年度の自宅NAS環境
UEFIのブート方式について
UEFI向け自作OSの紹介
NetBSD/evbarm (APC9750) への道
initramfsについて
Raspberry pi で始める v sphere 7 超入門
Infinite Debian - Platform for mass-producing system every second
Ad

More from Takuya ASADA (20)

PPTX
Seastar in 歌舞伎座.tech#8「C++初心者会」
PPTX
Seastar:高スループットなサーバアプリケーションの為の新しいフレームワーク
PDF
高スループットなサーバアプリケーションの為の新しいフレームワーク
「Seastar」
PDF
ヤマノススメ〜秋山郷 de ハッカソン〜
PDF
OSvのご紹介 in 
Java 8 HotSpot meeting
PDF
OSvパンフレット v3
PDF
OSvのご紹介 in OSC2014 Tokyo/Fall
PDF
OSv噺
PDF
OSvの概要と実装
PDF
Linux network stack
PDF
Ethernetの受信処理
PDF
Presentation on your terminal
PDF
僕のIntel nucが起動しないわけがない
PDF
Interrupt Affinityについて
PDF
OSvパンフレット
PDF
BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜
PDF
「ハイパーバイザの作り方」読書会#2
PDF
「ハイパーバイザの作り方」読書会#1
PDF
10GbE時代のネットワークI/O高速化
PDF
Implements BIOS emulation support for BHyVe: A BSD Hypervisor
Seastar in 歌舞伎座.tech#8「C++初心者会」
Seastar:高スループットなサーバアプリケーションの為の新しいフレームワーク
高スループットなサーバアプリケーションの為の新しいフレームワーク
「Seastar」
ヤマノススメ〜秋山郷 de ハッカソン〜
OSvのご紹介 in 
Java 8 HotSpot meeting
OSvパンフレット v3
OSvのご紹介 in OSC2014 Tokyo/Fall
OSv噺
OSvの概要と実装
Linux network stack
Ethernetの受信処理
Presentation on your terminal
僕のIntel nucが起動しないわけがない
Interrupt Affinityについて
OSvパンフレット
BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜
「ハイパーバイザの作り方」読書会#2
「ハイパーバイザの作り方」読書会#1
10GbE時代のネットワークI/O高速化
Implements BIOS emulation support for BHyVe: A BSD Hypervisor

UEFI時代のブートローダ