デバイスのツリー、オーバーレイ、およびパラメータ
RaspbianとNOOBSリリースを含むRaspberry Piの最新のカーネルとファームウェアは、デフォルトでいくつかのリソース割り当てとモジュールロードを管理するためにDevice Tree(DT)を使用しています。これは、システムリソースを競合する複数のドライバの問題を軽減し、HATモジュールを自動構成できるようにするために実装されました。
現在の実装は純粋なデバイスツリーシステムではなく、一部のプラットフォームデバイスを作成するボードサポートコードがありますが、外部インターフェイス(I2C、I2S、SPI)およびそれらを使用するオーディオデバイスは、デバイスTree Blob(DTB)は、loader(start.elf
)によってカーネルに渡されます。
デバイスツリーを使用しての主な影響はから変更することです上のすべてのものに、競合を管理するためのモジュールのブラックリストに頼って、DTBによって要求されない限り、すべてオフ。外部インターフェイスとそれに接続されている周辺機器を引き続き使用するには、新しい設定を追加する必要がありますconfig.txt
。パート3で詳細を説明しますが、これはいくつかの例です:
# Uncomment some or all of these lines to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# Uncomment one of these lines to enable an audio interface
#dtoverlay=hifiberry-amp
#dtoverlay=hifiberry-dac
#dtoverlay=hifiberry-dacplus
#dtoverlay=hifiberry-digi
#dtoverlay=iqaudio-dac
#dtoverlay=iqaudio-dacplus
#dtoverlay=audioinjector-wm8731-audio
# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi
# Uncomment this to override the defaults for the lirc-rpi module
#dtparam=gpio_out_pin=16
#dtparam=gpio_in_pin=17
#dtparam=gpio_in_pull=down
デバイスツリー
デバイスツリー(DT)は、システム内のハードウェアの説明です。これには、ベースCPUの名前、そのメモリ構成、およびすべての周辺機器(内部および外部)が含まれていなければなりません。通常、ドライバモジュールをロードさせるハードウェアモジュールを列挙することによって、DTをソフトウェアの記述に使用しないでください。DTがOSに中立であると考えられることを覚えておくと、Linux固有のものはおそらくそこには存在しないはずです。
デバイスツリーは、ハードウェア構成をノードの階層として表します。各ノードは、プロパティおよびサブノードを含むことができる。プロパティは、文字列、数字(ビッグエンディアン)、任意のバイト列、およびそれらの任意の組み合わせを含むことができるバイトの名前付き配列です。ファイルシステムと同様に、ノードはディレクトリで、プロパティはファイルです。ツリー内のノードおよびプロパティの位置は、パスを使用して区切り記号としてスラッシュ/
を、ルートを示す単一のスラッシュ()を使用して記述できます。
1.1:基本的なDTS構文
デバイスツリーは通常、デバイスツリーソース(DTS)と呼ばれるテキスト形式で記述され、.dts
接尾辞付きのファイルに格納されます。DTS構文はCのようなもので、各行の末尾にグループ化とセミコロンの括弧があります。DTSは中括弧を閉じた後にセミコロンを必要とすることに注意してくださいstruct
。関数ではなくCを考えてください。コンパイルされたバイナリ形式は、FDT(Flattened Device Tree)またはDTB(Device Tree Blob)と呼ばれ、.dtb
ファイルに格納されます。
次の.dts
形式の単純なツリーがあります。
/dts-v1/;
/include/ "common.dtsi";
/ {
node1 {
a-string-property = "A string";
a-string-list-property = "first string", "second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
cousin: child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
my-cousin = <&cousin>;
};
};
};
/node2 {
another-property-for-node2;
};
このツリーに含まれるもの:
- 必要なヘッダー:
/dts-v1/
。
- 別のDTSファイルの包含、従来名前
*.dtsi
との類似.h
Cのヘッダファイル-参照脇約/ /含む以下。
- 単一のルートノード:
/
- 子ノードのカップル:
node1
とnode2
- node1のためのいくつかの子供:
child-node1
とchild-node2
- label(
cousin
)とそのラベルへの参照(&cousin
):以下のラベルと参考文献を参照してください。
- 木を介して散在するいくつかのプロパティ
- 繰り返しノードは、(
/node2
)-参照/含む/脇約以下。
プロパティは単純なキーと値のペアです。値は空でも、任意のバイトストリームでも構いません。データ型はデータ構造内でエンコードされませんが、Device Treeソースファイルで表現できる基本的なデータ表現はいくつかあります。
テキスト文字列(NUL終端)は、二重引用符で囲みます。
string-property = "a string";
セルは山括弧で区切られた32ビットの符号なし整数です。
cell-property = <0xbeef 123 0xabcd1234>;
任意のバイトデータは角括弧で区切り、16進数で入力します。
binary-property = [01 23 45 67 89 ab cd ef];
異なる表現のデータは、コンマを使用して連結することができます。
mixed-property = "a string", [01 23 45 67], <0x12345678>;
カンマは、文字列のリストを作成するためにも使用されます。
string-list = "red fish", "blue fish";
1.2:ABOUT / INCLUDE /
この/include/
ディレクティブは、Cの#include
ディレクティブと同様に単純なテキストのインクルードになりますが、Device Treeコンパイラの機能はさまざまな使用パターンにつながります。潜在的に絶対パスを持つノードの名前が付けられている場合、同じノードがDTSファイル(およびその包含物)に2回表示される可能性があります。これが起こると、必要に応じてノードとプロパティが組み合わされ、インターリーブと上書きのプロパティが作成されます(後の値は以前のものをオーバーライドします)。
上記の例では、2番目の外観は/node2
、新しいプロパティをオリジナルに追加します。
/node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
another-property-for-node2;
child-node1 {
my-cousin = <&cousin>;
};
};
したがって.dtsi
、ツリー内の複数の場所を上書きするか、またはデフォルトを提供することが可能です。
1.3:ラベルとリファレンス
ツリーのある部分が別の部分を参照する必要があることが多く、これを行うには4つの方法があります。
- パス文字列パスはファイルシステムとの類推によって自明でなければなりません
/soc/i2s@7e203000
。BCM2835とBCM2836のI2Sデバイスへのフルパスです。プロパティ(たとえば、/soc/i2s@7e203000/status
)へのパスを作成するのは簡単ですが、標準のAPIはそうしないことに注意してください。最初にノードを見つけて、そのノードのプロパティを選択します。
- ファンドルズファンドルは、その
phandle
プロパティ内のノードに割り当てられた一意の32ビット整数です。歴史的な理由から、冗長なマッチングを見ることもできますlinux,phandle
。ファンドルは1から順に番号が付けられます。0は有効なファンドルではありません。通常、ラベルの形式で、整数コンテキストでノードへの参照を検出すると、DTコンパイラによって割り当てられます(以下を参照)。ファンドルを使用するノードへの参照は、単に対応する整数(セル)値としてエンコードされます。それがアプリケーション定義されているように、それらがファンドルとして解釈されるべきであることを示すためのマークアップはない。
- ラベルCのラベルがコード内の場所に名前を付けるように、DTラベルは階層内のノードに名前を割り当てます。コンパイラは、文字列context(
&node
)および整数context(<&node>
)のファンドルで使用されると、ラベルへの参照をパスに変換します。元のラベルはコンパイルされた出力には表示されません。ラベルは構造体を含まないことに注意してください。それらはフラットなグローバルネームスペースの単なるトークンです。
- エイリアスエイリアスは、FDT出力にインデックス形式で表示される点を除いて、ラベルに似ています。それらは
/aliases
ノードのプロパティとして格納され、各プロパティはエイリアス名をパス文字列にマッピングします。エイリアスノードはソースに表示されますが、通常、パス文字列はlabels(&node
)への参照として表示され、完全に書き出されるのではありません。ノードへのパス文字列を解決するDT APIは、通常、パスの最初の文字を調べ、スラッシュで始まらないパスを、/aliases
テーブルを使用して最初にパスに変換する必要がある別名として扱います。
1.4:デバイスツリーのセマンティクス
デバイスツリーを構築する方法と、それを使ってハードウェアの構成をキャプチャする方法は、大きく複雑なものです。利用可能なリソースはたくさんありますが、そのうちのいくつかを以下に示しますが、このドキュメントではいくつかの点について言及しておきます。
compatible
プロパティは、ハードウェアの説明とドライバソフトウェアの間のリンクです。OSは、compatible
プロパティを持つノードに出会うと、デバイスドライバのデータベースで検索し、最適なものを見つけます。Linuxでは、適切なラベルが付けられブラックリストに登録されていない場合、ドライバモジュールが自動的にロードされます。
このstatus
プロパティは、デバイスが有効か無効かを示します。場合status
でok
、okay
または不在で、そのデバイスが有効になっています。それ以外の場合は、デバイスが無効にstatus
なるようdisabled
にする必要があります。.dtsi
ステータスが「」に設定されたファイルにデバイスを配置すると便利ですdisabled
。それから、派生した構成はそれを含み、.dtsi
必要とされる装置の状態を設定することができるokay
。
パート2:デバイスツリーオーバーレイ
現代のSoC(System on a Chip)は非常に複雑なデバイスです。完全なデバイスツリーは数百行になる可能性があります。その一歩を踏み出し、SoCを他のコンポーネントを搭載したボードに置くだけでは、事態が悪化します。これを管理しやすくするために、特にコンポーネントを共有する関連デバイスがある場合、.dtsi
ファイル内の共通要素を複数の.dts
ファイルから含めることは理にかなっています。
しかし、Razberry Piのようなシステムが、HATなどのオプションのプラグインアクセサリをサポートすると、問題が深刻化します。最終的には、それぞれの設定でデバイスツリーが記述されている必要がありますが、異なる基本ハードウェア(モデルA、B、A +、B +)と共存できるGPIOピンをいくつか使用する必要があるガジェット組み合わせが急速に増え始める。
必要なのは、部分的なデバイスツリーを使用してこれらのオプションコンポーネントを記述し、ベースDTを取得し、いくつかのオプション要素を追加することによって完全なツリーを構築する方法です。これを行うことができ、これらのオプション要素は「オーバーレイ」と呼ばれます。
2.1:フラグメント
DTオーバーレイは、それぞれが1つのノードおよびそのサブノードを対象とする多数のフラグメントを含む。概念は簡単に聞こえるが、構文は最初は奇妙に思える。
// Enable the i2s interface
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};
};
このcompatible
文字列は、これがBCM2870の基本アーキテクチャーであるBCM2708のものであることを示しています。BCM2836の場合、互換性のある文字列 “brcm、bcm2709″を使用できますが、ARM CPUの機能をターゲットにしない限り、2つのアーキテクチャは同等である必要があります。したがって、 “brcm、bcm2708” 次に、最初の(そして、この場合のみ)断片が来ます。フラグメントは0から順に番号が付けられます。これを遵守しないと、フラグメントの一部または全部が欠落する可能性があります。
各フラグメントは2つの部分で構成されます:target
オーバーレイを適用するノードを識別するプロパティ。そして__overlay__
自体は、本体は、ターゲット・ノードに追加されます。上記の例は、次のように書かれているかのように解釈できます。
/dts-v1/;
/ {
compatible = "brcm,bcm2708";
};
&i2s {
status = "okay";
};
bcm2708-rpi-b-plus.dtb
オーバレイが後でロードされるのであれば、標準のラズベリーパイベースのデバイスツリー(例えば、)にそのオーバレイをマージすることの効果は、そのステータスをに変更することによってI2Sインターフェイスを有効にすることokay
です。しかし、次のようにしてこのオーバーレイをコンパイルしようとすると、
dtc -I dts -O dtb -o 2nd.dtbo 2nd-overlay.dts
エラーが発生します:
Label or path i2s not found
コンパイラーがラベルを見つけることができるように、ベース.dtb
または.dts
ファイルへの参照がないので、これも予期しないものではありませんi2s
。
今度は元の例-@
を使用して未解決の参照を許可するオプションを追加して、もう一度試してみてください。
dtc -@ -I dts -O dtb -o 1st.dtbo 1st-overlay.dts
dtc
3行目のエラーを返す場合、オーバーレイ作業に必要な拡張機能はありません。実行sudo apt-get install device-tree-compiler
してもう一度やり直してください。今回はコンパイルが正常に完了するはずです。適切なコンパイラはscripts/dtc/dtc
、dtbs
makeターゲットが使用されたときにビルドされたカーネルツリーでも利用可能であることに注意してください。
make ARCH=arm dtbs
DTBファイルの内容をダンプして、コンパイラが生成した内容を確認するのは面白いことです。
$ fdtdump 1st.dtbo
/dts-v1/;
// magic: 0xd00dfeed
// totalsize: 0x106 (262)
// off_dt_struct: 0x38
// off_dt_strings: 0xe8
// off_mem_rsvmap: 0x28
// version: 17
// last_comp_version: 16
// boot_cpuid_phys: 0x0
// size_dt_strings: 0x1e
// size_dt_struct: 0xb0
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <0xdeadbeef>;
__overlay__ {
status = "okay";
};
};
__fixups__ {
i2s = "/fragment@0:target:0";
};
};
ファイル構造の冗長な記述の後に、私たちの断片があります。しかし、慎重に見てください – ここで書い&i2s
たところによれ0xdeadbeef
ば、何か不思議なことが起こったという手掛かりがあります。フラグメントの後に新しいノードがあり__fixups__
ます。これには、未解決シンボルの名前を、ターゲットが見つかるとターゲットノードのファンドルでパッチする必要があるフラグメント内のセルへのパスのリストにマッピングするプロパティーのリストが含まれています。この場合、パスはの0xdeadbeef
値になりますがtarget
、フラグメントには未解決の参照が含まれる可能性があり、追加の修正が必要になります。
より複雑なフラグメントを書くと、コンパイラはさらに2つのノードを生成することが__local_fixups__
あり__symbols__
ます。前者は、フラグメント内のいずれかのノードがファンドルを有する場合に必要とされる。なぜなら、マージを実行するプログラムは、ファンドル番号が順次かつユニークであることを保証しなければならないからである。しかし、後者は、未解決のシンボルがどのように扱われるかの鍵です。
1.3節に戻って、「元のラベルはコンパイルされた出力には現れません」と言いますが、-@
スイッチを使用している場合はそうではありません。代わりに、すべてのラベルは、__symbols__
ノード内のプロパティを結果として、ノードとまったく同じようにパスにラベルをマッピングしaliases
ます。実際、このメカニズムは非常に似ているので、シンボルを解決するときに、Raspberry Piローダーはノードが存在しない場合に「エイリアス」ノードを検索し__symbols__
ます。十分なエイリアスを提供することで、古いdtc
DTBファイルを作成するために古いDTBファイルを使用できるようになるため、これは便利です。
更新:カーネル内の動的デバイスツリーのサポートでは、オーバーレイに異なる形式の「ローカルフィックスアップ」が必要です。古いスタイルと新しいスタイルのオーバーレイが混在する問題を回避し、他のオーバーレイユーザーとのマッチングを行うために、古い「name-overlay.dtb」という名前体系が4.4以降の「name.dtbo」に置き換えられました。オーバーレイは名前だけで参照され、それらをロードするファームウェアまたはユーティリティは適切な接尾辞を追加します。例えば:
dtoverlay=awesome-overlay # This is wrong
dtoverlay=awesome # This is correct
2.2:デバイスツリーのパラメータ
多くのデバイスツリーオーバーレイの必要性を回避し、周辺機器のユーザーがDTSファイルを変更する必要性を減らすため、Raspberry Piローダーは新しい機能、デバイスツリーのパラメータをサポートしています。これにより、カーネルモジュールがパラメータを受け取る方法modprobe
やカーネルコマンドラインと同様に、名前付きパラメータを使用してDTを少し変更することができます。パラメータは、基本DTBおよびHATオーバーレイを含むオーバーレイによって公開されます。
パラメータは、__overrides__
ノードをルートに追加することによってDTSで定義されます。それは、選択されたパラメータ名であり、その値は、ターゲットノードのファンドル(ラベルへの参照)およびターゲットプロパティを示す文字列を含むシーケンスであるプロパティを含む。文字列、整数(セル)、ブール値の各プロパティがサポートされています。
2.2.1:文字列パラメータ
文字列パラメータは次のように宣言されます:
name = <&label>,"property";
ここでlabel
、property
は適切な値に置き換えられます。文字列パラメータを使用すると、ターゲットプロパティの拡大、縮小、または作成が可能になります。
呼び出されるプロパティstatus
は特別に扱われることに注意してください。非ゼロ/真/イエス/オンの値は文字列"okay"
に変換され、ゼロ/偽/ノー/オフが変換されます"disabled"
。
2.2.2:整数パラメータ
整数パラメータは次のように宣言されます:
name = <&label>,"property.offset"; // 8-bit
name = <&label>,"property;offset"; // 16-bit
name = <&label>,"property:offset"; // 32-bit
name = <&label>,"property#offset"; // 64-bit
ここでlabel
、property
およびoffset
は適切な値に置き換えられます。オフセットはプロパティの開始位置からの相対的なバイト数(デフォルトは10進数)で指定され、先行するセパレータによってパラメータのサイズが決定されます。初期の実装からの変更点では、整数パラメータは、存在しないプロパティまたは既存のプロパティの終わりを越えるオフセットを参照することがあります。
2.2.3:ブール値のパラメータ
デバイスツリーはブール値を長さゼロのプロパティとしてエンコードします。存在する場合はtrue、それ以外の場合falseです。それらは次のように定義されています:
boolean_property; // Set 'boolean_property' to true
プロパティには、値false
を定義しないことによって値が割り当てられます。ブールパラメータは次のように宣言されます:
name = <&label>,"property?";
ここでlabel
、property
は適切な値に置き換えられます。ブールパラメータを使用すると、プロパティを作成または削除できます。
2.2.4オーバーレイ/フラグメントパラメータ
このようなDTパラメータメカニズムには、ノードの名前を変更できないことや、パラメータが使用されているときに任意のプロパティに任意の値を書き込むことができないなど、多くの制限があります。これらの制限のいくつかを克服する1つの方法は、条件付きで特定のフラグメントを含めるか除外することです。
__overlay__
ノードの名前を変更して、フラグメントを最終的なマージプロセス(除外)から除外することができます__dormant__
。パラメータ宣言の構文が拡張され、そうでなければ不正なゼロターゲットファンドルが、次の文字列がフラグメントまたはオーバーレイスコープのオペレーションを含むことを示すことができます。これまでのところ、4つの操作が実装されています。
+<n> // Enable fragment <n>
-<n> // Disable fragment <n>
=<n> // Enable fragment <n> if the assigned parameter value is true, otherwise disable it
!<n> // Enable fragment <n> if the assigned parameter value is false, otherwise disable it
例:
just_one = <0>,"+1-2"; // Enable 1, disable 2
conditional = <0>,"=3!4"; // Enable 3, disable 4 if value is true,
// otherwise disable 3, enable 4.
i2c-muxオーバーレイはこの手法を使用します。
2.2.5例
さまざまなタイプのプロパティのいくつかの例と、それらを変更するパラメータがあります。
/ {
fragment@0 {
target-path = "/";
__overlay__ {
test: test_node {
string = "hello";
status = "disabled";
bytes = /bits/ 8 <0x67 0x89>;
u16s = /bits/ 16 <0xabcd 0xef01>;
u32s = /bits/ 32 <0xfedcba98 0x76543210>;
u64s = /bits/ 64 < 0xaaaaa5a55a5a5555 0x0000111122223333>;
bool1; // Defaults to true
// bool2 defaults to false
};
};
};
fragment@1 {
target-path = "/";
__overlay__ {
frag1;
};
};
fragment@2 {
target-path = "/";
__dormant__ {
frag2;
};
};
__overrides__ {
string = <&test>,"string";
enable = <&test>,"status";
byte_0 = <&test>,"bytes.0";
byte_1 = <&test>,"bytes.1";
u16_0 = <&test>,"u16s;0";
u16_1 = <&test>,"u16s;2";
u32_0 = <&test>,"u32s:0";
u32_1 = <&test>,"u32s:4";
u64_0 = <&test>,"u64s#0";
u64_1 = <&test>,"u64s#8";
bool1 = <&test>,"bool1?";
bool2 = <&test>,"bool2?";
only1 = <0>,"+1-2";
only2 = <0>,"-1+2";
toggle1 = <0>,"=1";
toggle2 = <0>,"=2";
not1 = <0>,"!1";
not2 = <0>,"!2";
};
};
2.2.6:複数のターゲットを持つパラメータ
デバイスツリー内の複数の場所で同じ値を設定できることが便利な状況がいくつかあります。1つのパラメータに複数のターゲットを追加することは、複数のパラメータを連結することで可能です。
__overrides__ {
gpiopin = <&w1>,"gpios:4",
<&w1_pins>,"brcm,pins:0";
...
};
(w1-gpio
オーバーレイから取った例)
1つのパラメータで異なるタイプのプロパティをターゲットに設定することも可能です。status
文字列、0または1を含むセル、および適切なブール値プロパティに”enable”パラメータを合理的に接続できます。
2.2.7:オーバーレイの例
ここには、Raspberry Pi / Linux GitHubリポジトリでホストされているオーバーレイソースファイルのコレクションが増えています。
第3部:ラズベリーパイのデバイスツリーの使用
3.1:オーバーレイとCONFIG.TXT
ラズベリーパイでは、start.elf
オーバーレイを適切な基本デバイスツリーと結合し、次に完全に解決されたデバイスツリーをカーネルに渡すことがローダ(画像の1つ)の仕事です。ベースデバイスの木が並んで配置されてstart.elf
、FATパーティション(Linuxではからは/ boot)で指定されたbcm2708-rpi-b.dtb
、bcm2708-rpi-b-plus.dtb
、bcm2708-rpi-cm.dtb
、とbcm2709-rpi-2-b.dtb
。モデルAとA +は、それぞれ “b”と “b-plus”のバリアントを使用することに注意してください。この選択は自動的に行われ、同じSDカードイメージをさまざまなデバイスで使用することができます。
DTとATAGは相互排他的であることに注意してください。その結果、DT BLOBを理解できないカーネルにDT BLOBを渡すと、ブートに失敗します。これを防ぐために、ローダーはカーネルイメージのDT互換性をチェックします。これはmkknlimg
ユーティリティーによって追加されたトレーラーによってマークされます。これはで見つけることができるscripts
最近のカーネルソースツリーのディレクトリ。トレーラーのないカーネルは、DT対応ではないとみなされます。
rpi-4.4.yツリー(およびそれ以降)から構築されたカーネルは、DTBなしでは機能しません。したがって、4.4リリース以降、トレーラーのないカーネルはDT対応であるとみなされます。これを無効にするには、DTOKフラグを付けずにtrailerを追加するかdevice_tree=
、config.txtを入力します。ただし、動作しない場合は驚かないでください。NBこれは、カーネルにDT機能を示すトレーラがある場合、device_tree=
無視されることになります。
ローダーは、BCM2835サポートを選択するbcm2835_defconfigを使用してビルドをサポートするようになりました。この構成が原因bcm2835-rpi-b.dtb
とbcm2835-rpi-b-plus.dtb
なり、構築されます。これらのファイルがカーネルでコピーされ、カーネルに最近のタグが付いている場合mkknlimg
、ローダーはデフォルトでそれらのDTBの1つをロードしようとします。
デバイスツリーとオーバーレイを管理するために、ローダーはいくつかの新しいconfig.txt
ディレクティブをサポートしています:
dtoverlay=acme-board
dtparam=foo=bar,level=42
これにより、overlays/acme-board.dtbo
Raspbianがマウントするファームウェアパーティションでローダーが検索されます/boot
。次に、パラメータfoo
を検索しlevel
、示された値をそれらに割り当てます。
ローダーは、プログラムされたEEPROMで付属のHATを検索し、そこからサポートオーバーレイをロードします。ユーザーの介入なしにこれが発生します。
カーネルがデバイスツリーを使用していることを伝える方法はいくつかあります。
- 起動時の「マシンモデル:」カーネルメッセージには、「BCM2709」ではなく「Raspberry Pi 2 Model B」などのボード固有の値があります。
- 後で、「No ATAGs?」という別のカーネルメッセージが表示されることもあります。これは予想されます。
/proc/device-tree
DTのノードとプロパティを正確に反映するサブディレクトリとファイルを含んでいます。
デバイスツリーでは、カーネルは、指定された有効デバイスをサポートするモジュールを自動的に検索してロードします。その結果、デバイスの適切なDTオーバーレイを作成することにより、デバイスのユーザを編集する必要がなくなり/etc/modules
ます。すべての設定が入りconfig.txt
、HATの場合は、そのステップまでは不要です。ただし、レイヤードモジュールはi2c-dev
明示的にロードする必要があります。
フロップサイドは、DTBから要求されない限りプラットフォームデバイスが作成されないため、ボードサポートコードで定義されたプラットフォームデバイスの結果としてロードされていたモジュールをブラックリストに載せる必要がなくなりました。実際、現在のRaspbian画像はブラックリストファイルなしで出荷されます。
3.2:DTパラメータ
上述のように、DTパラメータは、デバイスの構成を少し変更する便利な方法です。現在のベースDTBは、専用オーバレイを使用せずにオンボードオーディオ、I2C、I2S、SPIインタフェースを有効にして制御するためのパラメータをサポートしています。使用時のパラメータは次のようになります。
dtparam=audio=on,i2c_arm=on,i2c_arm_baudrate=400000,spi=on
同じ行に複数の割り当てを配置できますが、80文字の制限を超えないように注意してください。
将来のデフォルトにconfig.txt
は次のようなセクションが含まれます:
# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
いくつかのパラメータを定義するオーバーレイがある場合は、次のように次のように指定することができます。
dtoverlay=lirc-rpi
dtparam=gpio_out_pin=16
dtparam=gpio_in_pin=17
dtparam=gpio_in_pull=down
次のようにオーバーレイ行に追加されます。
dtoverlay=lirc-rpi:gpio_out_pin=16,gpio_in_pin=17,gpio_in_pull=down
ここ:
では、サポートされている構文のバリエーションであるパラメータからオーバーレイ名を分離するためにcolon()を使用することに注意してください。
オーバーレイパラメータは、次のオーバーレイがロードされるまで範囲内にのみあります。同じ名前のパラメータがオーバーレイとベースの両方でエクスポートされる場合、オーバーレイのパラメータが優先されます。明確にするため、これを避けることをお勧めします。代わりにベースDTBによってエクスポートされたパラメータを公開するには、以下を使用して現在のオーバーレイスコープを終了します。
dtoverlay=
3.3:ボード固有のラベルとパラメータ
ラズベリーパイボードには2つのI2Cインターフェイスがあります。これらは名目上分割されています(ARM用とVideoCore用)。ほぼすべてのモデルでi2c1
、ARMとi2c0
VC に属し、カメラを制御し、HAT EEPROMを読み取るために使用されます。しかし、これらの役割を逆転させたモデルBの初期の2つの改訂があります。
1組のオーバーレイとパラメータをすべてのPisで使用できるようにするため、ファームウェアはボード固有のDTパラメータをいくつか作成します。これらは:
i2c/i2c_arm
i2c_vc
i2c_baudrate/i2c_arm_baudrate
i2c_vc_baudrate
これらはのための別名であるi2c0
、i2c1
、i2c0_baudrate
、とi2c1_baudrate
。あなただけ使用することをお勧めしi2c_vc
そしてi2c_vc_baudrate
あなたが本当にする必要がある場合-たとえば、あなたがHATのEEPROMをプログラミングしている場合。有効にi2c_vc
すると、Piカメラが検出されなくなります。
オーバレイを作成する人々のために、I2C DTノード上のラベルにも同じエイリアシングが適用されています。したがって、次のように記述する必要があります。
fragment@0 {
target = <&i2c_arm>;
__overlay__ {
status = "okay";
};
};
数値バリアントを使用するオーバーレイは、新しいエイリアスを使用するように変更されます。
3.4:HATとデバイスツリー
ラズベリーパイHATは、EEPROMが埋め込まれた「プラス」形(A +、B +またはPi2B)のラズベリーパイ用のアドオンボードです。EEPROMにはボードを有効にするために必要なDTオーバーレイが含まれており、このオーバーレイはパラメータを公開することもできます。
HATオーバーレイはベースDTBの後のファームウェアによって自動的にロードされるため、他のオーバーレイがロードされるまで、またはオーバーレイスコープが使用されるまでパラメータにアクセスできますdtoverlay=
。なんらかの理由でHATオーバーレイのロードを抑制したい場合はdtoverlay=
、他のディレクティブdtoverlay
またはdtparam
ディレクティブの前に配置します。
3.5:動的デバイスツリー
Linux 4.4以降、RPiカーネルはオーバーレイとパラメータの動的ロードをサポートしています。互換カーネルは、ベースDTBの上に適用されるオーバーレイのスタックを管理します。変更はすぐに反映され/proc/device-tree
、モジュールをロードし、プラットフォームデバイスを作成して破壊する可能性があります。
上記の「スタック」という単語の使用は重要です。オーバーレイはスタックの上部でのみ追加したり削除したりすることができます。スタックをさらに下に変更するには、スタック上の何かを最初に削除する必要があります。
オーバーレイを管理するためのいくつかの新しいコマンドがあります:
3.5.1 DTOVERLAYコマンド
dtoverlay
利用可能なオーバーレイを一覧表示し、ヘルプ情報を表示するだけでなく、システムの実行中にオーバーレイを読み込んで削除するコマンドラインユーティリティです。
pi@raspberrypi ~ $ dtoverlay -h
Usage:
dtoverlay <overlay> [<param>=<val>...]
Add an overlay (with parameters)
dtoverlay -r [<overlay>] Remove an overlay (by name, index or the last)
dtoverlay -R [<overlay>] Remove from an overlay (by name, index or all)
dtoverlay -l List active overlays/params
dtoverlay -a List all overlays (marking the active)
dtoverlay -h Show this usage message
dtoverlay -h <overlay> Display help on an overlay
dtoverlay -h <overlay> <param>.. Or its parameters
where <overlay> is the name of an overlay or 'dtparam' for dtparams
Options applicable to most variants:
-d <dir> Specify an alternate location for the overlays
(defaults to /boot/overlays or /flash/overlays)
-n Dry run - show what would be executed
-v Verbose operation
config.txt
同等のものとは異なり、オーバーレイへのすべてのパラメータは同じコマンドラインに含まれていなければなりません.dtparamコマンドはベースDTBのパラメータのみに使用されます。
注目すべき2つのポイント:
- カーネルの状態を変更する(コマンドを追加したり削除したりする)コマンドには、root特権が必要です。そのため、コマンドに接頭辞を付ける必要があります
sudo
。
- 実行時に適用されるオーバーレイとパラメータのみがアンロードできます。ファームウェアによって適用されるオーバーレイまたはパラメータは、リストされ
dtoverlay
ず削除できないように「焼き付け」されます。
3.5.2 DTPARAMコマンド
dtparam
でdtparamディレクティブを使用するのと同じ効果を持つオーバーレイを作成しconfig.txt
ます。使い方ではdtoverlay
、オーバーレイ名はほとんど同じです-
が、少し違いがあります:
dtparam
ベースDTBのすべての既知のパラメータのヘルプ情報が一覧表示されます。dtparamコマンドのヘルプは、を使用して引き続き使用できますdtparam -h
。
- 削除するパラメータを指定するときは、名前ではなくインデックス番号のみを使用できます。
3.5.3ランタイム対応オーバーレイの作成に関するガイドライン
この領域は文書化されていませんが、いくつかのヒントがあります:
- デバイスオブジェクトの作成または削除は、ノードの追加または削除、またはノードの状態が無効から有効、またはその逆に変化することによってトリガーされます。注意してください。 “status”プロパティがないということは、ノードが有効であることを意味します。
- ベースDTBの既存のノードを上書きするフラグメント内にノードを作成しないでください。カーネルは新しいノードの名前を変更して一意にします。既存のノードのプロパティを変更する場合は、それをターゲットとするフラグメントを作成します。
- ALSAはコーデックやその他のコンポーネントが使用中にアンロードされるのを防ぎません。オーバーレイを削除すると、サウンドカードでまだ使用されているコーデックが削除されると、カーネル例外が発生する可能性があります。実験では、オーバーレイのフラグメント順序の逆にデバイスが削除されるため、コンポーネントのノードの後にカードのノードを配置すると、正常にシャットダウンできます。
3.5.4警告
実行時のオーバーレイのロードはカーネルへの最近の追加であり、これまでユーザー空間からこれを行う方法はありません。このメカニズムの詳細をコマンドの後ろに隠すことによって、異なるカーネルインタフェースが標準化された場合の変更からユーザを隔離することが目的です。
- 一部のオーバーレイは、実行時に他のオーバーレイよりもうまく機能します。デバイスツリーの一部はブート時にのみ使用されます。オーバーレイを使用してデバイスツリーを変更しても効果はありません。
- 一部のオーバーレイを適用または削除すると予期しない動作が発生する可能性があるため、注意して実行する必要があります。これが必要な理由の1つです
sudo
。
- ALSAカードのオーバーレイをアンロードすると、何かALSAを積極的に使用している場合に停止することがあります.LXPanelボリュームスライダプラグインは、この効果を示します。削除するサウンドカードのオーバーレイを有効にするには、
lxpanelctl
ユーティリティは、2つの新しいオプションが与えられている- alsastop
とalsastart
-これらは補助スクリプトから呼び出されるdtoverlay-pre
と、dtoverlay-post
オーバーレイはそれぞれ、ロードまたはアンロードされる前と後。
- オーバーレイを削除しても、ロードされたモジュールはアンロードされませんが、一部のモジュールの参照カウントがゼロになる可能性があります。
rmmod -a
2回実行すると、未使用のモジュールがアンロードされます。
- オーバーレイは逆の順序で削除する必要があります。コマンドを使用すると、以前のものを削除することができますが、中間のものはすべて削除されて再適用され、意図しない結果が生じる可能性があります。
/clocks
実行時にノードの下にクロックを追加しても、新しいクロックプロバイダは登録されdevm_clk_get
ません。そのため、オーバーレイで作成されたクロックに失敗します。
3.6:サポートされているオーバーレイとパラメータ
個々のオーバーレイをここで文書化するのはあまりにも時間がかかるので、にあるオーバーレイファイルの横にあるREADMEファイルを参照してください。追加情報や変更情報は最新の状態に保たれています。.dtbo
/boot/overlays
パート4:トラブルシューティングとプロのヒント
4.1:デバッグ
ローダーは欠落しているオーバーレイや悪いパラメータをスキップしますが、欠落しているDTBや破損したオーバーレイのマージなどの重大なエラーがあると、ローダーは非DTブートに戻ります。このような場合や、設定が期待通りに動作しない場合は、ローダーからの警告やエラーをチェックする価値があります。
sudo vcdbg log msg
追加のデバッグは、追加することで有効にすることができますdtdebug=1
しconfig.txt
。
カーネルがDTモードで起動しない場合は、カーネルイメージに有効なトレーラがないためです。使用knlinfo
1をチェックすると、mkknlimg
ユーティリティは、1を追加します。どちらのユーティリティもscripts
現在のRaspberry Piカーネルソースツリーのディレクトリに含まれています。
次のように、DTの現在の状態を人間が読める形式で作成できます。
dtc -I fs /proc/device-tree
これは、下にあるツリーにオーバーレイをマージする効果を見るのに便利です。
カーネルモジュールが期待どおりにロードされない場合は、カーネルモジュールがブラックリストに載っていないことを確認してください/etc/modprobe.d/raspi-blacklist.conf
。デバイスツリーを使用しているときにブラックリストが必要ではありません。それは厄介なものを示していない場合は、モジュールを検索して、正しい別名をエクスポートしていることを確認することができます/lib/modules/<version>/modules.alias
のためのcompatible
値。それ以外の場合は、ドライバが不足している可能性があります:
.of_match_table = xxx_of_match,
または:
MODULE_DEVICE_TABLE(of, xxx_of_match);
失敗depmod
したか、更新されたモジュールがターゲットファイルシステムにインストールされていません。
4.2:DTMERGEとDTDIFFを使用したオーバーレイのテスト
コマンドと並んでdtoverlay
、dtparam
コマンドはDTBにオーバレイを適用するユーティリティですdtmerge
。それを使用するには、最初にベースDTBを取得する必要があります。これは、次の2つの方法のいずれかで取得できます。
a)ライブDT状態から生成する/proc/device-tree
:
dtc -I fs -O dtb -o base.dtb /proc/device-tree
これにはconfig.txt
、実行時にロードするか、ロードするかによって、これまでに適用したオーバーレイとパラメータが含まれます。代わりに…
b)/ boot内のソースDTBからコピーします。これにはオーバーレイとパラメータは含まれませんが、ファームウェアによる他の変更は含まれません。すべてのオーバーレイのテストを可能にするために、dtmerge
ユーティリティはボード固有のエイリアス( “i2c_arm”など)のいくつかを作成しますが、マージ結果に元のDTBとの相違点が多く含まれます。これを解決するには、dtmergeを使用してコピーを作成します。
dtmerge /boot/bcm2710-rpi-3-b.dtb base.dtb -
(は-
オーバーレイ名がないことを示します)。
オーバーレイまたはパラメータを適用することができます:
dtmerge base.dtb merged.dtb - sd_overclock=62
dtdiff base.dtb merged.dtb
それは返すでしょう:
--- /dev/fd/63 2016-05-16 14:48:26.396024813 +0100
+++ /dev/fd/62 2016-05-16 14:48:26.396024813 +0100
@@ -594,7 +594,7 @@
};
sdhost@7e202000 {
- brcm,overclock-50 = <0x0>;
+ brcm,overclock-50 = <0x3e>;
brcm,pio-limit = <0x1>;
bus-width = <0x4>;
clocks = <0x8>;
異なるオーバーレイやパラメータを比較することもできます。
dtmerge base.dtb merged1.dtb /boot/overlays/spi1-1cs.dtbo
dtmerge base.dtb merged2.dtb /boot/overlays/spi1-2cs.dtbo
dtdiff merged1.dtb merged2.dtb
取得するため:
--- /dev/fd/63 2016-05-16 14:18:56.189634286 +0100
+++ /dev/fd/62 2016-05-16 14:18:56.189634286 +0100
@@ -453,7 +453,7 @@
spi1_cs_pins {
brcm,function = <0x1>;
- brcm,pins = <0x12>;
+ brcm,pins = <0x12 0x11>;
phandle = <0x3e>;
};
@@ -725,7 +725,7 @@
#size-cells = <0x0>;
clocks = <0x13 0x1>;
compatible = "brcm,bcm2835-aux-spi";
- cs-gpios = <0xc 0x12 0x1>;
+ cs-gpios = <0xc 0x12 0x1 0xc 0x11 0x1>;
interrupts = <0x1 0x1d>;
linux,phandle = <0x30>;
phandle = <0x30>;
@@ -743,6 +743,16 @@
spi-max-frequency = <0x7a120>;
status = "okay";
};
+
+ spidev@1 {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ compatible = "spidev";
+ phandle = <0x41>;
+ reg = <0x1>;
+ spi-max-frequency = <0x7a120>;
+ status = "okay";
+ };
};
spi@7e2150C0 {
4.3:特定のデバイスツリーを強制する
デフォルトのDTB(特にARCH_BCM2835プロジェクトで使用されている純粋なDTアプローチを試している人)がサポートしていない非常に特殊なニーズがある場合や、独自のDTの作成を実験したい場合は、ローダは次のように代替DTBファイルをロードします。
device_tree=my-pi.dtb
4.4:デバイスツリーの使用を無効にする
4.4カーネルへの切り替えおよびより上流のドライバの使用のため、Piカーネルではデバイスツリーの使用が必要です。DTの使用を無効にする方法は次のものを追加することです:
device_tree=
〜にconfig.txt
。しかし、カーネルにmkknlimg
DT機能を示すトレーラがある場合、このディレクティブは無視されます。
4.5:ショートカットとシンタックスバリアント
ローダーはいくつかのショートカットを理解しています:
dtparam=i2c_arm=on
dtparam=i2s=on
短縮することができます:
dtparam=i2c,i2s
(i2c
のエイリアスでi2c_arm
あり、=on
と仮定されます)。また、まだ長い形式のバージョンを受け付けますdevice_tree_overlay
とdevice_tree_param
。
空白とコロンの区切り文字としての使用を受け入れるために使用されたローダーは、単純化のために中止されているため、引用符なしでパラメーター値内で使用することができます。
4.6:CONFIG.TXTで利用できる他のDTコマンド
device_tree_address
これは、ファームウェアがデバイスツリー(dt-blobではなく)をロードするアドレスを上書きするために使用されます。デフォルトでは、ファームウェアは適切な場所を選択します。
device_tree_end
これは、ロードされたデバイスツリーに(排他的な)制限を設定します。デフォルトでは、デバイスツリーは使用可能なメモリの終わりまで成長することができます。これはほぼ確実に必要なものです。
dtdebug
非ゼロの場合は、ファームウェアのデバイスツリー処理のための追加ログをオンにします。
enable_uart
プライマリ/コンソールUART(Pi3ではttyS0、それ以外の場合はttyAMA0)を有効にします(pi3-miniuart-btなどのオーバーレイと交換しない限り)。プライマリUARTがttyAMA0の場合、enable_uartのデフォルトは1(有効)、それ以外の場合はデフォルトの0(無効)です。これは、ttyS0を使用できなくするようにコア周波数が変化しないようにする必要があるため、enable_uart=1
core_freq = 250(force_turbo = 1を指定しない限り)を意味します。場合によってはこれがパフォーマンスヒットであるため、デフォルトではオフになっています。UARTの詳細はこちらをご覧ください
overlay_prefix
オーバーレイをロードするサブディレクトリ/プレフィックスを指定します。デフォルトは “overlays /”です。末尾の “/”に注意してください。望むならば、最終的な “/”の後ろに何かを追加して各ファイルにプレフィックスを付けることができますが、これは必要ではないでしょう。