参照元†
- 関数や変数の名前をカーネルのシンボルテーブルに登録する。
- 他のモジュールから名前が見えるようになる。
- 関数内で宣言しても正常に動作しない。
- sym
- カーネルのシンボルテーブルに登録したいシンボルを指定する。
- sec
- シンボルテーブルを表すセクション(__ksymtab)に追加する文字列を指定する。
- 今のところ "_gpl", "_gpl_future" が使われている。
返り値†
#ifndef __GENKSYMS__
- __GENKSYMS__ が宣言されていないときに有効である。
マクロの宣言部分†
#define __EXPORT_SYMBOL(sym, sec) \
1行目†
extern typeof(sym) sym; \
- シンボルがオブジェクト外部にあるかもしれないと宣言(extern 宣言)する。
これによって別のオブジェクトで定義されている関数もリンク時に解決、
エクスポートできる。たぶん。
- なのでエクスポート専用のソースファイルが書けるはずです。
- typeof は gcc の拡張構文で、指定した変数の型を表す。
2行目†
__CRC_SYMBOL(sym, sec) \
- モジュールのバージョン管理に使うシンボルの定義をする。
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" である。
4行目†
static const struct kernel_symbol __ksymtab_##sym \
__used \
- __attribute__( (__used) ) を理解できない古いコンパイラのために宣言する。
- 最適化で消されないため、そして「変数/関数が未使用」の警告を抑えるために使う。
__attribute__((section("__ksymtab" sec), unused)) \
- __ksymtab セクションに配置する。
sec に何か渡した(例: hoge)場合はその名前を
連結したセクション(例: __ksymtabhoge)に配置される。
- unused でも used でも同じはずだが、古い gcc(3.4 未満)だと
変数に対して __attribute__( (used) ) を宣言できないらしい。
= { (unsigned long)&sym, __kstrtab_##sym }
まとめ†
- sym: エクスポートすべきシンボル
- __kstrtab_##sym: カーネルが使うシンボルの名前 -> __ksymtab_strings セクションへ
- __ksymtab_##sym: シンボルテーブルの要素(シンボルのポインタと、名前のタプル) -> __ksymtab セクションへ
コメント†