(for Internet Explorer)
カーネル・モジュール・ファイル(*.ko)を一覧して、依存関係などを調査します。
/lib/modules/`uname --kernel-release` フォルダーに入っているすべてのカーネル用モジュール・
ファイルを一覧し、それぞれのエクスポート関数などを調べて、依存関係を
に保存します。 `uname --kernel-release` は、カーネルのバージョン番号に置きえてください。
この modules.dep ファイルは、modprobe が参照します。
sudo /sbin/depmod -A
-A は、タイムスタンプを見て調査を最小限にします。
/lib/modules/`uname --kernel-release`/modules.dep
コマンドがまとめたカーネル・モジュール・ファイルの一覧です。
このファイルのコロン(:)より左が、存在するカーネル・モジュール・ファイルの相対パス
(基準は、/lib/modules/`uname --kernel-release`) です。 コロンより右は、コロンより
左のモジュールが必要とするモジュールです。(lsmod の Used by とは逆方向です)
例:
/lib/modules/2.6.35.4/modules.dep
… 2.6.35.4 はカーネルのバージョン番号
sudo install --mode=777 -pv  "..../sample.ko" \
  "/lib/modules/`uname --kernel-release`/drivers/block/sample.ko"
sudo /sbin/depmod -A
続き
ときなどに使います。
クロス環境では、ターゲットボード上で depmod を実行する必要があります。
/lib/modules/`uname --kernel-release` 以下は、カーネルソースの構造と同じようです。
依存関係を考慮しないので、
カーネルにモジュールをインストール(ロード)します。(非推奨)
の使用を推奨します。
insmod  module_a
module_a をインストールします。
カーネルからモジュールをアンインストール(アンロード)します。
依存関係を考慮する場合は、
を使用します。
rmmod  module_a
rmmod  -a
module_a をアンインストールします。
使っていないモジュールをアンインストールします。
カーネルにインストール済みのモジュールを一覧表示します。
参考
$ lsmod
Module                  Size  Used by
binfmt_misc             6599  1
nfsd                  240992  13
exportfs                3449  1 nfsd
nfs                   275206  0
lockd                  65605  2 nfsd,nfs
Used by は、行頭のモジュールを使っているモジュールです。
たとえば、上記の最終行の場合、 nfsd と nfs は、lockd を必要としています。
モジュール名は、モジュール・ファイル(実行ファイル)ではありません。
参考
カーネルにインストール済みのモジュールを一覧表示します。
$ cat /proc/modules
binfmt_misc 6599 1 - Live 0xf823e000
nfsd 240992 13 - Live 0xf9bae000
exportfs 3449 1 nfsd, Live 0xf808c000
nfs 275206 0 - Live 0xf8da2000
lockd 65605 2 nfsd,nfs, Live 0xf81f2000
fscache 46361 1 nfs, Live 0xf81d3000
カーネル・モジュールのメモリ配置情報を一覧します。
cat /proc/ksyms > /tmp/ksyms.log
df97b000 __insmod_sample_O/lib/modules/2.4.20/kernel/drivers/char/sample.o_M3FE1F588_V132116 [sample]
df97b060 __insmod_sample_S.text_L5491 [sample]
df97c774 __insmod_sample_S.rodata_L60 [sample]
df97d000 __insmod_sample_S.data_L276 [sample]
出力例: sample モジュールに関する部分の抜粋
コールバック関数 (カーネル・モジュール)
カーネル・モジュールをロードしたときにコールバックされる関数です。
int  init_module( void );
【引数】
返り値
エラーコード、正常=0
#include <module.h>
ヘッダー
module_init(Xxx_Init);
ドライバーは、module_init マクロで登録する必要があります。
カーネル・モジュールがアンロードされたときにコールバックされる関数です。
void  cleanup_module( void );
#include <module.h>
ヘッダー
module_exit(Xxx_Init);
ドライバーは、module_exit マクロで登録する必要があります。
echo 1 > /sys/module/モジュール名/parameters/Variable
シェルの /sys/module から、グローバル変数にアクセスします。
module_param( Variable, Type, Flags );
/sys/module から、アクセスできるグローバル変数を登録します。
【引数】
Variable
Type
グローバル変数。 およびファイル名
変数の型
Flags
S_IRUGO | S_IWUSR など
MODULE_PARM_DESC(DebugLevel, "Sets the level of debug output (default 0x7)");
補足説明を登録します。(ソースの中)
カーネル・モジュールのライセンス名を指定します。
void  MODULE_LICENSE( char* LicenseName );
#include <module.h>
ヘッダー
ライセンス名によって、insmod するときに表示されるメッセージが変わります。
参考
カーネルモードで使える printf です。
int  printk( const char* Format, ... );
出力した文字数
【引数】
Format
ログレベル定数 + 出力内容
返り値
#include <linux/kernel.h>
ヘッダー
サンプル
printk( KERN_ERR "a = %d", a );
KERN_EMERG
KERN_ALERT
KERN_CRIT
KERN_ERR
KERN_WARNING
KERN_NOTICE
KERN_INFO
KERN_DEBUG
ログレベルによっては、
表示されないことがあります。
シリアル・コンソールに出力されます。
ただし、ログレベルによっては、出力されないことがあります。
カーネルの中で例外が発生したときは、表示されないことがあります。
/proc/sys/kernel/printk
4  4  1  7
タブ区切りのテキスト
(="<3>")
(="<4>")
(="<2>")
(="<0>")
(="<1>")
(="<7>")
(="<6>")
(="<5>")
左から、
・現在のログレベル。この値より小さいものが表示される
・ログレベル定数が指定されていないときのログレベル
・ロギングをオフにしたときのログレベル
・ロギングをオンにしたときのログレベル
echo -e  "8\t7\t1\t8" | sudo tee /proc/sys/kernel/printk
変更するコマンドの例:
OS が起動した後で、ターゲットのシリアル・コンソール等で実行してください。
OS を再起動すると、元の設定に戻ります。
ターゲットのシリアル・コンソールに出力されます。
上記の設定は、全てのログレベルを表示します。
関連
CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
make menuconfig の .config ファイルの下記をチェックしてください。
setenv bootargs '... earlyprintk'
saveenv
に、earlyprintk を追加してください。
_call_console_drivers
release_console_sem
__call_console_drivers
(=con->write)
[printk.c]
early_console_write
early_write
printch
[debug.S]
[early_printk.c]
printascii
waituart
senduart
[debug-macro.S]
busyuart
setup_early_printk
register_console
early_param("earlyprintk", setup_early_printk);
コールツリー
// UART に出力
addruart
[debug.S]
[debug-macro.S]
// UART のアドレスを取得
printk をバッファリングしないようにして、ハングアップしたときでも、出力が表示
されるようにします。
setenv bootargs '... loglevel=7'
saveenv
に、loglevel=(数字) を追加してください。
カーネルモードで使える malloc です。
void*  kmalloc( size_t Size, int Flags );
【引数】
Size
Flags
確保するメモリのサイズ(バイト)
GFP_KERNEL または GFP_ATOMIC
返り値
確保したメモリのアドレス
#include <slab.h>
ヘッダー
割り込みハンドラやタスクレット、タイムアウトハンドラから呼び出すときに指定します。
GFP_ATOMIC 定数
カーネルモードで使える free です。
→ usleep
関連
ヘッダー
void  mdelay( unsigned long MilliSeconds );
void  ndelay( unsigned long NanoSeconds );
unsigned long  msleep_interruptible( unsigned int MilliSeconds );
void  msleep( unsigned int MilliSeconds );
カーネルはデバイスを識別する番号(メジャー番号、マイナー番号)を提供しています。
ブート時のカーネルや、init などが、mknod コマンドを実行することにより、デバイス番号を
デバイス・ファイルに関連付けしています。
一般的なデバイス番号とデバイス・ファイルの関係は、カーネルソース/Documents/devices.txt
に書かれています。

