Linux Kernel(2.6)の実装に関するメモ書き

モジュール


Rev.1を表示中。最新版はこちら

モジュールのロード

sys_init_module()


	load_module()
		フォーマット(ELFか?等)をチェック

		module_alloc() - 単なるvmalloc()

		セクションヘッダテーブル内の全エントリに対して以下を実行
			SHF_ALLOCが設定されているセクションを移動

		simplify_symbols()
			シンボルテーブル内の全エントリに対して以下を実行
			st_shndx: SHN_UNDEFならresolve_symbol()

		/* Now do relocations. */
		セクションヘッダテーブルを全てチェック。

		セクションのタイプが
			SHT_REL ならapply_relocate()
			SHT_RELAならapply_relocate_add()

	mod->init() - モジュールの初期化ルーチン呼び出し


resolve_symbol() - シンボルのアドレス解決
	__find_symbol() - シンボルの検索
		カーネル内のシンボルテーブルから検索
			__start___ksymtab
			__start___ksymtab_gpl

		組み込み済のモジュール内のシンボルテーブルから検索
			mod->syms[i]
			mod->gpl_syms[i]


apply_relocate() - 再配置(アドレスの書き換えを行う)

	再配置テーブル内の全エントリに対して以下を実行

		rel[i].r_offsetが指しているアドレスにシンボルテーブル
		から引っ張って来たアドレスを設定する。
		*location += sym->st_value;

		(シンボルのアドレス解決(sym->st_value)の設定は
		simplify_symbols()で行われる。)


----------------------------------------------------
ELFファイルメモ
+--------------------------+
| ELFヘッダ                |
| e_type                   | ET_REL,ET_EXEC,ET_DYN,ET_CORE
|                          | 
| e_phoff                  |プログラムヘッダテーブルのファイルオフセット
| e_shoff                  |セクションヘッダテーブルのファイルオフセット
|                          |
| e_shstrndx               |セクション名文字列テーブルに関連付けられたエントリ
|                          |のセクションヘッダテーブルインデックスを保持する。
+--------------------------+
+--------------------------+
| プログラムヘッダテーブル | セグメントを表す
|                          | セグメント には 1 つ以上の セクション が含まれる
|                          |
| p_vaddr                  | セグメント開始の仮想アドレス
|                          |
|                          |
+--------------------------+
|                          |
             :

+--------------------------+
| セクションヘッダテーブル | ファイル内の各セクションの情報を保存
|                          |
| sh_name                  | セクション名(セクションヘッダ文字列テーブル
|                          | セクションのインデクス)
| sh_type                  | SHT_SYMTAB, SHT_REL, SHT_STRTA...
+--------------------------+
|                          |
             :

+--------------------------+
| シンボルテーブル         | シンボル情報が列挙される
|                          |
|                          | 00000000 l    df *ABS*  00000000 ifload.c
|                          | 00000000 l    d  .text  00000000
|                          | 00000000 l    d  .data  00000000
|                          | 00000000 l    d  .bss   00000000
|                          | 00000000 l    d  .rodata.str1.4 00000000
|                          | 00000348 l     F .text  00000197 get_iflist
|                          | 000004e0 l     F .text  00000134 update_stats
|                          | 00000000         *UND*  00000000 stderr
|                          | 00000000         *UND*  00000000 fwrite
|                          |            :
+--------------------------+ *UND*が未解決シンボル

+--------------------------+
| 文字列テーブル           |

+--------------------------+
| 再配置テーブル           | 再配置必要な箇所が列挙される
|                          |
|                          | OFFSET   TYPE              VALUE
|                          | 00000008 R_386_32          stderr
|                          | 00000011 R_386_32          .rodata.str1.1
|                          | 00000016 R_386_PC32        fwrite
|                          | 0000001c R_386_32          stderr
|                          |            :
+--------------------------+

OFFSET 再配置動作が適用される位置(解決後のアドレスが書き込まれる場所)
       <--逆アセンブルしてみるとここのアドレスにはダミーのアドレス値
          が入っている。以下参照
TYPE   R_386_32,R_386_PC32
VALUE  参照先シンボル(実際にはシンボルテーブル内でのインデックス値)


00000000 <usage>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   ff 35 00 00 00 00       pushl  0x0             #0x08 stderr
   c:   6a 07                   push   $0x7
   e:   6a 01                   push   $0x1
  10:   68 00 00 00 00          push   $0x0            #0x11 .rodata.str1.1
  15:   e8 fc ff ff ff          call   16 <usage+0x16> #0x16 fwrite
  1a:   ff 35 00 00 00 00       pushl  0x0             #0x1c stderr
  20:   6a 0e                   push   $0xe
  22:   6a 01                   push   $0x1

最終更新 2006/03/27 12:59:43 - kztomita
(2006/03/27 12:59:43 作成)


リンク
最近更新したページ
検索