参照元

説明

  • パス: linux-2.6.33/include/linux/module.h?
  • 関数や変数の名前をカーネルのシンボルテーブルに登録する。
    • 他のモジュールから名前が見えるようになる。
    • 関数内で宣言しても正常に動作しない。

引数

  • sym
    • カーネルのシンボルテーブルに登録したいシンボルを指定する。
  • sec
    • シンボルテーブルを表すセクション(__ksymtab)に追加する文字列を指定する。
      • 今のところ "_gpl", "_gpl_future" が使われている。

返り値

  • なし

参考

#ifndef __GENKSYMS__
  • __GENKSYMS__ が宣言されていないときに有効である。
    • linux-2.6.33/__GENKSYMS__?

実装

マクロの宣言部分

#define __EXPORT_SYMBOL(sym, sec)                               \

1行目

        extern typeof(sym) sym;                                 \
  • シンボルがオブジェクト外部にあるかもしれないと宣言(extern 宣言)する。 これによって別のオブジェクトで定義されている関数もリンク時に解決、 エクスポートできる。たぶん。
    • なのでエクスポート専用のソースファイルが書けるはずです。
    • typeof は gcc の拡張構文で、指定した変数の型を表す。

2行目

        __CRC_SYMBOL(sym, sec)                                  \
  • モジュールのバージョン管理に使うシンボルの定義をする。
    • linux-2.6.33/__CRC_SYMBOL()?

3行目

        static const char __kstrtab_##sym[]                     \
  • シンボル名を定義する。
    • ## はトークン連結演算子で、トークン同士を繋いで一つのトークンにする。
    • 例えば __EXPORT_SYMBOL(hogehoge, "") なら sym に hogehoge を渡した ことになるので、__kstrtab_hogehoge[] が宣言される。
        __attribute__((section("__ksymtab_strings"), aligned(1))) \
  • __attribute__ ディレクティブは gcc の拡張構文である。 コンパイラへの命令を書く場合に用いる。
  • section は、セクション指定である。 上記の __kstrtab_xxxx 変数を __ksymtab_strings セクションに置きなさい、 とコンパイラに指示する。
  • aligned は、アラインメントの指定である。 上記の __kstrtab_xxxx 変数を 1バイト境界に配置しなさい、 とコンパイラに指示する。目的はカーネルサイズを削減するため。
    • 参考: Linux kernel のパッチ情報:
      --------------------
      commit ea01e798e2d27fd04142e0473ca36570fa9d9218
      Author: Rusty Russell <rusty@rustcorp.com.au>
      Date:   Thu Mar 13 09:02:17 2008 +0000
      
          module: reduce module image and resident size
      
          Resulting reduction (x86-64, gcc 4.1.2) with my (special purpose, i.e.
          much reduced) configurations:
          - 16k kernel resident size
          - 180k module resident size
          - 10k module image size
      
          Signed-off-by: Jan Beulich <jbeulich@novell.com>
          Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
      --------------------
        = MODULE_SYMBOL_PREFIX #sym;                            \
  • # はトークンを文字列リテラルに変換する演算子である。 プリプロセッサがシンボル名を勝手に " " で囲ってくれると思えば簡単?
  • MODULE_SYMBOL_PREFIX は "" である。
  • 連続する文字列リテラルは連結される(C の規則)ので、 例えば sym => hogehoge だとすると生成される文字列は "hogehoge" である。
    • MODULE_SYMBOL_PREFIX はアーキテクチャ依存で、asm/module.h にて上書きされている場合がある。
    • 参考
      asm-blackfin/module.h:#define MODULE_SYMBOL_PREFIX "_"
      asm-h8300/module.h:#define MODULE_SYMBOL_PREFIX "_"
      asm-v850/module.h:#define MODULE_SYMBOL_PREFIX "_"

4行目

        static const struct kernel_symbol __ksymtab_##sym       \
  • シンボルテーブルの要素を定義する。
        __used                                                  \
  • __attribute__( (__used__) ) を理解できない古いコンパイラのために宣言する。
    • 最適化で消されないため、そして「変数/関数が未使用」の警告を抑えるために使う。
    • linux-2.6.33/__used
        __attribute__((section("__ksymtab" sec), unused))       \
  • __ksymtab セクションに配置する。 sec に何か渡した(例: hoge)場合はその名前を 連結したセクション(例: __ksymtabhoge)に配置される。
  • unused でも used でも同じはずだが、古い gcc(3.4 未満)だと 変数に対して __attribute__( (used) ) を宣言できないらしい。
    • この辺りはよくわかりません。正直どうでもいい…。
        = { (unsigned long)&sym, __kstrtab_##sym }
  • シンボルテーブルの 1要素を定義する。

まとめ

  • sym: エクスポートすべきシンボル
  • __kstrtab_##sym: カーネルが使うシンボルの名前 -> __ksymtab_strings セクションへ
  • __ksymtab_##sym: シンボルテーブルの要素(シンボルのポインタと、名前のタプル) -> __ksymtab セクションへ

コメント


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-09-13 (土) 08:26:40 (1523d)