実際のデバイス番号は、cat /proc/devices でメジャー番号は分かります。

デバイス・ファイルは、sudo rm コマンドで削除できます。
ルート・ファイル・システム(ユーザーランド)が変わると、デバイス・ファイルを作りなおさなければ
ならなくなります。 デバイス番号は、ルート・ファイル・システムが異なっていても、変わりません。
デバイス・ファイルは、/dev にあります。
/etc/init.d などの起動プロセスのスクリプトによって作られます。(→下記、デバイス番号)
一般のファイルとは構造が異なり、ファイルとしてのデータを持っていません。
デバイス(ドライバー)を操作するときに、指定するものでしかありません。
デバイス番号
デバイス・ファイル
mknod  (path)  (type)  (major)  (minor)
デバイス・ファイル(スペシャル・ファイル)を作成します。
【引数】
path
type
作成するデバイス・ファイルのパス。 通常 /dev の中
種類(下記)
major
メジャー番号
minor
マイナー番号
type 引数
デバイス・ファイルの種類を指定します。
"b"
ブロック・デバイス。 HDD などのストレージ
"c"
キャラクター・デバイス(バッファーあり)。 標準出力など
キャラクター・デバイス(バッファーなし)
"u"
"p"
FIFO
%linux_src%/Documentation/devices.txt を参照
write
read
Unix API
(cache)
参考
Win32 API
CreateFile
CloseHandle
DeviceIoControl
ReadFile
WriteFile
ファイル:
fcntl.h
int  open( char* Path, int Flags, ... );
ファイルやデバイス・ファイルを開きます。
【引数】
Path
Flags
ファイルのパス
(出力) ****へのハンドル
返り値
ファイル・ディスクリプター(ハンドル)。 -1=失敗(errno)
O_RDWR
Flags 引数
O_RDONLY
O_WRONLY
O_APPEND
読み書きする
読み込みのみする
書き込みのみする
返り値であるファイル・ディスクリプターを何に使うかどうかを宣言してください。
追記する
(他にもあります)
サンプル
#include  <fcntl.h>   // open
#include  <unistd.h>  // close
#include  <errno.h>   // errno
#define  IF  if   /* error check */

