EN JA
FIRMWARE(9)
FIRMWARE(9) FreeBSD Kernel Developer's Manual FIRMWARE(9)

名称

firmware_register, firmware_unregister, firmware_get, firmware_putファームウェアイメージのローディングと管理

書式

#include < sys/param.h>
#include < sys/systm.h>
#include < sys/linker.h>
#include < sys/firmware.h>

struct firmware { 
 const char *name;  /* システム全体の名前 */ 
 const void *data;  /* イメージの位置 */ 
 size_t  datasize; /* バイト単位のイメージのサイズ */ 
 unsigned int version; /* イメージのバージョン */ 
};


const struct firmware *
firmware_register( const char *imagename, const void *data, size_t datasize, unsigned int version, const struct firmware *parent);

int
firmware_unregister( const char *imagename);

const struct firmware *
firmware_get( const char *imagename);

void
firmware_put( const struct firmware *fp, int flags);

解説

firmware 抽象化は、カーネルへのローディング firmware images (ファームウェアイメージ) のためと、カーネルコンポーネントからそのようなイメージにアクセスするための便利なインタフェースを提供します。

firmware image (または、略して image) は、カーネルメモリにあるデータの不透明な (サイズおよび形がわからない) ブロックです。それは、検索キーを構成するユニークな imagename と、また、ファームウェアサブシステムのための不透明な情報の部分である、整数 version 番号に関連づけられます。

イメージは、関数 firmware_register() を呼び出すことによって firmware サブシステムに登録され、 firmware_unregister() を呼び出すことによって登録を取り消します。通常 (しかし、排他的でなく)、これらの関数は、ファームウェアイメージを含む特別に作られたカーネルモジュールによって呼び出されます。モジュールは、カーネルで静的にコンパイルするか、または実行時に手動で、または、ファームウェアサブシステムによる要求で、 /boot/loader によってモジュールをロードすることができます。

ファームウェアサブシステムの clients は、それらが引数として欲しい imagename で、関数 firmware_get() を呼び出すことによって、与えられたイメージへのアクセスを要求することができます。適合しているイメージがまだ登録されていないなら、ファームウェアサブシステムは、以下で指定されたメカニズム (通常、イメージとして同じ名前がある firmware_register カーネルモジュール) を使用してそれをロードしようと試みます。

API 解説

カーネル firmware_register ファームウェア API は、次の関数で作られています:

firmware_register() は、名前 imagename 下のアドレス data に位置付けらられたサイズ datasize のイメージをカーネルに登録します。

関数は、エラーのとき NULL を返すか、 (例えば、同じ名前が既に存在しているイメージであるか、またはイメージテーブルが満杯であるので)、または、要求されたイメージを指す const struct firmware * ポインタを返します。

firmware_unregister() は、システムからファームウェアイメージ imagename の登録取り消しを試みます。関数が成功し、イメージへの保留中 (pending) の参照がなければ、0 を返し、そうでなければ、イメージの登録取り消しせず、EBUSY を返します。

firmware_get() は、要求されたファームウェアイメージを返します。イメージがまだシステムに登録されていないなら、関数は、それをロードしようと試みます。これは、リンカサブシステムとディスクアクセスによって生じるので、 ( Giant を除いて) 任意のロックで firmware_get() を、呼び出してはなりません。また、ファームウェアイメージがファイルシステムからロードされるなら、既にそのファイルシステムがマウントされていなければなければならないことに注意してください。特に、これは、ルートファイルシステムが既にマウントされていることが知られていないなら、トライバアタッチ方法から要求を延期する必要があることを意味します。

成功すれば、 firmware_get() は、イメージ記述へのポインタを返し、このイメージのために参照カウントを増加させます。失敗すれば、関数は、NULL を返します。

firmware_put() は、ファームウェアイメージの参照を落とします。 flags 引数は、 firmware_put が、これが最後の参照であるなら、ファームウェアイメージに関連しているリソースを再利用するために解放されることを示すために、 FIRMWARE_UNLOAD に設定されます。デフォルトで、ファームウェアイメージは、 taskqueue(9) スレッドに延期されるので、ロックを保持している間に、呼び出しは、行われます。ドライバのデタッチのような、ある特定の場合に、これを許可することはできません。

