Suche senden
Hochladen
UEFIによるELFバイナリの起動
•
Als PPTX, PDF herunterladen
•
5 gefällt mir
•
5,106 views
uchan_nos
Folgen
Write your own bootloader that handles ELF binaries using UEFI.
Weniger lesen
Mehr lesen
Software
Melden
Teilen
Melden
Teilen
1 von 29
Jetzt herunterladen
Empfohlen
UEFI時代のブートローダ
UEFI時代のブートローダ
Takuya ASADA
OSを手作りするという趣味と仕事
OSを手作りするという趣味と仕事
uchan_nos
30分で分かる!OSの作り方 ver.2
30分で分かる!OSの作り方 ver.2
uchan_nos
ゼロからはじめるKVM超入門
ゼロからはじめるKVM超入門
VirtualTech Japan Inc.
AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較
beyond Co., Ltd.
C++でできる!OS自作入門
C++でできる!OS自作入門
uchan_nos
UEFIベアメタルプログラミング
UEFIベアメタルプログラミング
Yuma Ohgami
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
モノビット エンジン
Empfohlen
UEFI時代のブートローダ
UEFI時代のブートローダ
Takuya ASADA
OSを手作りするという趣味と仕事
OSを手作りするという趣味と仕事
uchan_nos
30分で分かる!OSの作り方 ver.2
30分で分かる!OSの作り方 ver.2
uchan_nos
ゼロからはじめるKVM超入門
ゼロからはじめるKVM超入門
VirtualTech Japan Inc.
AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較
beyond Co., Ltd.
C++でできる!OS自作入門
C++でできる!OS自作入門
uchan_nos
UEFIベアメタルプログラミング
UEFIベアメタルプログラミング
Yuma Ohgami
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
モノビット エンジン
UEFIで始めるLinux From Scratch
UEFIで始めるLinux From Scratch
Yuma Ohgami
DockerとPodmanの比較
DockerとPodmanの比較
Akihiro Suda
10GbE時代のネットワークI/O高速化
10GbE時代のネットワークI/O高速化
Takuya ASADA
AS45679 on FreeBSD
AS45679 on FreeBSD
Tomocha Potter
CXL_説明_公開用.pdf
CXL_説明_公開用.pdf
Yasunori Goto
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
Kuniyasu Suzaki
仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング
Takuya ASADA
Deflate
Deflate
7shi
レシピの作り方入門
レシピの作り方入門
Nobuhiro Iwamatsu
その ionice、ほんとに効いてますか?
その ionice、ほんとに効いてますか?
Narimichi Takamura
大規模サービスを支えるネットワークインフラの全貌
大規模サービスを支えるネットワークインフラの全貌
LINE Corporation
30分で分かる!OSの作り方
30分で分かる!OSの作り方
uchan_nos
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門
Hirotaka Kawata
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線
Motonori Shindo
Ethernetの受信処理
Ethernetの受信処理
Takuya ASADA
ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!
Mr. Vengineer
Topology Managerについて / Kubernetes Meetup Tokyo 50
Topology Managerについて / Kubernetes Meetup Tokyo 50
Preferred Networks
Glibc malloc internal
Glibc malloc internal
Motohiro KOSAKI
SSH力をつけよう
SSH力をつけよう
(^-^) togakushi
NVIDIA GPUで作るHeadless X11 Linux
NVIDIA GPUで作るHeadless X11 Linux
Tomoki SHISHIKURA
Serfが面白いと俺の中で話題にwwwwww 【改訂版】
Serfが面白いと俺の中で話題にwwwwww 【改訂版】
Masahito Zembutsu
FreeBSDで行こう for small server
FreeBSDで行こう for small server
Tatsumi Naganuma
Weitere ähnliche Inhalte
Was ist angesagt?
UEFIで始めるLinux From Scratch
UEFIで始めるLinux From Scratch
Yuma Ohgami
DockerとPodmanの比較
DockerとPodmanの比較
Akihiro Suda
10GbE時代のネットワークI/O高速化
10GbE時代のネットワークI/O高速化
Takuya ASADA
AS45679 on FreeBSD
AS45679 on FreeBSD
Tomocha Potter
CXL_説明_公開用.pdf
CXL_説明_公開用.pdf
Yasunori Goto
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
Kuniyasu Suzaki
仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング
Takuya ASADA
Deflate
Deflate
7shi
レシピの作り方入門
レシピの作り方入門
Nobuhiro Iwamatsu
その ionice、ほんとに効いてますか?
その ionice、ほんとに効いてますか?
Narimichi Takamura
大規模サービスを支えるネットワークインフラの全貌
大規模サービスを支えるネットワークインフラの全貌
LINE Corporation
30分で分かる!OSの作り方
30分で分かる!OSの作り方
uchan_nos
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門
Hirotaka Kawata
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線
Motonori Shindo
Ethernetの受信処理
Ethernetの受信処理
Takuya ASADA
ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!
Mr. Vengineer
Topology Managerについて / Kubernetes Meetup Tokyo 50
Topology Managerについて / Kubernetes Meetup Tokyo 50
Preferred Networks
Glibc malloc internal
Glibc malloc internal
Motohiro KOSAKI
SSH力をつけよう
SSH力をつけよう
(^-^) togakushi
NVIDIA GPUで作るHeadless X11 Linux
NVIDIA GPUで作るHeadless X11 Linux
Tomoki SHISHIKURA
Was ist angesagt?
(20)
UEFIで始めるLinux From Scratch
UEFIで始めるLinux From Scratch
DockerとPodmanの比較
DockerとPodmanの比較
10GbE時代のネットワークI/O高速化
10GbE時代のネットワークI/O高速化
AS45679 on FreeBSD
AS45679 on FreeBSD
CXL_説明_公開用.pdf
CXL_説明_公開用.pdf
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング
Deflate
Deflate
レシピの作り方入門
レシピの作り方入門
その ionice、ほんとに効いてますか?
その ionice、ほんとに効いてますか?
大規模サービスを支えるネットワークインフラの全貌
大規模サービスを支えるネットワークインフラの全貌
30分で分かる!OSの作り方
30分で分かる!OSの作り方
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線
Ethernetの受信処理
Ethernetの受信処理
ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!
Topology Managerについて / Kubernetes Meetup Tokyo 50
Topology Managerについて / Kubernetes Meetup Tokyo 50
Glibc malloc internal
Glibc malloc internal
SSH力をつけよう
SSH力をつけよう
NVIDIA GPUで作るHeadless X11 Linux
NVIDIA GPUで作るHeadless X11 Linux
Ähnlich wie UEFIによるELFバイナリの起動
Serfが面白いと俺の中で話題にwwwwww 【改訂版】
Serfが面白いと俺の中で話題にwwwwww 【改訂版】
Masahito Zembutsu
FreeBSDで行こう for small server
FreeBSDで行こう for small server
Tatsumi Naganuma
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
Masaki Muranaka
play framework 勉強会 in 関西
play framework 勉強会 in 関西
Shinichi Kozake
Slide
Slide
Kazki Matsumoto
POSIX Threads
POSIX Threads
Masato HORINOUCHI
ライブストリーミングの基礎知識
ライブストリーミングの基礎知識
kumaryu
あなたのAppleにもEFIモンスターはいませんか? by Pedro Vilaça - CODE BLUE 2015
あなたのAppleにもEFIモンスターはいませんか? by Pedro Vilaça - CODE BLUE 2015
CODE BLUE
openstack+cephインテグレーション
openstack+cephインテグレーション
OSSラボ株式会社
LPICレベル1技術解説セミナー(2012/11/11)
LPICレベル1技術解説セミナー(2012/11/11)
Kazuko Itoda
OSSライセンス入門
OSSライセンス入門
KageShiron
最新UE4タイトルでのローカライズ事例 (UE4 Localization Deep Dive)
最新UE4タイトルでのローカライズ事例 (UE4 Localization Deep Dive)
エピック・ゲームズ・ジャパン Epic Games Japan
Open vSwitchソースコードの全体像
Open vSwitchソースコードの全体像
Sho Shimizu
初心者がOpenIndianaで自宅サーバを作ったよって話
初心者がOpenIndianaで自宅サーバを作ったよって話
Masataka Tsukamoto
OSvの概要と実装
OSvの概要と実装
Takuya ASADA
Composer による依存管理 と Packagist によるライブラリの公開
Composer による依存管理 と Packagist によるライブラリの公開
Shogo Kawahara
CMSI計算科学技術特論B(15) インテル Xeon Phi コプロセッサー向け最適化、並列化概要 1
CMSI計算科学技術特論B(15) インテル Xeon Phi コプロセッサー向け最適化、並列化概要 1
Computational Materials Science Initiative
Osoljp201204
Osoljp201204
Masataka Tsukamoto
Bsd suki
Bsd suki
yamori813
Fn project爆誕
Fn project爆誕
Hiroshi Hayakawa
Ähnlich wie UEFIによるELFバイナリの起動
(20)
Serfが面白いと俺の中で話題にwwwwww 【改訂版】
Serfが面白いと俺の中で話題にwwwwww 【改訂版】
FreeBSDで行こう for small server
FreeBSDで行こう for small server
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
play framework 勉強会 in 関西
play framework 勉強会 in 関西
Slide
Slide
POSIX Threads
POSIX Threads
ライブストリーミングの基礎知識
ライブストリーミングの基礎知識
あなたのAppleにもEFIモンスターはいませんか? by Pedro Vilaça - CODE BLUE 2015
あなたのAppleにもEFIモンスターはいませんか? by Pedro Vilaça - CODE BLUE 2015
openstack+cephインテグレーション
openstack+cephインテグレーション
LPICレベル1技術解説セミナー(2012/11/11)
LPICレベル1技術解説セミナー(2012/11/11)
OSSライセンス入門
OSSライセンス入門
最新UE4タイトルでのローカライズ事例 (UE4 Localization Deep Dive)
最新UE4タイトルでのローカライズ事例 (UE4 Localization Deep Dive)
Open vSwitchソースコードの全体像
Open vSwitchソースコードの全体像
初心者がOpenIndianaで自宅サーバを作ったよって話
初心者がOpenIndianaで自宅サーバを作ったよって話
OSvの概要と実装
OSvの概要と実装
Composer による依存管理 と Packagist によるライブラリの公開
Composer による依存管理 と Packagist によるライブラリの公開
CMSI計算科学技術特論B(15) インテル Xeon Phi コプロセッサー向け最適化、並列化概要 1
CMSI計算科学技術特論B(15) インテル Xeon Phi コプロセッサー向け最適化、並列化概要 1
Osoljp201204
Osoljp201204
Bsd suki
Bsd suki
Fn project爆誕
Fn project爆誕
Mehr von uchan_nos
MikanOSと自作CPUをUSBで接続する
MikanOSと自作CPUをUSBで接続する
uchan_nos
小型安価なFPGAボードの紹介と任意波形発生器
小型安価なFPGAボードの紹介と任意波形発生器
uchan_nos
トランジスタ回路:エミッタ接地増幅回路
トランジスタ回路:エミッタ接地増幅回路
uchan_nos
OpeLa: セルフホストなOSと言語処理系を作るプロジェクト
OpeLa: セルフホストなOSと言語処理系を作るプロジェクト
uchan_nos
自作言語でお絵描き
自作言語でお絵描き
uchan_nos
OpeLa 進捗報告 at 第23回自作OSもくもく会
OpeLa 進捗報告 at 第23回自作OSもくもく会
uchan_nos
サイボウズ・ラボへ転籍して1年を振り返る
サイボウズ・ラボへ転籍して1年を振り返る
uchan_nos
USB3.0ドライバ開発の道
USB3.0ドライバ開発の道
uchan_nos
Security Nextcamp remote mob programming
Security Nextcamp remote mob programming
uchan_nos
Langsmith OpeLa handmade self-hosted OS and LPS
Langsmith OpeLa handmade self-hosted OS and LPS
uchan_nos
OpeLa セルフホストなOSと言語処理系の自作
OpeLa セルフホストなOSと言語処理系の自作
uchan_nos
自動でバグを見つける!プログラム解析と動的バイナリ計装
自動でバグを見つける!プログラム解析と動的バイナリ計装
uchan_nos
1を書いても0が読める!?隠れた重要命令INVLPG
1を書いても0が読める!?隠れた重要命令INVLPG
uchan_nos
レガシーフリーOSに必要な要素技術 legacy free os
レガシーフリーOSに必要な要素技術 legacy free os
uchan_nos
Building libc++ for toy OS
Building libc++ for toy OS
uchan_nos
プランクトンサミットの歴史2019
プランクトンサミットの歴史2019
uchan_nos
Introduction of security camp 2019
Introduction of security camp 2019
uchan_nos
Timers
Timers
uchan_nos
USB3 host driver program structure
USB3 host driver program structure
uchan_nos
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
uchan_nos
Mehr von uchan_nos
(20)
MikanOSと自作CPUをUSBで接続する
MikanOSと自作CPUをUSBで接続する
小型安価なFPGAボードの紹介と任意波形発生器
小型安価なFPGAボードの紹介と任意波形発生器
トランジスタ回路:エミッタ接地増幅回路
トランジスタ回路:エミッタ接地増幅回路
OpeLa: セルフホストなOSと言語処理系を作るプロジェクト
OpeLa: セルフホストなOSと言語処理系を作るプロジェクト
自作言語でお絵描き
自作言語でお絵描き
OpeLa 進捗報告 at 第23回自作OSもくもく会
OpeLa 進捗報告 at 第23回自作OSもくもく会
サイボウズ・ラボへ転籍して1年を振り返る
サイボウズ・ラボへ転籍して1年を振り返る
USB3.0ドライバ開発の道
USB3.0ドライバ開発の道
Security Nextcamp remote mob programming
Security Nextcamp remote mob programming
Langsmith OpeLa handmade self-hosted OS and LPS
Langsmith OpeLa handmade self-hosted OS and LPS
OpeLa セルフホストなOSと言語処理系の自作
OpeLa セルフホストなOSと言語処理系の自作
自動でバグを見つける!プログラム解析と動的バイナリ計装
自動でバグを見つける!プログラム解析と動的バイナリ計装
1を書いても0が読める!?隠れた重要命令INVLPG
1を書いても0が読める!?隠れた重要命令INVLPG
レガシーフリーOSに必要な要素技術 legacy free os
レガシーフリーOSに必要な要素技術 legacy free os
Building libc++ for toy OS
Building libc++ for toy OS
プランクトンサミットの歴史2019
プランクトンサミットの歴史2019
Introduction of security camp 2019
Introduction of security camp 2019
Timers
Timers
USB3 host driver program structure
USB3 host driver program structure
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
UEFIによるELFバイナリの起動
1.
UEFIによる ELFバイナリの起動 @uchan_nos 2017年9月18日,第8回 自作OSもくもく会
2.
このスライドの目標 ELFバイナリ(自作OS)を • Grubなどの既存ブートローダの力を借りず UEFIでブートさせてみたい人が • 実際のブートローダのコードを読めるようになる こと.
3.
ELF : Executable
and Linking Format • a.out や COFF とかの仲間 • 現在の Unix, Linux での標準 • オブジェクトファイル,実行可能ファイルどちらもOK • ツールチェーンで良くサポートされている • a.out や COFF に比べ柔軟 • a.out には text, bss, data セクションしかない. C++ のコンストラクタや例外テーブルとかサポートできない. • COFF は a.out の拡張.でも,いろいろ制限がある. • ELF は柔軟で,新しい言語とかのサポートがしやすい
4.
ELF ファイルフォーマット • ELFヘッダ、SHT
、PHT 、セクション群からなる • SHT:セクション・ヘッダ・テーブル • PHT:プログラム・ヘッダ・テーブル • セクション:.text, .data, .bss, .shstrtab など • 詳しくは 『リンカ・ローダ実践開発テクニック』坂井弘亮, 2010 ELFヘッダ PHT SHT セクション
5.
ELF64ヘッダフォーマット off field 意味 0x00
e_ident 先頭4バイトは 0x7f, ‘E’, ‘L’, ‘F’ 0x10 e_type ファイルタイプ ET_EXEC, ET_REL など 0x12 e_machine EM_386 など 0x14 e_version ファイルバージョン 0x18 e_entry エントリポイントのアドレス 0x20 e_phoff プログラムヘッダテーブルのファイル位置 0x28 e_shoff セクションヘッダテーブルのファイル位置 0x30 e_flags 未使用 0x34 e_ehsize ELF ヘッダサイズ 0x36 … 0x3e e_shstrndx セクション名格納用セクションの番号 ELFヘッダ PHT SHT セクション
6.
基本となるアイデア • ELFファイルを適当なアドレス (ADDR_FOO)に配置 • 初期化 •
.bssを0クリアしたり • グローバル変数のコンストラクタを呼 び出したり • ADDR_FOO+e_entryにジャンプ メモリ ELFファイル ADDR_FOO +e_entry .text
7.
問題:空きメモリはどこにある? • マシンごとにいろいろ違う • アーキテクチャ(x86,ARM) •
搭載メモリ量 • UEFIファームウェアの実装・バージョン • 当然,メモリマップは異なる • メモリマップ:メモリのどこに,何があるか • UEFI Memory Map メモ http://uchan.hateblo.jp/entry/2017/07/18/231528 • お行儀よくするためには • メモリマップを取得して • ELFファイルが乗る大きさの空き領域を探す
8.
メモリマップ実例 使用用途 開始アドレス ページ数 0
EfiBootServicesCode 00000000 1 1 EfiConventionalMemory 00001000 9F 2 EfiConventionalMemory 00100000 700 3 EfiACPIMemoryNVS 00800000 8 4 EfiConventionalMemory 00808000 8 5 EfiACPIMemoryNVS 00810000 8 6 EfiConventionalMemory 00818000 8 7 EfiACPIMemoryNVS 00820000 E0 8 EfiBootServicesData 00900000 A00 … 太字:ExitBootServices()の呼出し後に自由に使えるメモリ領域
9.
実行可能ファイルとアドレス • 一般に,オブジェクトファイルをリンクすると,アドレスが固 定化される • というより,アドレスを固定化する作業=リンク •
しかし,空き領域のアドレスは固定でない • →困った!
10.
2つの解決策 • 常に空いてる固定領域があると仮定する • 手持ちのマシンで確認した感じでは, 0x00100000(1MiB)から数MBは空いてるっぽい •
位置非依存の実行可能ファイルを生成する • Position Independent Executable • どこに配置しても動く • clang -fPIE -wl,-pie
11.
解決策:空き領域を仮定 • 手持ちのマシンで確認した感じでは, 0x00100000(1MiB)から数MBは空いてるっぽい • どんなマシンでも空いているかは不明 •
0x00100000に配置する設定でリンク • UEFIが提供する,指定アドレスにメモリを確保するAPIを使い, 0x00100000を先頭とするメモリ領域を割り当てる • 割り当てられなかったらあきらめる
12.
解決策:位置非依存実行可能ファイル • PIEでコンパイル&リンクすると,どこに配置しても動くよう に,相対ジャンプとかを使った機械語になる • どうしても無理なものもあり,リロケーションが必須 •
.ctors セクション • .ctors には,初期化関数のアドレスが格納されている • PIEモードではリンク時にアドレスは決まらない • データのアドレス • 文字列リテラルのアドレス,グローバル変数のアドレスなど • 関数じゃないので,相対ジャンプではどうしようもできない
13.
.ctorsについて • ctors =
Contructors の略 • dtors = Destructors • コンストラクタとは,変数の初期化用関数のこと • 変数を「組み立てる(construct)」もの • std::vector<int> numbers(128); • こう書くと,コンストラクタが引数128で呼ばれ, 要素数128の整数配列が生成される. • グローバル変数のコンストラクタは メイン関数を実行する前に呼ばないといけない • グローバル変数の初期値をメイン関数実行前に設定するのと同じ理由.
14.
UEFIブートローダー
15.
UEFIとは • Unified Extensible
Firmware Interface • Unified:各メーカーで統一された規格 • Extensible:あとあと拡張しやすい規格 • Firmware Interface:ファームウェアとOSのインターフェース • BIOSを置き換えるファームウェアインターフェースの規格 • IntelとHPが開発したものが元となっている. • インターフェースなので,プロセッサ非依存. • 実装はいろいろ.「OVMF」はオープンソース実装 • 今のPCは既にUEFIに置き換わっている • BIOSエミュレーションがある機種もある
16.
BIOS時代のブートローダー • 512バイトのブートレコード • 16ビット実アドレスモード&アセンブラで頑張る •
保護モード,IA32eモードの遷移は自力で. • ※IA32eモード:64ビットモード • ファイルシステムの解析も自力 • USBメモリが使えるかは機種依存
17.
UEFI時代のブートローダー • サイズ制限はない • 最初からIA32eモードで起動する •
UEFIが64ビットUEFIの場合. • 最初からC言語で書ける! • FATファイルシステムは標準装備 • USBメモリは標準サポート OVMF搭載 MinnowBoard Turbot
18.
UEFIアプリの自動起動 • UEFIアプリ • UEFIの作法にのっとって作ったアプリ •
中身はPEバイナリ • ブートローダーもUEFIアプリとして作る • 自動起動 • USBメモリをFATでフォーマット • 固定パスにUEFIアプリを配置 • /EFI/BOOT/BOOTX64.EFI
19.
ブートローダーのコード解説 概要 • 参考文献:EDK II
で UEFI アプリケーションを作る • http://osdev-jp.readthedocs.io/ja/latest/2017/create-uefi-app-with-edk2.html • ソース:https://github.com/uchan-nos/edk2/tree/bootloader/MyBootLoader • ファイル構成 • MyBootLoader.dsc:パッケージ記述ファイル • MyBootLoader.dec:パッケージ宣言ファイル • Loader.inf:モジュール定義ファイル • Loader.c:メイン関数を含むソースコード • *.c:その他ソースコード
20.
ブートローダーのコード解説 処理の流れ(本質のところだけ) • グラフィックモードを取得(後でカーネルに渡すため) • カーネルファイルを開く •
ファイルの大きさだけメモリを確保 • ファイルを読み込む • グローバル変数のコンストラクタを呼ぶ • メモリマップを得る • ブートサービスを抜ける • エントリポイントにジャンプ
21.
グラフィックモードを取得 EFI_STATUS EFIAPI UefiMain(…) { //
コンソールを最大サイズにする gST->ConOut->SetMode(gST->ConOut, FindLargestConMode()); // グラフィックモードを取得 struct GraphicMode GraphicMode; GetGraphicMode(ImageHandle, &GraphicMode); • 沢山表示できるように,コンソールサイズを最大にする. • カーネルに渡すためのグラフィックモードを得る. (画面サイズやピクセルフォーマットなど)
22.
カーネルファイルを開く // ルートディレクトリを開く EFI_FILE_PROTOCOL *RootDir
= NULL; OpenFileProtocolForThisAppRootDir(ImageHandle, &RootDir); // カーネルファイルを開く UINTN KernelFileSize; EFI_FILE_PROTOCOL *KernelFile; OpenFileForRead(RootDir, L"kernel.elf", &KernelFile, &KernelFileSize); • 起動パーティションのルートディレクトリを開く. • ルートディレクトリ直下の kernel.elf を開く. • ファイルサイズが KernelFileSize に書かれる.
23.
ファイルの大きさだけメモリを確保 // 0x100000からメモリを確保 EFI_PHYSICAL_ADDRESS KernelFileAddr
= 0x00100000lu; gBS->AllocatePages( AllocateAddress, EfiLoaderData, (KernelFileSize + 4095) / 4096, &KernelFileAddr); • 0x100000を先頭としたメモリ領域を確保. • 確保するメモリタイプはEfiLoaderData • (KernelFileSize + 4095) / 4096 でページ数を計算.
24.
ファイルを読み込む KernelFile->Read(KernelFile, &KernelFileSize, (VOID*)KernelFileAddr); //
ELFのマジックナンバを確認 Elf64_Ehdr *Ehdr = (Elf64_Ehdr*)KernelFileAddr; if (AsciiStrnCmp((CHAR8*)Ehdr->e_ident, "x7f" "ELF", 4) != 0) { Print(L"Kernel file is not elf.n"); return EFI_LOAD_ERROR; } • 確保したメモリ領域にファイル全体を読み込む • マジックナンバでEFLファイルであることを確認
25.
グローバル変数のコンストラクタを呼ぶ typedef void (CtorType)(void); Elf64_Shdr
*CtorsSection = Elf64_FindSection(Ehdr, ".ctors"); for (UINT64 *Ctor = (UINT64*)CtorsSection->sh_addr; Ctor < (UINT64*)(CtorsSection->sh_addr + CtorsSection->sh_size); ++Ctor) { CtorType *F = (CtorType*)*Ctor; F(); } • .ctorsセクションの内容は,64ビット整数の配列 • 配列の要素は初期化関数のアドレス
26.
補足:ELFのセクションヘッダ ELFヘッダ PHT SHT セクション .ctors sh_addr sh_size ctor0のアドレス ctor1のアドレス ctorNのアドレス セクションの 先頭アドレス セクションの 大きさ(バイト)
27.
メモリマップを得る // メモリマップを書き込むためのメモリを確保 struct MemoryMap
MemoryMap; AllocateMemoryMap(&MemoryMap, 4096); // メモリマップを取得 GetMemoryMap(&MemoryMap); • メモリマップ用には4KiBもあれば十分. • メモリマップの1行につき40バイト程度必要. • 余程のことがなければ100行を超えないだろう…
28.
ブートサービスを抜ける Status = gBS->ExitBootServices(ImageHandle,
MemoryMap.MapKey); if (EFI_ERROR(Status)) { Status = GetMemoryMap(&MemoryMap); if (EFI_ERROR(Status)) { return Status; } Status = gBS->ExitBootServices(ImageHandle, MemoryMap.MapKey); if (EFI_ERROR(Status)) { return Status; } } • 前回のメモリマップの取得からExitBootServicesの呼び出しの 間にメモリマップが変わると,ExitBootServicesが失敗する • 失敗したら,再度メモリマップを取得すればOK
29.
エントリポイントにジャンプ // カーネルパラメータを準備 struct BootParam
BootParam; … BootParam.graphic_mode = &GraphicMode; // エントリポイントにジャンプ EntryPoint(&BootParam); • カーネルに渡す引数を準備して • エントリポイントにジャンプ
Jetzt herunterladen