Play with UEFI
Upcoming SlideShare
Loading in...5
×
 

Play with UEFI

on

  • 4,261 views

 

Statistics

Views

Total Views
4,261
Views on SlideShare
4,232
Embed Views
29

Actions

Likes
10
Downloads
15
Comments
0

1 Embed 29

https://twitter.com 29

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Play with UEFI Play with UEFI Presentation Transcript

  • PLAY WITH UEFI @syuu122813年2月16日土曜日
  • UEFI使ったことある人 ノ13年2月16日土曜日
  • UEFI APPLICATION書いたこと ある人 ノ13年2月16日土曜日
  • 今日は簡単なUEFI APPLICATIONを 書いて遊んでみようという話です13年2月16日土曜日
  • UEFIとは何か? • 90年代にIntelとHPにより開発された、IA32/IA64共通のブートシステム • PCに依然として残るレガシーな仕組みであるBIOSを置き換え • CPU非依存なアーキテクチャ • CPU非依存なドライバ • 128partition・over 2TBのディスクをサポートするGPTを採用 • ネットワーク対応などの多彩な機能に対応 • モジュラー型のデザイン • 高速起動にも寄与13年2月16日土曜日
  • (U)EFIの歴史1 • 1990年代にIntel・HPがIA64アーキテクチャを設計した時に、 IA32/IA64両方で使えるファームウェア仕様を作ったのが始 まり • IA64ではそれしかないので使われていたが、IA32では広まら ず • 例外:2006年にリリースされたIntel MacはEFI 1.10をベースに した独自ファームウェアを採用13年2月16日土曜日
  • (U)EFIの歴史2 • EFI specificationはIntelからUnified EFI Forumへ移管 →規格名がUEFIに・2.x系がリリース • 2009年頃から2TBの壁が問題視され始め、UEFI搭載PCが 普及しはじめる・OSも標準対応へ • 普通にその辺のヨ○バシでUEFI対応機買えるように←イ マココ!13年2月16日土曜日
  • MBRと2TBの壁 • MBRのパーティーションテーブルでは、開始セクタ値とセクタ数が 32bit(4G sectors) • 4G sectors * 512byte = 2TB! • パーティーションテーブル変えるかセクタサイズ変えるしかない→ 互換性無くなる • バッドノウハウで回避出来ないことも無いけど… • もうしんどいしGPTを前提としているUEFIに移行しようよ13年2月16日土曜日
  • MBRとGPTの比較 • MBRではパーティーション:4個→128個 • セクタアドレス長:32bit→64bit • パーティーションタイプ:1byte→16byte GUID • ブートフラグ:1byte→属性フラグ:8bytes • パーティーション名:72bytes UTF-16 • バックアップのパーティーションテーブル領域13年2月16日土曜日
  • GPT13年2月16日土曜日
  • GPT パーティションエントリ13年2月16日土曜日
  • UEFIの見た目 • 普通のBIOSみたいな起動画面である事が多い • デフォルト設定でOSが自動的にブートされる限り、特にBIOSブ ートとの見た目上の違いはない • 但し、よく見ると全然違う: • Boot ManagerというGRUBのブートメニューのようなものがある • UEFI Shellというコマンドプロンプトのようなシェルがある13年2月16日土曜日
  • メインメニュー13年2月16日土曜日
  • BOOT MANAGER ブート項目の選択画面。 OSは自分のブートローダをここに登録する13年2月16日土曜日
  • BOOT MAINTENANCE MANAGER メニューの編集、ロードするドライバの指 定、任意のファイルの実行など13年2月16日土曜日
  • UEFI SHELL コマンドプロンプト風のシェル 任意のOS起動などに使用13年2月16日土曜日
  • GRUB2 FOR UEFI13年2月16日土曜日
  • UEFIからのブート BootManagerの設定値がデフォルトの場合 • UEFIがHDDを検出、GPTをロード • EFI System Partitionを検索 • EFIBOOTBOOTX64.EFIをロード (32bit環境ならBOOTX86.EFI)13年2月16日土曜日
  • EFI SYSTEM PARTITION • パーティーションタイプGUIDがEFI System Partitionな FATファイルシステム • GPTにブートセクタは無い • ここからUEFIアプリケーションをロードする事により 起動13年2月16日土曜日
  • UEFI APPLICATION • 64bit protected modeのPEバイナリ (UEFIがx64版の場合) • 拡張子:.EFI • UEFI APIを利用して各種処理を実装13年2月16日土曜日
  • UEFIからのブート 厳密にはどうなっているか 以下のようなUEFI NVRAM variablesにより起動処理が制御される • Boot####:ロードするUEFI applicationのPATH・ 又はディスクのデバイスPATH • BootOrder:Boot####の試行順序(配列で指定) • BootNext:次回起動時にロードするBoot####(BootOrderより優 先、一度起動すると削除) • Timeout:設定秒数だけBoot Menuを表示(自動起動を遅延)13年2月16日土曜日
  • 設定例 • 起動まで10秒待つ • ubuntu→HDD→CDROM→Network→Shellの順で試行 • ファイル指定がないドライブはEFI System PartitionのEFIBOOTBOOTX64.EFIを探索13年2月16日土曜日
  • EFIBOOTMGR • efibootmgrでブートメニューを編集 • カーネルは/sys/firmware/efi/vars/・/sys/firmware/efi/efivars/経由でUEFI NVRAM variablesへのユーザランドからのアクセスを許可している13年2月16日土曜日
  • /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) ?A ?13年2月16日土曜日
  • UEFIの内部構造 PI specification UEFI specification UEFI APIs UEFI Services Device Apps Drivers Boot UEFI PEI DXE Bootl OS Manager oader Load drivers Load UEFI apps CPU init Chipset init Board init13年2月16日土曜日
  • UEFIの内部構造 PI specification UEFI specification 今日はここを見ていきます UEFI APIs UEFI Services Device Apps Drivers Boot UEFI PEI DXE Bootl OS Manager oader Load drivers Load UEFI apps CPU init Chipset init Board init13年2月16日土曜日
  • UEFI APPLICATIONの種類 • 二種類のUEFI Application • 通常のUEFI Application:終了時にExit()をコールし、 UEFI Shellなどに制御を戻す • OS Loader:終了時にExitBootServices()をコールし、 UEFIが利用していた資源を開放して制御をOSへ移す13年2月16日土曜日
  • MAIN() IN UEFI APPLICATION EFI_STATUS HelloMain ( IN EFI_HANDLE       ImageHandle,             IN EFI_SYSTEM_TABLE *SystemTable) 引数は2個(ImageHandle、SystemTable) ImageHandleはロードされたUEFI Applicationのイメージファイルに対するハンドル SystemTableを経由して全てのUEFI APIへアクセス13年2月16日土曜日
  • #define EFI_2_30_SYSTEM_TABLE_REVISION ((2<<16) | (30)) #define EFI_2_20_SYSTEM_TABLE_REVISION ((2<<16) | (20)) #define EFI_2_10_SYSTEM_TABLE_REVISION ((2<<16) | (10)) #define EFI_2_00_SYSTEM_TABLE_REVISION ((2<<16) | (00)) UEFI SYSTEM TABLE #define EFI_1_10_SYSTEM_TABLE_REVISION ((1<<16) | (10)) #define EFI_1_02_SYSTEM_TABLE_REVISION ((1<<16) | (02)) #define EFI_SYSTEM_TABLE_REVISION EFI_2_30_SYSTEM_TABLE_REVISION #define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION #define EFI_SYSTEM_TABLE_REVISION EFI_2_31_SYSTEM_TABLE_REVISION typedef struct { EFI_TABLE_HEADER Hdr; CHAR16 *FirmwareVendor; UINT32 FirmwareRevision; EFI_HANDLE ConsoleInHandle; EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; EFI System Table EFI_HANDLE ConsoleOutHandle; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; EFI_HANDLE StandardErrorHandle; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr; EFI_RUNTIME_SERVICES *RuntimeServices; 80 EFI_BOOT_SERVICES June 27, 2012 *BootServices; Version 2.3.1, Errata C UINTN NumberOfTableEntries; EFI_CONFIGURATION_TABLE *ConfigurationTable; } EFI_SYSTEM_TABLE; Parameters UEFI Applicationに対して公開するインタフェースが全て Hdr The table header for the EFI System Table. This header contains the EFI_SYSTEM_TABLE_SIGNATURE and EFI_SYSTEM_TABLE_REVISION values along with the size 詰め込まれた構造体 of the EFI_SYSTEM_TABLE structure and a 32-bit CRC to verify that the contents of the EFI System Table are valid. FirmwareVendor A pointer to a null terminated string that identifies the vendor that produces the system firmware for the platform.13年2月16日土曜日 FirmwareRevision A firmware vendor specific value that identifies the revision of
  • CONOUT, CONIN, STDERR #include <Library/UefiApplicationEntryPoint.h> #include <Library/UefiLib.h> EFI_STATUS EFIAPI UefiMain (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Hello Worldrn"); return EFI_SUCCESS; } •コンソールへの入出力API •文字エンコーディングはUTF-16を使用13年2月16日土曜日
  • RUNTIME SERVICES • ExitBootServices()後もUEFIがOSに対して提供するサービス • 最低限の機能のみ • Time (GetTime, SetTime...) • Virtual Memory (SetirtualAddressMap...) • Variable Services (GetVariable...) • Miscellaneous Services(ResetSystem...)13年2月16日土曜日
  • 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...)13年2月16日土曜日
  • PROCOTOLS • ネットワークプロトコルスタックのことではない • UEFI上で提供される様々なサービスの事 • UEFI Driverを実装しUEFIへロードする事により、自作の Protocolを提供する事も可能13年2月16日土曜日
  • 定義されているPROTOCOL • EFI Loaded Image • USB Support • Device Path Protocol • Debugger Support • UEFI Driver Model • Compression Algorithm • Console Support • ACPI Protocols • Media Access • TCP/IP, IPSec, FTP • PCI Bus Support • ARP & DHCP • SCSI Driver Models and Bus Support • UDP & MTFTP • iSCSI Boot • etc...13年2月16日土曜日
  • PROTOCOL利用例 #define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID { 0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } EFI_GUID gEfiSimpleFileSystemProtocolGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; EFI_FILE_HANDLE Root; EFI_FILE_HANDLE CurDir; EFI_FILE_HANDLE FileHandle; CHAR16 *FileName = L”hoge.txt”; gBS->HandleProtocol ( DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, &Vol ); Vol->OpenVolume (Vol, &Root); CurDir->Open ( CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0 ); •ProtocolのHandleを経由してAPIコール13年2月16日土曜日
  • よくみると • さっき出てきたConOutとかもProtocol • HandleProtocolとかしなくてもすぐ呼べるように SystemTableにポインタが最初から用意されてるだけ13年2月16日土曜日
  • UEFIのSDK • EDK II:オープンソースで開発されているUEFI実装で、デファクトスタンダード ググってすぐ出てくるのはこれ。 但し、ビルド方法のドキュメントをよく見るとtrunkをチェックアウトしている。 そして、trunkだと色々と地雷があって頻繁に踏む… • UDK2010:Intelが作っているEDK IIのstableリリース。 地雷を踏みたくなかったらこっちを使ったほうが良いのだが、EDK IIにしか無い機能も色々 と存在。 • gnu-efi:EDK IIはUEFIファームウェアのソースコードを全て含んでいるが、こちらはUEFI Applicationを実装するためだけのLightweightな実装。 シンプル簡単お手軽で普通のMakefileも使えるし、LinuxやOSXユーザにとってはこっちの方 が使いやすそう。 …だが、これでも色々と踏んだ…13年2月16日土曜日
  • OVMF FOR QEMU/KVM • EDK II上でビルドできるQEMU・KVM用のUEFI実装 • コマンド一発でビルド&実行まで簡単に出来る • QEMUでdebugconを有効にするとUEFIからのデバッグ出力が得られる • シリアルコンソールを有効にするとVGA側と同等の出力が得られる • ちょっと設定すればgdbも繋がるはず • stable版じゃないのが激しく気になるけどそんなもん存在しないので見なか ったことにするしか…13年2月16日土曜日
  • EDK IIにしかないもの • ここまで見てきたように、UEFIのAPIは標準CのAPIと互換性 がない • 通常のOSで動作しているアプリケーションを移植するのが 面倒 • libcとPOSIX APIの一部とBSD Socketを移植してしまえ! →Python移植できちゃいました →mrubyも移植できちゃいました13年2月16日土曜日
  • EDK II使ってTWITTERクライ アントを移植してみた • 組み込みとかで使いやすそうなPureC実装のTwitterクライ アント「Twitter4C」を利用 https://github.com/Plemling138/Twitter4C • Makefileじゃなくて独自形式の.infというビルドスクリプト を定義 • ダメそうなところを一つづつ潰して行ったら動いた https://gist.github.com/syuu1228/496539013年2月16日土曜日
  • ダメポイント1 • このプログラム、メッセージが日本語だ… if(access_token == NULL) { //リクエストトークン取得 if(errcode = Twitter_GetRequestToken(c, r), errcode < 0) { - printf("リクエストトークンの取得でエラーが発生していますn"); - printf("エラーコード:%dn", errcode); + printf("error occured during get request tokenn"); + printf("error code:%dn", errcode); exit(0); }13年2月16日土曜日
  • ダメポイント2 • なんか知らんけどTRUE/FALSEがredefinedになるので +#if 0 #define TRUE 1 #define FALSE 0 +#endif13年2月16日土曜日
  • ダメポイント3 • 微妙な型のズレ //時間を取得してタイムスタンプと一意な値をセット gettimeofday(&tv, NULL); - sprintf(tstamp, "%ld", tv.tv_sec); + sprintf(tstamp, "%d", tv.tv_sec); - sprintf(nonce_tmp, "%ld", tv.tv_usec); + sprintf(nonce_tmp, "%d", tv.tv_usec); base64_encode(nonce_tmp, strlen(nonce_tmp), nonce, 128); URLEncode(nonce, nonce_urlenc);13年2月16日土曜日
  • ダメポイント4 • なんか知らんけどリクエストトークンの取得に失敗してしまって、認証のところまで行けない • めんどくせぇからアクセストークンとか一切をソースコードにベタ埋め込みしてみた a->user_id = "ほげほげ"; a->access_token = "ほげほげ"; a->access_secret = "ほげほげ"; a->pin = "2630697";13年2月16日土曜日
  • ハマりポイント • X64で試してたら、UEFI Application側のバイナリのABIに誤りでもあ るのか、gethostbyname()するとUEFI側が の死を遂げるとかいう悲 惨な目にあった • ググってたらビルドオプション変えたら動いたとか、IA32なら行け たとか書いてあったので順に試した Re: [edk2] OVMF x64 - CR has Bad Signature:http://bit.ly/Yi3N8Y • ビルドオプション変えてもダメだったので、IA32にした(これだと 実機のUEFIはX64なので困るんだが。。。。13年2月16日土曜日
  • ツイートできた! • OSを起動しなくてもツイート出来る そう、UEFIならね • もっと頑張ればPythonやmruby経由でもツイート出来る はず13年2月16日土曜日
  • まとめ • UEFIならリアルモードのアセンブリゴリゴリ書いた り、サイズに悩んだりしないでも気軽にCでOSレス環 境向けのプログラムを書くことが出来ます • EDK IIを使えば標準C APIを使ってプログラミング出来 ます • なので、みんなも色々移植してみよう13年2月16日土曜日