ファームウェアローディングメカニズム

以前に述べられたように、システムの任意の要素は、単に firmware_register(). を呼び出すことによって、いつでも、ファームウェアイメージを登録することができます。

ファームウェアイメージを含むモジュールが、コンパイルされるか、 /boot/loader によって前もってロードされるか、または kldload(8) で手動でロードされるかどうかの制御が与えられるとき、これは、通常行われます。しかしながら、システムは、 firmware_register() を呼び出す前にメモリのこれらのイメージをもたらすために追加メカニズムを実行することができます。

firmware_get() が要求されたイメージを見つけられないとき、利用可能なローディングメカニズムの 1 つを使用してそれをロードしようと試みます。現在のところ、すなわち、次の ロード可能なカーネルモジュール があります:

foo と名前が付けられたファームウェアイメージは、 kld(4) に説明された機能を使用して、 foo.ko と名前が付けられたモジュールをロードしようと試みることによって、検索されます。特に、イメージは、ほとんどのシステムで /boot/kernel;/boot/modules をデフォルトとする sysctl 変数 kern.module_path によって指定されたディレクトリで検索されます。

万一モジュールが複数のイメージを含む場合には、呼び出し側は、最初に、他のイメージを要求することによって続く、モジュールに含まれた最初のイメージのために firmware_get() を要求するべきであることに注意してください。

ファームウェアローディングモジュールの構築

ファームウェアモジュールは、 ファームウェアイメージ を、ローディングのときに firmware_register() を呼び出し、アンローディングのときに、 firmware_unregister() を呼び出す、適切なロード可能なカーネルモジュールに組み込むことによって構築されます。

様々なシステムスクリプトと makefile によって、利用者は、次のエントリがある Makefile を単に書くことによって、モジュールを構築することができます:

 
        KMOD=   imagename 
        FIRMWS= image_file:imagename[:version] 
        .include <bsd.kmod.mk> 

ここで、KMOD は、モジュールの basename です。 FIRMWS は、モジュール、imagename と各ファームウェアイメージのバージョンに組み込まれる image_file を示すコロンで区切られたタプル (組) のリストです。

ファームウェアイメージをシステムに組み込む必要があるなら、利用者は、 <files.arch>ファイルに適切なエントリを書くべきです、例えば、次の例は、 sys/arm/xscale/ixp425/files.ixp425 から来ています:

ixp425_npe_fw.c                         optional npe_fw                 \ 
        compile-with    "${AWK} -f $S/tools/fw_stub.awk   \ 
   IxNpeMicrocode.dat:npe_fw -mnpe -c${.TARGET}" \ 
        no-implicit-rule before-depend local                            \ 
        clean           "ixp425_npe_fw.c" 
# 
# 注意: ld は、ファームウェアイメージのために生成されたバイナリシンボル 
#       のパスをエンコードします、従って、_fw.c ファイルの参照のために知 
#       られている値を得るためにファイルをオブジェクトディレクトリに 
#       リンクします. 
# 
IxNpeMicrocode.fwo  optional npe_fw     \ 
        dependency      "IxNpeMicrocode.dat"    \ 
        compile-with    "${LD} -b binary -d -warn-common  \ 
       -r -d -o ${.TARGET} IxNpeMicrocode.dat" \ 
        no-implicit-rule                                                \ 
        clean           "IxNpeMicrocode.fwo" 
IxNpeMicrocode.dat                      optional npe_fw                 \ 
        dependency      ".PHONY"                                        \ 
        compile-with    "uudecode < $S/contrib/dev/npe/IxNpeMicrocode.dat.uu" \ 
        no-obj no-implicit-rule                                         \ 
        clean           "IxNpeMicrocode.dat"

この方法でファームウェアモジュールを生成するためには、次のツールが利用可能でなければならないことに注意してください: awk(1), make(1), コンパイラとリンカ。

関連項目

kld(4), module(9)

/usr/share/examples/kld/firmware

歴史

firmware システムは、 FreeBSD 6.1 で導入されました。

作者

このマニュアルページは、 Max Laier <mlaier@FreeBSD.org>によって書かれました。
August 2, 2008 FreeBSD