Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
自己紹介 ● orumin – 学生 ● sepcamp2012, GSoC(now) ● twitter: @kotatsu_mi
Slide 2
Slide 2 text
自己紹介 ● orumin – 学生 ● sepcamp2012, GSoC(now) ● twitter: @kotatsu_mi ● 側転できなさそうな顔の人とか TL 大破とか
Slide 3
Slide 3 text
自己紹介 ● orumin – 学生 ● sepcamp2012, GSoC(now) ● twitter: @kotatsu_mi ● 側転できなさそうな顔の人とか TL 大破とか ● ておくれではない
Slide 4
Slide 4 text
ておくれではないので, みんなにわかりやすいネタ, やります 既に知ってたらごめんなさい
Slide 5
Slide 5 text
ておくれではないので, みんなにわかりやすいネタ, やります 既に知ってたらごめんなさい
Slide 6
Slide 6 text
UEFI
Slide 7
Slide 7 text
Introduction for developping UEFI app/driver
Slide 8
Slide 8 text
UEFI ● 初出 - “Play with UEFI” カーネル VM 関西 4 ● “ いじぇくと的ななにか” カーネル /VM 探検隊 第九回
Slide 9
Slide 9 text
UEFI ● ベタ C 移植 ? ● Python? ● EFI Protocol? ● なぞのシェル
Slide 10
Slide 10 text
UEFI ● わからん ● どう開発してるのか ● どう動くのか ● ておくれ
Slide 11
Slide 11 text
UEFI ● UEFI は真面目に利便性の高いもの ● ておくれてないよ !
Slide 12
Slide 12 text
UEFI( 加筆 ) ● そもそも UEFI とは, BIOS をおきかえるもの ● UEFI 自体にブートローダーやシェルのような ものが実装されている ● 自作のアプリケーション,ドライバが簡単に作 れ動かせる ← ココ重要
Slide 13
Slide 13 text
First Step
Slide 14
Slide 14 text
First Step ● まずは SDK のインストール 今回は UDK について説明します UDK は EDK(II) の stable で,現在 2014 が最新 (syuu1228 さん,情報提供ありがとうございます )
Slide 15
Slide 15 text
First Step $ mkdir ~/src $ cd ~/src $ svn co https://edk2.svn.sourceforge.net/svnroot/ edk2/trunk/edk2 $ make -C edk2/BaseTools $ cd ~/src/edk2 $ export EDK_TOOLS_PATH=$HOME/src/edk2/BaseTools $ source edksetup.sh BaseTools
Slide 16
Slide 16 text
FirstStep ● ${EDK_TOOLS_PATH}/Conf ● TOOLS_CHAIN_TAG 変数 ● ACTIVE_PLATFORM 変数
Slide 17
Slide 17 text
FirstStep ● ${EDK_TOOLS_PATH}/Conf/target.txt ● TOOLS_CHAIN_TAG 変数 -> GCC47 ● ACTIVE_PLATFORM 変数 -> FooPkg/FooPkg.dec
Slide 18
Slide 18 text
FirstStep ● ${EDK_TOOLS_PATH}/Conf/target.txt ● TOOLS_CHAIN_TAG 変数 -> GCC47 ● ACTIVE_PLATFORM 変数 -> FooPkg/FooPkg.dec ● 準備完了
Slide 19
Slide 19 text
FirstStep ● ${EDK_TOOLS_PATH}/Conf/target.txt ● TOOLS_CHAIN_TAG 変数 -> GCC47 ● ACTIVE_PLATFORM 変数 -> FooPkg/FooPkg.dec ● 準備完了 ● build コマンドでビルドしはじめる
Slide 20
Slide 20 text
Second Step
Slide 21
Slide 21 text
Second Step ● プロジェクトの設定 ● 設定ファイルは基本的には ini ファイルの変種
Slide 22
Slide 22 text
Second Step ● プロジェクトの設定 ● 設定ファイルは基本的には ini ファイルの変種 ● UNIX-Like OS で開発してても,滲み出る そこはかとない Windows っぽさ
Slide 23
Slide 23 text
Second Step ● *.dec [Defines] DEC_SPECIFICATION = 0x00010005 PACKAGE_NAME = AppPkg PACKAGE_GUID = B3E3D3D5-D62B-4497-A175-264F489D127E PACKAGE_VERSION = 0.01
Slide 24
Slide 24 text
Second Step ● たった 4 行 ● 設定ファイルのバージョン ● プロジェクト名 ● UUID ● プロジェクトのバージョン
Slide 25
Slide 25 text
Second Step ● *.dsc [Defines] PLATFORM_NAME = AppPkg PLATFORM_GUID = 0458dade-8b6e-4e45-b773-1b27cbda3e06 PLATFORM_VERSION = 0.01 DSC_SPECIFICATION = 0x00010006 OUTPUT_DIRECTORY = Build/AppPkg SUPPORTED_ARCHITECTURES = IA32|IPF|X64 BUILD_TARGETS = DEBUG|RELEASE SKUID_IDENTIFIER = DEFAULT
Slide 26
Slide 26 text
Second Step ● プロジェクト名 ● UUID(*.dec とは違うもの ) ● プロジェクトのバージョン ● 設定ファイルのバージョン ● ビルドの出力先 ● ターゲットアーキテクチャ ● ビルドターゲット
Slide 27
Slide 27 text
Second Step ● まだまだ続く
Slide 28
Slide 28 text
Second Step [LibraryClasses] UefiApplicationEntryPoint| MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf ShellCEntryLib| ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf UefiDriverEntryPoint| MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
Slide 29
Slide 29 text
Second Step ● この LibraryClasses セクションは, foo|path/to/libraryfolder という形 ● foo はなんでも良いけれど, UDK 内の既存プ ロジェクトに従ったほうが良い
Slide 30
Slide 30 text
Second Step ● 最初の 3 つはエントリポイントについての ライブラリをプロジェクトに読み込む ● これをしないとエントリポイントつくれない ● 3 つのエントリポイントの違いは後ほど
Slide 31
Slide 31 text
Second Step BaseLib|MdePkg/Library/BaseLib/BaseLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf MemoryAllocationLib| MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf UefiBootServicesTableLib| MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf UefiRuntimeServicesTableLib| MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
Slide 32
Slide 32 text
Second Step ● その他必要ライブラリのみなさん ● 必ずしもこれらが必要なわけではない ● UDK 内の既存プロジェクトとそのヘッダを 見てどんなユーティリティがあるか判断
Slide 33
Slide 33 text
No content
Slide 34
Slide 34 text
Second Step [Components] AppPkg/Applications/Hello/Hello.inf …
Slide 35
Slide 35 text
Second Step ● [Components] セクション ● プロジェクトを更にモジュール毎に分割した 小さいプロジェクトの設定ファイルのパス この設定ファイルは *.inf
Slide 36
Slide 36 text
Second Step ● dsc ファイルについて最後に ● libc とか web socket を使う場合だけ !include StdLib/StdLib.inc !include AppPkg/Applications/Sockets/Sockets.inc ● この 2 行で設定の読み込みが必要
Slide 37
Slide 37 text
Second Step
Slide 38
Slide 38 text
Second Step [Defines] INF_VERSION = 0x00010006 BASE_NAME = Hello FILE_GUID = a912f198-7f0e-4803-b908-b757b806ec83 MODULE_TYPE = UEFI_APPLICATION VERSION_STRING = 0.1 ENTRY_POINT = ShellCEntryLib
Slide 39
Slide 39 text
Second Step ● inf ファイルの [defines] セクション ● dsc の [defines] と大差なし ● ポイントは,ここで MODULE_TYPE と ENTRY_POINT を指定
Slide 40
Slide 40 text
Second Step ● MODULE_TYPE は UEFI_APPLICATION か UEFI_DRIVER ● ENTRY_POINT は dsc ファイルに書いて 読み込んだ 3 つ, ShellCLibEntryPoint UefiApplicationEntryPoint UefiDriverEntryPoint
Slide 41
Slide 41 text
Second Step [Sources] Hello.c [Packages] MdePkg/MdePkg.dec ShellPkg/ShellPkg.dec [LibraryClasses] UefiLib ShellCEntryLib
Slide 42
Slide 42 text
Second Step ● リンク / コンパイルするソース全て ● 使用するライブラリを含むパッケージの プロジェクト設定へのパス ● LibraryClasses ここでは, dsc に既に書いたので省略形で 記述
Slide 43
Slide 43 text
Second Step ● dsc の Components でモジュール分割するほどのプ ロジェクトでなければ, dsc のほうに MODULE_TYPE やら ENTRY_POINT や ら書いてしまって, inf には [Sources] だけというのも可能 ● inf を応用して,ソースコードだけ別フォルダに 分けるときに使うという使用方法もあり
Slide 44
Slide 44 text
エントリポイントについて UefiApplication 〜は UEFI の API 独自の作法に 従うエントリポイント EFI_IMAGE_HANDLE,EFI_SYSTEM_TABLE という型の引数で呼ばれる
Slide 45
Slide 45 text
エントリポイントについて ● ShellCLib 〜の場合は普通の main から スタート ● ほぼ完全にコード変更なしに pure C が動作 ● UEFI Protocol(API) を呼ぶのがちと面倒
Slide 46
Slide 46 text
エントリポイントについて ● UefiDriver 〜はいわずもがな, UEFI ドライバを記述するときの エントリポイント ● 引数は UefiApplication 〜と同様 ● ドライバはこれしかない ● UnEntryPoint の設定も必要
Slide 47
Slide 47 text
Let's coding
Slide 48
Slide 48 text
Let's coding ● さあ後はコーディングするだけ ! ● inf に適宜ソースファイル追加しつつ コーディングしましょう
Slide 49
Slide 49 text
Let's coding ● さあ後はコーディングするだけ ! ● inf に適宜ソースファイル追加しつつ コーディングしましょう ● Happy Hacking!!!
Slide 50
Slide 50 text
おわり
Slide 51
Slide 51 text
なワケないでショー !?
Slide 52
Slide 52 text
なワケないでショー !?
Slide 53
Slide 53 text
Let's coding ● UEFI Protocol について ● UEFI の API のこと ● なんで Protocol なんでしょうね ● データ駆動型 API です
Slide 54
Slide 54 text
Let's coding ● 基本的には, HandleProtocol() で特定の デバイス等の Handle を取得 ● その Handle を OpenProtocol() にぶちこんで Protocol 構造体にデータを詰め込んでもらう ● 構造体に詰められた関数ポインタを通して API コール
Slide 55
Slide 55 text
No content
Slide 56
Slide 56 text
Let's coding 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;
Slide 57
Slide 57 text
Let's coding 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 58
Slide 58 text
Let's coding 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 59
Slide 59 text
Let's coding ● gST,gRS,gBS … 既に宣言 ● gBS が特に重要 LocateHandle() , Open/CloseProtocol() 他にも LoadImage() , StartImage() ExitBootServices() 等 ● 最悪 EFI_SYMPLE_FILE_SYSTEM_PROTOCOL と EFI_BOOT_SERVICES だけでブートローダ書ける
Slide 60
Slide 60 text
● ドライバの場合,加えてヘッダで自身の プロトコルのデータ構造を公開 ● DRIVER_BINDING_PROTOCOL で プロトコルをデバイスに対して使えるかの チェック,プロトコル開始時の資源確保, プロトコル終了時の資源解放を記述
Slide 61
Slide 61 text
Let's coding ● 実際のコードを見てみよう https://github.com/tianocore/edk2-FatPkg *.dec と *.dsc と *.inf が設定, Fat.h に各種宣言, Fat.c が EntryPoint 他にも Fat.c でつかわれる Lock が Misc.c デバイスのアロケートを Init.c Read/Write を ReadWrite.c… という具合
Slide 62
Slide 62 text
おわりに ● 駆け足だったので伝わらない部分もあったはず ● スライド上げとくのでどうぞ読み直して下さい ● デモ用意できませんでした ● 最小限のプロジェクトのテンプレートを GitHub に上げとく ( 予定 )
Slide 63
Slide 63 text
おわりに ● UDK は VisualStudio でも使えます (Windows ユーザーさんどうぞ ) ● UNIX Like な OS で動作させる前提のツールは gnu-efi のほうが楽かもしれません GrowBuffer() や LocateHandlebyDiskSignature() とか ● rEFInd とか参考にしてね ! http://sourceforge.net/projects/refind/files/
Slide 64
Slide 64 text
余談 ● Hibernation 中の swap パーティションの snapshot を UEFI app で弄ったりして, secure boot の secure さを壊せるのでは ? https://lkml.org/lkml/2013/8/22/218 ● 発端 http://lists.opensuse.org/opensuse-kernel/ 2013-09/msg00068.html