int  main()
{
  int  e;
  int  file = -1;

  file = open( "README", O_RDONLY ); IF(file==-1)goto err;

  e=0;
fin:
  if ( file != -1 )  close( file );
  return  e;

err:  e=errno;  goto fin;
}
ファイル:
unistd.h
int  close( int FileDescriptor );
ファイルやデバイス・ファイルを開きます。
【引数】
FileDescriptor
ファイル・ディスクリプター(open の返り値)
返り値
0= 成功。 -1=失敗(errno)
ファイル:
sys/ioctl.h
int  ioctl( int DeviceFileDescriptor, int CommandNum [, void* Parameter ] );
ファイルやデバイス・ファイルを開きます。
【引数】
DeviceFileDescriptor
CommandNum
デバイス・ファイルのファイル・ディスクリプター(open の返り値)
デバイス・ドライバーに要求する操作の識別番号
返り値
0= 成功、 負の数=失敗(errno)、 正の数=成功したが通知情報あり
Parameter
パラメーター。1つまたは無し
CommandNum や Parameter は、デバイス・ファイルの仕様によります。
参考
参考
request_irq
→ DLL
関連
Windows では、so = DLL, a = LIB
参考
Windows では DLL と呼ばれています。 実行ファイル(バイナリ)の共通部分を共有オブジェクトに
して、複数の実行ファイルからリンクして使うことができます。
実行ファイルが共有オブジェクトを要求したときに、共有オブジェクトを探しに行くフォルダーを、
この変数に指定できます。
優先的にリンクする共有オブジェクトを、この変数に指定できます。

優先する共有オブジェクトにリンクするか、通常の共有オブジェクトにリンクするかは、
シンボル(関数)単位で、行われます。

実行ファイルが要求する共有オブジェクトをロードする前に(未確認)、LD_PRELOAD 環境変数に
設定してある共有オブジェクトをロードします(必ずロードするかは未確認)。
add_path=`readlink -f .`
case $LD_LIBRARY_PATH in *$add_path*);; *) export LD_LIBRARY_PATH=$add_path:$LD_LIBRARY_PATH; esac
カレント・フォルダーが PATH に含まれていなかったら追加する。
共有ライブラリ(*.so) の情報を /etc/ld.so.conf から集めて、キャッシュを /etc/ld.so.cache に作成します。
参考
include /etc/ld.so.conf.d/*.conf
/etc/ld.so.conf
/etc/ld.so.conf.d/libc.conf
/usr/local/lib
/etc/ld.so.cache
(バイナリファイル)
ファイル構造
include
ldconfig
sudo ldconfig
シェルから
… キャッシュを更新する
ldconfig -p
… キャッシュの内容を表示する
/etc/ld.so.preload
/usr/local/lib/preload.so
フルパスのスペース区切り
↑ /usr/local/lib/lib*.so* を探す