Upload
uchannos
View
206
Download
5
Embed Size (px)
Citation preview
はりぼて OS で ELF なアプリを起動してみた@uchan_nos
2016/11/26 第 4 回自作 OS もくもく会
はりぼて OS によるアプリ起動• デモ
はりぼて OS によるアプリ起動• コンソールにコマンドを打ち込むと起動する• 裏では:• カーネルが .hrb ファイルをメモリに配置• アプリ用のデータ領域確保や ESP 設定• エントリポイントにジャンプ
hrb ファイルフォーマット( p.460 )off 意味0x00 stack+.data+heap の大きさ0x04 “Hari”0x08 mmarea の大きさ0x0C ESP の初期値( = .data の転送先)0x10 .data のサイズ0x14 .data の初期値のファイル内オフセット0x18 0xE90000000x1C エントリアドレス -0x200x20 heap 領域開始アドレス
ヘッダ.text
.data
Segm 1Segm 2
ロード後のメモリ配置stack
.data.bss
heap
.text
.data
ヘッダ.hrb ファイルそのまま
ESP 初期値
はりぼて OS のプログラムローダ( ELF 化前)console.c
実行可能形式いろいろ• COM• 実行時のメモリイメージそのままの形式
• PE• Windows の標準
• a.out• Unix 最初期の形式。 TEXT, DATA, BSS だけをもつ
• COFF• オブジェクトファイル形式として有名
• ELF• Executable and Linking Format
ELF : Executable and Linking Format• 現在の Unix, Linux での標準• オブジェクトファイル、実行可能ファイルどちらも OK• ツールチェーンで良くサポートされている• a.out や COFF に比べ柔軟。新しい言語にも対応できる• → これは ELF に対応するしかないでしょ!
ELF ファイルフォーマット• ELF ヘッダ、 SHT 、 PHT 、セクション群からなる• SHT :セクション・ヘッダ・テーブル• PHT :プログラム・ヘッダ・テーブル• セクション群: .text, .data, .bss, .shstrtab など• 詳しくは『リンカ・ローダ実践開発テクニック』坂井弘亮 , 2010
ELF ヘッダPHT
SHT
セクション
ELF32 ヘッダフォーマットoff field 意味0x00 e_ident 先頭 4 バイトは 0x7f, ‘E’, ‘L’, ‘F’0x10 e_type ファイルタイプ ET_EXEC, ET_REL など0x12 e_machin
eEM_386 など
0x14 e_version ファイルバージョン0x18 e_entry エントリポイントのアドレス0x1C e_phoff プログラムヘッダテーブルのファイル位置0x20 e_shoff セクションヘッダテーブルのファイル位置0x24 e_flags 未使用0x28 e_ehsize ELF ヘッダサイズ0x2A …0x32 e_shstrnd
xセクション名格納用セクションの番号
ELF ヘッダPHT
SHT
セクション
セクション・ヘッダ• .text 、 .data 、 .bss などのセクションを管理するヘッダ• コンパイラが出力したセクションをリンカがまとめる• セクション名• セクションの属性(書き込み、実行)• セクションのロード先仮想アドレス• セクションデータのファイル位置とサイズ
プログラム・ヘッダ• ローダが利用するセグメントを記述する• PHT は実行可能ファイルにしかない• セグメントのタイプ• セグメントのロード先仮想アドレス• セグメントデータのファイル位置とサイズ• セグメントのメモリ上のサイズ• セグメント属性(読み書き実行)
ロードの仕様を考える• はりぼて OS では、スタック領域は .data の前に置く• メモリ上では .text, .stack の先頭アドレスが両方とも 0 になって欲しい• .stack, .bss, .mallocはファイル上は 0 バイト
.text.stack
.malloc
欲しいELF ファイル
EXEC
RW
.text
.data.bss
ELF ヘッダPHT
SHT
欲しいメモリ配置
.stack.data
0 番地
0 番地.bss
.malloc
ELF 用リンカスクリプトENTRY(_HariMain)INCLUDE ld_variables.lds
SECTIONS{ . = SIZEOF_HEADERS; .text : { *(.text) } "file offset of data" = .;
. = 0; .stack : AT("file offset of data") { . = STACK; } .data : { *(.rodata*) *(.data) } .bss : { *(.bss) } .malloc : { . += MALLOC; }}
EXEC セグメントにロードされる部分
RW セグメントにロードされる部分
生成されるヘッダ構造セクション タイプ ロード先 Offset Size.text PROGBITS 00000094 000094 000188.stack NOBITS 00000000 00021c 000400.data PROGBITS 00000400 00021c 000088.bss NOBITS 00000488 0002a4 000100.malloc NOBITS 00000588 0002a4 00c000
セグメント Offset 仮想アドレス File Size Mem Size
Flag
LOAD 000094 00000094 000188 000188 R ELOAD 00021c 00000000 000000 000400 RWLOAD 00021c 00000400 000088 00c188 RW※ これらは readelf -a hoge.elf で表示できるよ!
ローダの改造 1.elf ファイルを探す console.c
ローダの改造 2ELF のマジックナンバーを確認する
…
ローダの改造 3esp の初期値を計算する
calc_elf_esp
.stack セクションがあれば、そのサイズを返す→.stack セクションが 0 番地から配置されることを暗に仮定している
ローダの改造 4.data のコピーとアプリ起動
EXEC0*8+4
RW1*8+
4
ELFファイル全体
.data.bss
.stack
p
q
appsiz
segsiz
.malloc
esp
calc_elf_datasize
copy_elf_data
ELF アプリ起動 デモ
リンカスクリプト豆知識location counterとvirtual memory address (VMA)load memory address (LMA)の関係
参考: https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html
Location counter is . (dot)SECTIONS{ . = SIZEOF_HEADERS; .text : { *(.text) } "file offset of data" = .;
• VMA, LMA の現在値を保持するもの• 値が加算されていくので「カウンタ」• "file offset of data" はシンボル
Virtual memory address (VMA)
• VMA はそのセクションが配置されるメモリの仮想アドレス• 上記の例では “ .text” の VMA は SIZEOF_HEADERS
SECTIONS{ . = SIZEOF_HEADERS; .text : { *(.text) } "file offset of data" = .;
SIZEOF_HEADERSファイルのヘッダのバイト数を返すリンカの組み込み変数
Virtual memory address (VMA)
ヘッダ.text
SIZEOF_HEADERS(= ELF ヘッダ +PHT) バイト
"file offset of data" .dataSHT
Load memory address (LMA)
• VMA はファイル実行時のアドレス• 対して、 LMA はファイルが読み込まれるアドレス• 今回、これを「ファイル内のオフセット」として使っている
• 上記の例では “ .stack” の VMA は 0 、 LMA は “ .text” の直後
. = 0;
.stack : AT("file offset of data") { . = STACK;}
. = 0;
.stack : AT("file offset of data") { . = STACK;}.data : { *(.rodata*) *(.data) }.bss : { *(.bss) }Sect VMA LMA.stack 0 “file offset of data”.data STACK “file offset of data”.bss STACK+sizeof(.data
)“file offset of data”+sizeof(.data)
AT を指定しなければ、 LMA に関して直前の AT の効果が続く
参考文献など• ELF 化したはりぼて OS のソースコード
https://github.com/osdev-jp/elf_haribote• 『リンカ・ローダ実践開発テクニック』坂井 弘亮 , 2010• ELF の仕様書
http://www.skyfree.org/linux/references/ELF_Format.pdf• LD のドキュメント
https://sourceware.org/binutils/docs/ld/• 3.1 Basic Linker Script Concepts• 3.6.8.2 Output Section LMA
• はりぼて OS サポートページ内 “ tools/obj2bim”http://hrb.osask.jp/wiki/?tools/obj2bim